mirror of
https://github.com/DOI-DO/j40-cejst-2.git
synced 2025-02-23 10:04:18 -08:00
1 line
No EOL
4.4 MiB
1 line
No EOL
4.4 MiB
(self.webpackChunkjustice40_tool=self.webpackChunkjustice40_tool||[]).push([[281],{9968:function(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": function() { return /* binding */ _arrayWithHoles; }\n/* harmony export */ });\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hcnJheVdpdGhIb2xlcy5qcz8wZDIxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFlO0FBQ2Y7QUFDQSIsImZpbGUiOiI5OTY4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyO1xufSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9968\n')},8970:function(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": function() { return /* binding */ _nonIterableRest; }\n/* harmony export */ });\nfunction _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}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9ub25JdGVyYWJsZVJlc3QuanM/M2Q4YyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBZTtBQUNmO0FBQ0EiLCJmaWxlIjoiODk3MC5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG59Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///8970\n')},8481:function(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "Z": function() { return /* binding */ _slicedToArray; }\n});\n\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nvar arrayWithHoles = __webpack_require__(9968);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i["return"] != null) _i["return"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\nvar unsupportedIterableToArray = __webpack_require__(2961);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nvar nonIterableRest = __webpack_require__(8970);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction _slicedToArray(arr, i) {\n return (0,arrayWithHoles/* default */.Z)(arr) || _iterableToArrayLimit(arr, i) || (0,unsupportedIterableToArray/* default */.Z)(arr, i) || (0,nonIterableRest/* default */.Z)();\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz8wOWYwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXkuanM/MzgzNSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBZTtBQUNmOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsMkJBQTJCLCtCQUErQjtBQUMxRDs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxDOzs7Ozs7QUM1QmlEO0FBQ1k7QUFDWTtBQUN0QjtBQUNwQztBQUNmLFNBQVMsaUNBQWMsU0FBUyxxQkFBb0IsWUFBWSw2Q0FBMEIsWUFBWSxrQ0FBZTtBQUNySCIsImZpbGUiOiI4NDgxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2kgPSBhcnIgPT0gbnVsbCA/IG51bGwgOiB0eXBlb2YgU3ltYm9sICE9PSBcInVuZGVmaW5lZFwiICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07XG5cbiAgaWYgKF9pID09IG51bGwpIHJldHVybjtcbiAgdmFyIF9hcnIgPSBbXTtcbiAgdmFyIF9uID0gdHJ1ZTtcbiAgdmFyIF9kID0gZmFsc2U7XG5cbiAgdmFyIF9zLCBfZTtcblxuICB0cnkge1xuICAgIGZvciAoX2kgPSBfaS5jYWxsKGFycik7ICEoX24gPSAoX3MgPSBfaS5uZXh0KCkpLmRvbmUpOyBfbiA9IHRydWUpIHtcbiAgICAgIF9hcnIucHVzaChfcy52YWx1ZSk7XG5cbiAgICAgIGlmIChpICYmIF9hcnIubGVuZ3RoID09PSBpKSBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIF9kID0gdHJ1ZTtcbiAgICBfZSA9IGVycjtcbiAgfSBmaW5hbGx5IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFfbiAmJiBfaVtcInJldHVyblwiXSAhPSBudWxsKSBfaVtcInJldHVyblwiXSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBfYXJyO1xufSIsImltcG9ydCBhcnJheVdpdGhIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheUxpbWl0IGZyb20gXCIuL2l0ZXJhYmxlVG9BcnJheUxpbWl0LmpzXCI7XG5pbXBvcnQgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkgZnJvbSBcIi4vdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCBub25JdGVyYWJsZVJlc3QgZnJvbSBcIi4vbm9uSXRlcmFibGVSZXN0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///8481\n')},9809:function(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": function() { return /* binding */ _toArray; }\n/* harmony export */ });\n/* harmony import */ var _arrayWithHoles_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9968);\n/* harmony import */ var _iterableToArray_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6410);\n/* harmony import */ var _unsupportedIterableToArray_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2961);\n/* harmony import */ var _nonIterableRest_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8970);\n\n\n\n\nfunction _toArray(arr) {\n return (0,_arrayWithHoles_js__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(arr) || (0,_iterableToArray_js__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(arr) || (0,_unsupportedIterableToArray_js__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(arr) || (0,_nonIterableRest_js__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)();\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0FycmF5LmpzPzRmOTYiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFpRDtBQUNFO0FBQ3NCO0FBQ3RCO0FBQ3BDO0FBQ2YsU0FBUyxvRUFBYyxTQUFTLHFFQUFlLFNBQVMsZ0ZBQTBCLFNBQVMscUVBQWU7QUFDMUciLCJmaWxlIjoiOTgwOS5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhcnJheVdpdGhIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi9pdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IG5vbkl0ZXJhYmxlUmVzdCBmcm9tIFwiLi9ub25JdGVyYWJsZVJlc3QuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF90b0FycmF5KGFycikge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufSJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///9809\n')},5366:function(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "Z": function() { return /* binding */ _wrapNativeSuper; }\n});\n\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nvar getPrototypeOf = __webpack_require__(7608);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js\nvar setPrototypeOf = __webpack_require__(4665);\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeFunction.js\nfunction _isNativeFunction(fn) {\n return Function.toString.call(fn).indexOf("[native code]") !== -1;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js\nfunction _isNativeReflectConstruct() {\n if (typeof Reflect === "undefined" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === "function") return true;\n\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/construct.js\n\n\nfunction _construct(Parent, args, Class) {\n if (_isNativeReflectConstruct()) {\n _construct = Reflect.construct;\n } else {\n _construct = function _construct(Parent, args, Class) {\n var a = [null];\n a.push.apply(a, args);\n var Constructor = Function.bind.apply(Parent, a);\n var instance = new Constructor();\n if (Class) (0,setPrototypeOf/* default */.Z)(instance, Class.prototype);\n return instance;\n };\n }\n\n return _construct.apply(null, arguments);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js\n\n\n\n\nfunction _wrapNativeSuper(Class) {\n var _cache = typeof Map === "function" ? new Map() : undefined;\n\n _wrapNativeSuper = function _wrapNativeSuper(Class) {\n if (Class === null || !_isNativeFunction(Class)) return Class;\n\n if (typeof Class !== "function") {\n throw new TypeError("Super expression must either be null or a function");\n }\n\n if (typeof _cache !== "undefined") {\n if (_cache.has(Class)) return _cache.get(Class);\n\n _cache.set(Class, Wrapper);\n }\n\n function Wrapper() {\n return _construct(Class, arguments, (0,getPrototypeOf/* default */.Z)(this).constructor);\n }\n\n Wrapper.prototype = Object.create(Class.prototype, {\n constructor: {\n value: Wrapper,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n return (0,setPrototypeOf/* default */.Z)(Wrapper, Class);\n };\n\n return _wrapNativeSuper(Class);\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pc05hdGl2ZUZ1bmN0aW9uLmpzP2ZhOTUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0LmpzP2Q5NjciLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY29uc3RydWN0LmpzPzQ0NzgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vd3JhcE5hdGl2ZVN1cGVyLmpzPzkwNzIiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFBZTtBQUNmO0FBQ0EsQzs7QUNGZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdGQUFnRjtBQUNoRjtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsQzs7QUNYaUQ7QUFDb0I7QUFDdEQ7QUFDZixNQUFNLHlCQUF3QjtBQUM5QjtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGlDQUFjO0FBQy9CO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEM7O0FDakJpRDtBQUNBO0FBQ0k7QUFDZDtBQUN4QjtBQUNmOztBQUVBO0FBQ0EsMkJBQTJCLGlCQUFnQjs7QUFFM0M7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGFBQWEsVUFBUyxtQkFBbUIsaUNBQWM7QUFDdkQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsV0FBVyxpQ0FBYztBQUN6Qjs7QUFFQTtBQUNBIiwiZmlsZSI6IjUzNjYuanMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfaXNOYXRpdmVGdW5jdGlvbihmbikge1xuICByZXR1cm4gRnVuY3Rpb24udG9TdHJpbmcuY2FsbChmbikuaW5kZXhPZihcIltuYXRpdmUgY29kZV1cIikgIT09IC0xO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTtcbiAgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTtcblxuICB0cnkge1xuICAgIEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufSIsImltcG9ydCBzZXRQcm90b3R5cGVPZiBmcm9tIFwiLi9zZXRQcm90b3R5cGVPZi5qc1wiO1xuaW1wb3J0IGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCBmcm9tIFwiLi9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9jb25zdHJ1Y3QoUGFyZW50LCBhcmdzLCBDbGFzcykge1xuICBpZiAoaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkpIHtcbiAgICBfY29uc3RydWN0ID0gUmVmbGVjdC5jb25zdHJ1Y3Q7XG4gIH0gZWxzZSB7XG4gICAgX2NvbnN0cnVjdCA9IGZ1bmN0aW9uIF9jb25zdHJ1Y3QoUGFyZW50LCBhcmdzLCBDbGFzcykge1xuICAgICAgdmFyIGEgPSBbbnVsbF07XG4gICAgICBhLnB1c2guYXBwbHkoYSwgYXJncyk7XG4gICAgICB2YXIgQ29uc3RydWN0b3IgPSBGdW5jdGlvbi5iaW5kLmFwcGx5KFBhcmVudCwgYSk7XG4gICAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQ29uc3RydWN0b3IoKTtcbiAgICAgIGlmIChDbGFzcykgc2V0UHJvdG90eXBlT2YoaW5zdGFuY2UsIENsYXNzLnByb3RvdHlwZSk7XG4gICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBfY29uc3RydWN0LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG59IiwiaW1wb3J0IGdldFByb3RvdHlwZU9mIGZyb20gXCIuL2dldFByb3RvdHlwZU9mLmpzXCI7XG5pbXBvcnQgc2V0UHJvdG90eXBlT2YgZnJvbSBcIi4vc2V0UHJvdG90eXBlT2YuanNcIjtcbmltcG9ydCBpc05hdGl2ZUZ1bmN0aW9uIGZyb20gXCIuL2lzTmF0aXZlRnVuY3Rpb24uanNcIjtcbmltcG9ydCBjb25zdHJ1Y3QgZnJvbSBcIi4vY29uc3RydWN0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKSB7XG4gIHZhciBfY2FjaGUgPSB0eXBlb2YgTWFwID09PSBcImZ1bmN0aW9uXCIgPyBuZXcgTWFwKCkgOiB1bmRlZmluZWQ7XG5cbiAgX3dyYXBOYXRpdmVTdXBlciA9IGZ1bmN0aW9uIF93cmFwTmF0aXZlU3VwZXIoQ2xhc3MpIHtcbiAgICBpZiAoQ2xhc3MgPT09IG51bGwgfHwgIWlzTmF0aXZlRnVuY3Rpb24oQ2xhc3MpKSByZXR1cm4gQ2xhc3M7XG5cbiAgICBpZiAodHlwZW9mIENsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvblwiKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIF9jYWNoZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgaWYgKF9jYWNoZS5oYXMoQ2xhc3MpKSByZXR1cm4gX2NhY2hlLmdldChDbGFzcyk7XG5cbiAgICAgIF9jYWNoZS5zZXQoQ2xhc3MsIFdyYXBwZXIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIFdyYXBwZXIoKSB7XG4gICAgICByZXR1cm4gY29uc3RydWN0KENsYXNzLCBhcmd1bWVudHMsIGdldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yKTtcbiAgICB9XG5cbiAgICBXcmFwcGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogV3JhcHBlcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gc2V0UHJvdG90eXBlT2YoV3JhcHBlciwgQ2xhc3MpO1xuICB9O1xuXG4gIHJldHVybiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKTtcbn0iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5366\n')},3873:function(module){eval("/**\n * chroma.js - JavaScript library for color conversions\n *\n * Copyright (c) 2011-2019, Gregor Aisch\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * 3. The name Gregor Aisch may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * -------------------------------------------------------\n *\n * chroma.js includes colors from colorbrewer2.org, which are released under\n * the following license:\n *\n * Copyright (c) 2002 Cynthia Brewer, Mark Harrower,\n * and The Pennsylvania State University.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n * either express or implied. See the License for the specific\n * language governing permissions and limitations under the License.\n *\n * ------------------------------------------------------\n *\n * Named colors are taken from X11 Color Names.\n * http://www.w3.org/TR/css3-color/#svg-color\n *\n * @preserve\n */\n(function (global, factory) {\n true ? module.exports = factory() : 0;\n})(this, function () {\n 'use strict';\n\n var limit = function limit(x, min, max) {\n if (min === void 0) min = 0;\n if (max === void 0) max = 1;\n return x < min ? min : x > max ? max : x;\n };\n\n var clip_rgb = function clip_rgb(rgb) {\n rgb._clipped = false;\n rgb._unclipped = rgb.slice(0);\n\n for (var i = 0; i <= 3; i++) {\n if (i < 3) {\n if (rgb[i] < 0 || rgb[i] > 255) {\n rgb._clipped = true;\n }\n\n rgb[i] = limit(rgb[i], 0, 255);\n } else if (i === 3) {\n rgb[i] = limit(rgb[i], 0, 1);\n }\n }\n\n return rgb;\n }; // ported from jQuery's $.type\n\n\n var classToType = {};\n\n for (var i = 0, list = ['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Undefined', 'Null']; i < list.length; i += 1) {\n var name = list[i];\n classToType[\"[object \" + name + \"]\"] = name.toLowerCase();\n }\n\n var type = function type(obj) {\n return classToType[Object.prototype.toString.call(obj)] || \"object\";\n };\n\n var unpack = function unpack(args, keyOrder) {\n if (keyOrder === void 0) keyOrder = null; // if called with more than 3 arguments, we return the arguments\n\n if (args.length >= 3) {\n return Array.prototype.slice.call(args);\n } // with less than 3 args we check if first arg is object\n // and use the keyOrder string to extract and sort properties\n\n\n if (type(args[0]) == 'object' && keyOrder) {\n return keyOrder.split('').filter(function (k) {\n return args[0][k] !== undefined;\n }).map(function (k) {\n return args[0][k];\n });\n } // otherwise we just return the first argument\n // (which we suppose is an array of args)\n\n\n return args[0];\n };\n\n var last = function last(args) {\n if (args.length < 2) {\n return null;\n }\n\n var l = args.length - 1;\n\n if (type(args[l]) == 'string') {\n return args[l].toLowerCase();\n }\n\n return null;\n };\n\n var PI = Math.PI;\n var utils = {\n clip_rgb: clip_rgb,\n limit: limit,\n type: type,\n unpack: unpack,\n last: last,\n PI: PI,\n TWOPI: PI * 2,\n PITHIRD: PI / 3,\n DEG2RAD: PI / 180,\n RAD2DEG: 180 / PI\n };\n var input = {\n format: {},\n autodetect: []\n };\n var last$1 = utils.last;\n var clip_rgb$1 = utils.clip_rgb;\n var type$1 = utils.type;\n\n var Color = function Color() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var me = this;\n\n if (type$1(args[0]) === 'object' && args[0].constructor && args[0].constructor === this.constructor) {\n // the argument is already a Color instance\n return args[0];\n } // last argument could be the mode\n\n\n var mode = last$1(args);\n var autodetect = false;\n\n if (!mode) {\n autodetect = true;\n\n if (!input.sorted) {\n input.autodetect = input.autodetect.sort(function (a, b) {\n return b.p - a.p;\n });\n input.sorted = true;\n } // auto-detect format\n\n\n for (var i = 0, list = input.autodetect; i < list.length; i += 1) {\n var chk = list[i];\n mode = chk.test.apply(chk, args);\n\n if (mode) {\n break;\n }\n }\n }\n\n if (input.format[mode]) {\n var rgb = input.format[mode].apply(null, autodetect ? args : args.slice(0, -1));\n me._rgb = clip_rgb$1(rgb);\n } else {\n throw new Error('unknown format: ' + args);\n } // add alpha channel\n\n\n if (me._rgb.length === 3) {\n me._rgb.push(1);\n }\n };\n\n Color.prototype.toString = function toString() {\n if (type$1(this.hex) == 'function') {\n return this.hex();\n }\n\n return \"[\" + this._rgb.join(',') + \"]\";\n };\n\n var Color_1 = Color;\n\n var chroma = function chroma() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(chroma.Color, [null].concat(args)))();\n };\n\n chroma.Color = Color_1;\n chroma.version = '2.1.2';\n var chroma_1 = chroma;\n var unpack$1 = utils.unpack;\n var max = Math.max;\n\n var rgb2cmyk = function rgb2cmyk() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$1(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n r = r / 255;\n g = g / 255;\n b = b / 255;\n var k = 1 - max(r, max(g, b));\n var f = k < 1 ? 1 / (1 - k) : 0;\n var c = (1 - r - k) * f;\n var m = (1 - g - k) * f;\n var y = (1 - b - k) * f;\n return [c, m, y, k];\n };\n\n var rgb2cmyk_1 = rgb2cmyk;\n var unpack$2 = utils.unpack;\n\n var cmyk2rgb = function cmyk2rgb() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$2(args, 'cmyk');\n var c = args[0];\n var m = args[1];\n var y = args[2];\n var k = args[3];\n var alpha = args.length > 4 ? args[4] : 1;\n\n if (k === 1) {\n return [0, 0, 0, alpha];\n }\n\n return [c >= 1 ? 0 : 255 * (1 - c) * (1 - k), // r\n m >= 1 ? 0 : 255 * (1 - m) * (1 - k), // g\n y >= 1 ? 0 : 255 * (1 - y) * (1 - k), // b\n alpha];\n };\n\n var cmyk2rgb_1 = cmyk2rgb;\n var unpack$3 = utils.unpack;\n var type$2 = utils.type;\n\n Color_1.prototype.cmyk = function () {\n return rgb2cmyk_1(this._rgb);\n };\n\n chroma_1.cmyk = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['cmyk'])))();\n };\n\n input.format.cmyk = cmyk2rgb_1;\n input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$3(args, 'cmyk');\n\n if (type$2(args) === 'array' && args.length === 4) {\n return 'cmyk';\n }\n }\n });\n var unpack$4 = utils.unpack;\n var last$2 = utils.last;\n\n var rnd = function rnd(a) {\n return Math.round(a * 100) / 100;\n };\n /*\n * supported arguments:\n * - hsl2css(h,s,l)\n * - hsl2css(h,s,l,a)\n * - hsl2css([h,s,l], mode)\n * - hsl2css([h,s,l,a], mode)\n * - hsl2css({h,s,l,a}, mode)\n */\n\n\n var hsl2css = function hsl2css() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var hsla = unpack$4(args, 'hsla');\n var mode = last$2(args) || 'lsa';\n hsla[0] = rnd(hsla[0] || 0);\n hsla[1] = rnd(hsla[1] * 100) + '%';\n hsla[2] = rnd(hsla[2] * 100) + '%';\n\n if (mode === 'hsla' || hsla.length > 3 && hsla[3] < 1) {\n hsla[3] = hsla.length > 3 ? hsla[3] : 1;\n mode = 'hsla';\n } else {\n hsla.length = 3;\n }\n\n return mode + \"(\" + hsla.join(',') + \")\";\n };\n\n var hsl2css_1 = hsl2css;\n var unpack$5 = utils.unpack;\n /*\n * supported arguments:\n * - rgb2hsl(r,g,b)\n * - rgb2hsl(r,g,b,a)\n * - rgb2hsl([r,g,b])\n * - rgb2hsl([r,g,b,a])\n * - rgb2hsl({r,g,b,a})\n */\n\n var rgb2hsl = function rgb2hsl() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$5(args, 'rgba');\n var r = args[0];\n var g = args[1];\n var b = args[2];\n r /= 255;\n g /= 255;\n b /= 255;\n var min = Math.min(r, g, b);\n var max = Math.max(r, g, b);\n var l = (max + min) / 2;\n var s, h;\n\n if (max === min) {\n s = 0;\n h = Number.NaN;\n } else {\n s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min);\n }\n\n if (r == max) {\n h = (g - b) / (max - min);\n } else if (g == max) {\n h = 2 + (b - r) / (max - min);\n } else if (b == max) {\n h = 4 + (r - g) / (max - min);\n }\n\n h *= 60;\n\n if (h < 0) {\n h += 360;\n }\n\n if (args.length > 3 && args[3] !== undefined) {\n return [h, s, l, args[3]];\n }\n\n return [h, s, l];\n };\n\n var rgb2hsl_1 = rgb2hsl;\n var unpack$6 = utils.unpack;\n var last$3 = utils.last;\n var round = Math.round;\n /*\n * supported arguments:\n * - rgb2css(r,g,b)\n * - rgb2css(r,g,b,a)\n * - rgb2css([r,g,b], mode)\n * - rgb2css([r,g,b,a], mode)\n * - rgb2css({r,g,b,a}, mode)\n */\n\n var rgb2css = function rgb2css() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var rgba = unpack$6(args, 'rgba');\n var mode = last$3(args) || 'rgb';\n\n if (mode.substr(0, 3) == 'hsl') {\n return hsl2css_1(rgb2hsl_1(rgba), mode);\n }\n\n rgba[0] = round(rgba[0]);\n rgba[1] = round(rgba[1]);\n rgba[2] = round(rgba[2]);\n\n if (mode === 'rgba' || rgba.length > 3 && rgba[3] < 1) {\n rgba[3] = rgba.length > 3 ? rgba[3] : 1;\n mode = 'rgba';\n }\n\n return mode + \"(\" + rgba.slice(0, mode === 'rgb' ? 3 : 4).join(',') + \")\";\n };\n\n var rgb2css_1 = rgb2css;\n var unpack$7 = utils.unpack;\n var round$1 = Math.round;\n\n var hsl2rgb = function hsl2rgb() {\n var assign;\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$7(args, 'hsl');\n var h = args[0];\n var s = args[1];\n var l = args[2];\n var r, g, b;\n\n if (s === 0) {\n r = g = b = l * 255;\n } else {\n var t3 = [0, 0, 0];\n var c = [0, 0, 0];\n var t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var t1 = 2 * l - t2;\n var h_ = h / 360;\n t3[0] = h_ + 1 / 3;\n t3[1] = h_;\n t3[2] = h_ - 1 / 3;\n\n for (var i = 0; i < 3; i++) {\n if (t3[i] < 0) {\n t3[i] += 1;\n }\n\n if (t3[i] > 1) {\n t3[i] -= 1;\n }\n\n if (6 * t3[i] < 1) {\n c[i] = t1 + (t2 - t1) * 6 * t3[i];\n } else if (2 * t3[i] < 1) {\n c[i] = t2;\n } else if (3 * t3[i] < 2) {\n c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;\n } else {\n c[i] = t1;\n }\n }\n\n assign = [round$1(c[0] * 255), round$1(c[1] * 255), round$1(c[2] * 255)], r = assign[0], g = assign[1], b = assign[2];\n }\n\n if (args.length > 3) {\n // keep alpha channel\n return [r, g, b, args[3]];\n }\n\n return [r, g, b, 1];\n };\n\n var hsl2rgb_1 = hsl2rgb;\n var RE_RGB = /^rgb\\(\\s*(-?\\d+),\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*\\)$/;\n var RE_RGBA = /^rgba\\(\\s*(-?\\d+),\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*,\\s*([01]|[01]?\\.\\d+)\\)$/;\n var RE_RGB_PCT = /^rgb\\(\\s*(-?\\d+(?:\\.\\d+)?)%,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*\\)$/;\n var RE_RGBA_PCT = /^rgba\\(\\s*(-?\\d+(?:\\.\\d+)?)%,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*([01]|[01]?\\.\\d+)\\)$/;\n var RE_HSL = /^hsl\\(\\s*(-?\\d+(?:\\.\\d+)?),\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*\\)$/;\n var RE_HSLA = /^hsla\\(\\s*(-?\\d+(?:\\.\\d+)?),\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*(-?\\d+(?:\\.\\d+)?)%\\s*,\\s*([01]|[01]?\\.\\d+)\\)$/;\n var round$2 = Math.round;\n\n var css2rgb = function css2rgb(css) {\n css = css.toLowerCase().trim();\n var m;\n\n if (input.format.named) {\n try {\n return input.format.named(css);\n } catch (e) {// eslint-disable-next-line\n }\n } // rgb(250,20,0)\n\n\n if (m = css.match(RE_RGB)) {\n var rgb = m.slice(1, 4);\n\n for (var i = 0; i < 3; i++) {\n rgb[i] = +rgb[i];\n }\n\n rgb[3] = 1; // default alpha\n\n return rgb;\n } // rgba(250,20,0,0.4)\n\n\n if (m = css.match(RE_RGBA)) {\n var rgb$1 = m.slice(1, 5);\n\n for (var i$1 = 0; i$1 < 4; i$1++) {\n rgb$1[i$1] = +rgb$1[i$1];\n }\n\n return rgb$1;\n } // rgb(100%,0%,0%)\n\n\n if (m = css.match(RE_RGB_PCT)) {\n var rgb$2 = m.slice(1, 4);\n\n for (var i$2 = 0; i$2 < 3; i$2++) {\n rgb$2[i$2] = round$2(rgb$2[i$2] * 2.55);\n }\n\n rgb$2[3] = 1; // default alpha\n\n return rgb$2;\n } // rgba(100%,0%,0%,0.4)\n\n\n if (m = css.match(RE_RGBA_PCT)) {\n var rgb$3 = m.slice(1, 5);\n\n for (var i$3 = 0; i$3 < 3; i$3++) {\n rgb$3[i$3] = round$2(rgb$3[i$3] * 2.55);\n }\n\n rgb$3[3] = +rgb$3[3];\n return rgb$3;\n } // hsl(0,100%,50%)\n\n\n if (m = css.match(RE_HSL)) {\n var hsl = m.slice(1, 4);\n hsl[1] *= 0.01;\n hsl[2] *= 0.01;\n var rgb$4 = hsl2rgb_1(hsl);\n rgb$4[3] = 1;\n return rgb$4;\n } // hsla(0,100%,50%,0.5)\n\n\n if (m = css.match(RE_HSLA)) {\n var hsl$1 = m.slice(1, 4);\n hsl$1[1] *= 0.01;\n hsl$1[2] *= 0.01;\n var rgb$5 = hsl2rgb_1(hsl$1);\n rgb$5[3] = +m[4]; // default alpha = 1\n\n return rgb$5;\n }\n };\n\n css2rgb.test = function (s) {\n return RE_RGB.test(s) || RE_RGBA.test(s) || RE_RGB_PCT.test(s) || RE_RGBA_PCT.test(s) || RE_HSL.test(s) || RE_HSLA.test(s);\n };\n\n var css2rgb_1 = css2rgb;\n var type$3 = utils.type;\n\n Color_1.prototype.css = function (mode) {\n return rgb2css_1(this._rgb, mode);\n };\n\n chroma_1.css = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['css'])))();\n };\n\n input.format.css = css2rgb_1;\n input.autodetect.push({\n p: 5,\n test: function test(h) {\n var rest = [],\n len = arguments.length - 1;\n\n while (len-- > 0) {\n rest[len] = arguments[len + 1];\n }\n\n if (!rest.length && type$3(h) === 'string' && css2rgb_1.test(h)) {\n return 'css';\n }\n }\n });\n var unpack$8 = utils.unpack;\n\n input.format.gl = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var rgb = unpack$8(args, 'rgba');\n rgb[0] *= 255;\n rgb[1] *= 255;\n rgb[2] *= 255;\n return rgb;\n };\n\n chroma_1.gl = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['gl'])))();\n };\n\n Color_1.prototype.gl = function () {\n var rgb = this._rgb;\n return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];\n };\n\n var unpack$9 = utils.unpack;\n\n var rgb2hcg = function rgb2hcg() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$9(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n var min = Math.min(r, g, b);\n var max = Math.max(r, g, b);\n var delta = max - min;\n var c = delta * 100 / 255;\n\n var _g = min / (255 - delta) * 100;\n\n var h;\n\n if (delta === 0) {\n h = Number.NaN;\n } else {\n if (r === max) {\n h = (g - b) / delta;\n }\n\n if (g === max) {\n h = 2 + (b - r) / delta;\n }\n\n if (b === max) {\n h = 4 + (r - g) / delta;\n }\n\n h *= 60;\n\n if (h < 0) {\n h += 360;\n }\n }\n\n return [h, c, _g];\n };\n\n var rgb2hcg_1 = rgb2hcg;\n var unpack$a = utils.unpack;\n var floor = Math.floor;\n /*\n * this is basically just HSV with some minor tweaks\n *\n * hue.. [0..360]\n * chroma .. [0..1]\n * grayness .. [0..1]\n */\n\n var hcg2rgb = function hcg2rgb() {\n var assign, assign$1, assign$2, assign$3, assign$4, assign$5;\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$a(args, 'hcg');\n var h = args[0];\n var c = args[1];\n var _g = args[2];\n var r, g, b;\n _g = _g * 255;\n\n var _c = c * 255;\n\n if (c === 0) {\n r = g = b = _g;\n } else {\n if (h === 360) {\n h = 0;\n }\n\n if (h > 360) {\n h -= 360;\n }\n\n if (h < 0) {\n h += 360;\n }\n\n h /= 60;\n var i = floor(h);\n var f = h - i;\n var p = _g * (1 - c);\n var q = p + _c * (1 - f);\n var t = p + _c * f;\n var v = p + _c;\n\n switch (i) {\n case 0:\n assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2];\n break;\n\n case 1:\n assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2];\n break;\n\n case 2:\n assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2];\n break;\n\n case 3:\n assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2];\n break;\n\n case 4:\n assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2];\n break;\n\n case 5:\n assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2];\n break;\n }\n }\n\n return [r, g, b, args.length > 3 ? args[3] : 1];\n };\n\n var hcg2rgb_1 = hcg2rgb;\n var unpack$b = utils.unpack;\n var type$4 = utils.type;\n\n Color_1.prototype.hcg = function () {\n return rgb2hcg_1(this._rgb);\n };\n\n chroma_1.hcg = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hcg'])))();\n };\n\n input.format.hcg = hcg2rgb_1;\n input.autodetect.push({\n p: 1,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$b(args, 'hcg');\n\n if (type$4(args) === 'array' && args.length === 3) {\n return 'hcg';\n }\n }\n });\n var unpack$c = utils.unpack;\n var last$4 = utils.last;\n var round$3 = Math.round;\n\n var rgb2hex = function rgb2hex() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$c(args, 'rgba');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n var a = ref[3];\n var mode = last$4(args) || 'auto';\n\n if (a === undefined) {\n a = 1;\n }\n\n if (mode === 'auto') {\n mode = a < 1 ? 'rgba' : 'rgb';\n }\n\n r = round$3(r);\n g = round$3(g);\n b = round$3(b);\n var u = r << 16 | g << 8 | b;\n var str = \"000000\" + u.toString(16); //#.toUpperCase();\n\n str = str.substr(str.length - 6);\n var hxa = '0' + round$3(a * 255).toString(16);\n hxa = hxa.substr(hxa.length - 2);\n\n switch (mode.toLowerCase()) {\n case 'rgba':\n return \"#\" + str + hxa;\n\n case 'argb':\n return \"#\" + hxa + str;\n\n default:\n return \"#\" + str;\n }\n };\n\n var rgb2hex_1 = rgb2hex;\n var RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;\n var RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;\n\n var hex2rgb = function hex2rgb(hex) {\n if (hex.match(RE_HEX)) {\n // remove optional leading #\n if (hex.length === 4 || hex.length === 7) {\n hex = hex.substr(1);\n } // expand short-notation to full six-digit\n\n\n if (hex.length === 3) {\n hex = hex.split('');\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n var u = parseInt(hex, 16);\n var r = u >> 16;\n var g = u >> 8 & 0xFF;\n var b = u & 0xFF;\n return [r, g, b, 1];\n } // match rgba hex format, eg #FF000077\n\n\n if (hex.match(RE_HEXA)) {\n if (hex.length === 5 || hex.length === 9) {\n // remove optional leading #\n hex = hex.substr(1);\n } // expand short-notation to full eight-digit\n\n\n if (hex.length === 4) {\n hex = hex.split('');\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];\n }\n\n var u$1 = parseInt(hex, 16);\n var r$1 = u$1 >> 24 & 0xFF;\n var g$1 = u$1 >> 16 & 0xFF;\n var b$1 = u$1 >> 8 & 0xFF;\n var a = Math.round((u$1 & 0xFF) / 0xFF * 100) / 100;\n return [r$1, g$1, b$1, a];\n } // we used to check for css colors here\n // if _input.css? and rgb = _input.css hex\n // return rgb\n\n\n throw new Error(\"unknown hex color: \" + hex);\n };\n\n var hex2rgb_1 = hex2rgb;\n var type$5 = utils.type;\n\n Color_1.prototype.hex = function (mode) {\n return rgb2hex_1(this._rgb, mode);\n };\n\n chroma_1.hex = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hex'])))();\n };\n\n input.format.hex = hex2rgb_1;\n input.autodetect.push({\n p: 4,\n test: function test(h) {\n var rest = [],\n len = arguments.length - 1;\n\n while (len-- > 0) {\n rest[len] = arguments[len + 1];\n }\n\n if (!rest.length && type$5(h) === 'string' && [3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0) {\n return 'hex';\n }\n }\n });\n var unpack$d = utils.unpack;\n var TWOPI = utils.TWOPI;\n var min = Math.min;\n var sqrt = Math.sqrt;\n var acos = Math.acos;\n\n var rgb2hsi = function rgb2hsi() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n /*\n borrowed from here:\n http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp\n */\n\n\n var ref = unpack$d(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n r /= 255;\n g /= 255;\n b /= 255;\n var h;\n var min_ = min(r, g, b);\n var i = (r + g + b) / 3;\n var s = i > 0 ? 1 - min_ / i : 0;\n\n if (s === 0) {\n h = NaN;\n } else {\n h = (r - g + (r - b)) / 2;\n h /= sqrt((r - g) * (r - g) + (r - b) * (g - b));\n h = acos(h);\n\n if (b > g) {\n h = TWOPI - h;\n }\n\n h /= TWOPI;\n }\n\n return [h * 360, s, i];\n };\n\n var rgb2hsi_1 = rgb2hsi;\n var unpack$e = utils.unpack;\n var limit$1 = utils.limit;\n var TWOPI$1 = utils.TWOPI;\n var PITHIRD = utils.PITHIRD;\n var cos = Math.cos;\n /*\n * hue [0..360]\n * saturation [0..1]\n * intensity [0..1]\n */\n\n var hsi2rgb = function hsi2rgb() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n /*\n borrowed from here:\n http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp\n */\n\n\n args = unpack$e(args, 'hsi');\n var h = args[0];\n var s = args[1];\n var i = args[2];\n var r, g, b;\n\n if (isNaN(h)) {\n h = 0;\n }\n\n if (isNaN(s)) {\n s = 0;\n } // normalize hue\n\n\n if (h > 360) {\n h -= 360;\n }\n\n if (h < 0) {\n h += 360;\n }\n\n h /= 360;\n\n if (h < 1 / 3) {\n b = (1 - s) / 3;\n r = (1 + s * cos(TWOPI$1 * h) / cos(PITHIRD - TWOPI$1 * h)) / 3;\n g = 1 - (b + r);\n } else if (h < 2 / 3) {\n h -= 1 / 3;\n r = (1 - s) / 3;\n g = (1 + s * cos(TWOPI$1 * h) / cos(PITHIRD - TWOPI$1 * h)) / 3;\n b = 1 - (r + g);\n } else {\n h -= 2 / 3;\n g = (1 - s) / 3;\n b = (1 + s * cos(TWOPI$1 * h) / cos(PITHIRD - TWOPI$1 * h)) / 3;\n r = 1 - (g + b);\n }\n\n r = limit$1(i * r * 3);\n g = limit$1(i * g * 3);\n b = limit$1(i * b * 3);\n return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1];\n };\n\n var hsi2rgb_1 = hsi2rgb;\n var unpack$f = utils.unpack;\n var type$6 = utils.type;\n\n Color_1.prototype.hsi = function () {\n return rgb2hsi_1(this._rgb);\n };\n\n chroma_1.hsi = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hsi'])))();\n };\n\n input.format.hsi = hsi2rgb_1;\n input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$f(args, 'hsi');\n\n if (type$6(args) === 'array' && args.length === 3) {\n return 'hsi';\n }\n }\n });\n var unpack$g = utils.unpack;\n var type$7 = utils.type;\n\n Color_1.prototype.hsl = function () {\n return rgb2hsl_1(this._rgb);\n };\n\n chroma_1.hsl = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hsl'])))();\n };\n\n input.format.hsl = hsl2rgb_1;\n input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$g(args, 'hsl');\n\n if (type$7(args) === 'array' && args.length === 3) {\n return 'hsl';\n }\n }\n });\n var unpack$h = utils.unpack;\n var min$1 = Math.min;\n var max$1 = Math.max;\n /*\n * supported arguments:\n * - rgb2hsv(r,g,b)\n * - rgb2hsv([r,g,b])\n * - rgb2hsv({r,g,b})\n */\n\n var rgb2hsl$1 = function rgb2hsl$1() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$h(args, 'rgb');\n var r = args[0];\n var g = args[1];\n var b = args[2];\n var min_ = min$1(r, g, b);\n var max_ = max$1(r, g, b);\n var delta = max_ - min_;\n var h, s, v;\n v = max_ / 255.0;\n\n if (max_ === 0) {\n h = Number.NaN;\n s = 0;\n } else {\n s = delta / max_;\n\n if (r === max_) {\n h = (g - b) / delta;\n }\n\n if (g === max_) {\n h = 2 + (b - r) / delta;\n }\n\n if (b === max_) {\n h = 4 + (r - g) / delta;\n }\n\n h *= 60;\n\n if (h < 0) {\n h += 360;\n }\n }\n\n return [h, s, v];\n };\n\n var rgb2hsv = rgb2hsl$1;\n var unpack$i = utils.unpack;\n var floor$1 = Math.floor;\n\n var hsv2rgb = function hsv2rgb() {\n var assign, assign$1, assign$2, assign$3, assign$4, assign$5;\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$i(args, 'hsv');\n var h = args[0];\n var s = args[1];\n var v = args[2];\n var r, g, b;\n v *= 255;\n\n if (s === 0) {\n r = g = b = v;\n } else {\n if (h === 360) {\n h = 0;\n }\n\n if (h > 360) {\n h -= 360;\n }\n\n if (h < 0) {\n h += 360;\n }\n\n h /= 60;\n var i = floor$1(h);\n var f = h - i;\n var p = v * (1 - s);\n var q = v * (1 - s * f);\n var t = v * (1 - s * (1 - f));\n\n switch (i) {\n case 0:\n assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2];\n break;\n\n case 1:\n assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2];\n break;\n\n case 2:\n assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2];\n break;\n\n case 3:\n assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2];\n break;\n\n case 4:\n assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2];\n break;\n\n case 5:\n assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2];\n break;\n }\n }\n\n return [r, g, b, args.length > 3 ? args[3] : 1];\n };\n\n var hsv2rgb_1 = hsv2rgb;\n var unpack$j = utils.unpack;\n var type$8 = utils.type;\n\n Color_1.prototype.hsv = function () {\n return rgb2hsv(this._rgb);\n };\n\n chroma_1.hsv = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hsv'])))();\n };\n\n input.format.hsv = hsv2rgb_1;\n input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$j(args, 'hsv');\n\n if (type$8(args) === 'array' && args.length === 3) {\n return 'hsv';\n }\n }\n });\n var labConstants = {\n // Corresponds roughly to RGB brighter/darker\n Kn: 18,\n // D65 standard referent\n Xn: 0.950470,\n Yn: 1,\n Zn: 1.088830,\n t0: 0.137931034,\n // 4 / 29\n t1: 0.206896552,\n // 6 / 29\n t2: 0.12841855,\n // 3 * t1 * t1\n t3: 0.008856452 // t1 * t1 * t1\n\n };\n var unpack$k = utils.unpack;\n var pow = Math.pow;\n\n var rgb2lab = function rgb2lab() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$k(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n var ref$1 = rgb2xyz(r, g, b);\n var x = ref$1[0];\n var y = ref$1[1];\n var z = ref$1[2];\n var l = 116 * y - 16;\n return [l < 0 ? 0 : l, 500 * (x - y), 200 * (y - z)];\n };\n\n var rgb_xyz = function rgb_xyz(r) {\n if ((r /= 255) <= 0.04045) {\n return r / 12.92;\n }\n\n return pow((r + 0.055) / 1.055, 2.4);\n };\n\n var xyz_lab = function xyz_lab(t) {\n if (t > labConstants.t3) {\n return pow(t, 1 / 3);\n }\n\n return t / labConstants.t2 + labConstants.t0;\n };\n\n var rgb2xyz = function rgb2xyz(r, g, b) {\n r = rgb_xyz(r);\n g = rgb_xyz(g);\n b = rgb_xyz(b);\n var x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / labConstants.Xn);\n var y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / labConstants.Yn);\n var z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / labConstants.Zn);\n return [x, y, z];\n };\n\n var rgb2lab_1 = rgb2lab;\n var unpack$l = utils.unpack;\n var pow$1 = Math.pow;\n /*\n * L* [0..100]\n * a [-100..100]\n * b [-100..100]\n */\n\n var lab2rgb = function lab2rgb() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$l(args, 'lab');\n var l = args[0];\n var a = args[1];\n var b = args[2];\n var x, y, z, r, g, b_;\n y = (l + 16) / 116;\n x = isNaN(a) ? y : y + a / 500;\n z = isNaN(b) ? y : y - b / 200;\n y = labConstants.Yn * lab_xyz(y);\n x = labConstants.Xn * lab_xyz(x);\n z = labConstants.Zn * lab_xyz(z);\n r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); // D65 -> sRGB\n\n g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z);\n b_ = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z);\n return [r, g, b_, args.length > 3 ? args[3] : 1];\n };\n\n var xyz_rgb = function xyz_rgb(r) {\n return 255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow$1(r, 1 / 2.4) - 0.055);\n };\n\n var lab_xyz = function lab_xyz(t) {\n return t > labConstants.t1 ? t * t * t : labConstants.t2 * (t - labConstants.t0);\n };\n\n var lab2rgb_1 = lab2rgb;\n var unpack$m = utils.unpack;\n var type$9 = utils.type;\n\n Color_1.prototype.lab = function () {\n return rgb2lab_1(this._rgb);\n };\n\n chroma_1.lab = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['lab'])))();\n };\n\n input.format.lab = lab2rgb_1;\n input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$m(args, 'lab');\n\n if (type$9(args) === 'array' && args.length === 3) {\n return 'lab';\n }\n }\n });\n var unpack$n = utils.unpack;\n var RAD2DEG = utils.RAD2DEG;\n var sqrt$1 = Math.sqrt;\n var atan2 = Math.atan2;\n var round$4 = Math.round;\n\n var lab2lch = function lab2lch() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$n(args, 'lab');\n var l = ref[0];\n var a = ref[1];\n var b = ref[2];\n var c = sqrt$1(a * a + b * b);\n var h = (atan2(b, a) * RAD2DEG + 360) % 360;\n\n if (round$4(c * 10000) === 0) {\n h = Number.NaN;\n }\n\n return [l, c, h];\n };\n\n var lab2lch_1 = lab2lch;\n var unpack$o = utils.unpack;\n\n var rgb2lch = function rgb2lch() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$o(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n var ref$1 = rgb2lab_1(r, g, b);\n var l = ref$1[0];\n var a = ref$1[1];\n var b_ = ref$1[2];\n return lab2lch_1(l, a, b_);\n };\n\n var rgb2lch_1 = rgb2lch;\n var unpack$p = utils.unpack;\n var DEG2RAD = utils.DEG2RAD;\n var sin = Math.sin;\n var cos$1 = Math.cos;\n\n var lch2lab = function lch2lab() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n /*\n Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.\n These formulas were invented by David Dalrymple to obtain maximum contrast without going\n out of gamut if the parameters are in the range 0-1.\n A saturation multiplier was added by Gregor Aisch\n */\n\n\n var ref = unpack$p(args, 'lch');\n var l = ref[0];\n var c = ref[1];\n var h = ref[2];\n\n if (isNaN(h)) {\n h = 0;\n }\n\n h = h * DEG2RAD;\n return [l, cos$1(h) * c, sin(h) * c];\n };\n\n var lch2lab_1 = lch2lab;\n var unpack$q = utils.unpack;\n\n var lch2rgb = function lch2rgb() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$q(args, 'lch');\n var l = args[0];\n var c = args[1];\n var h = args[2];\n var ref = lch2lab_1(l, c, h);\n var L = ref[0];\n var a = ref[1];\n var b_ = ref[2];\n var ref$1 = lab2rgb_1(L, a, b_);\n var r = ref$1[0];\n var g = ref$1[1];\n var b = ref$1[2];\n return [r, g, b, args.length > 3 ? args[3] : 1];\n };\n\n var lch2rgb_1 = lch2rgb;\n var unpack$r = utils.unpack;\n\n var hcl2rgb = function hcl2rgb() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var hcl = unpack$r(args, 'hcl').reverse();\n return lch2rgb_1.apply(void 0, hcl);\n };\n\n var hcl2rgb_1 = hcl2rgb;\n var unpack$s = utils.unpack;\n var type$a = utils.type;\n\n Color_1.prototype.lch = function () {\n return rgb2lch_1(this._rgb);\n };\n\n Color_1.prototype.hcl = function () {\n return rgb2lch_1(this._rgb).reverse();\n };\n\n chroma_1.lch = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['lch'])))();\n };\n\n chroma_1.hcl = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['hcl'])))();\n };\n\n input.format.lch = lch2rgb_1;\n input.format.hcl = hcl2rgb_1;\n ['lch', 'hcl'].forEach(function (m) {\n return input.autodetect.push({\n p: 2,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$s(args, m);\n\n if (type$a(args) === 'array' && args.length === 3) {\n return m;\n }\n }\n });\n });\n /**\n \tX11 color names\n \thttp://www.w3.org/TR/css3-color/#svg-color\n */\n\n var w3cx11 = {\n aliceblue: '#f0f8ff',\n antiquewhite: '#faebd7',\n aqua: '#00ffff',\n aquamarine: '#7fffd4',\n azure: '#f0ffff',\n beige: '#f5f5dc',\n bisque: '#ffe4c4',\n black: '#000000',\n blanchedalmond: '#ffebcd',\n blue: '#0000ff',\n blueviolet: '#8a2be2',\n brown: '#a52a2a',\n burlywood: '#deb887',\n cadetblue: '#5f9ea0',\n chartreuse: '#7fff00',\n chocolate: '#d2691e',\n coral: '#ff7f50',\n cornflower: '#6495ed',\n cornflowerblue: '#6495ed',\n cornsilk: '#fff8dc',\n crimson: '#dc143c',\n cyan: '#00ffff',\n darkblue: '#00008b',\n darkcyan: '#008b8b',\n darkgoldenrod: '#b8860b',\n darkgray: '#a9a9a9',\n darkgreen: '#006400',\n darkgrey: '#a9a9a9',\n darkkhaki: '#bdb76b',\n darkmagenta: '#8b008b',\n darkolivegreen: '#556b2f',\n darkorange: '#ff8c00',\n darkorchid: '#9932cc',\n darkred: '#8b0000',\n darksalmon: '#e9967a',\n darkseagreen: '#8fbc8f',\n darkslateblue: '#483d8b',\n darkslategray: '#2f4f4f',\n darkslategrey: '#2f4f4f',\n darkturquoise: '#00ced1',\n darkviolet: '#9400d3',\n deeppink: '#ff1493',\n deepskyblue: '#00bfff',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1e90ff',\n firebrick: '#b22222',\n floralwhite: '#fffaf0',\n forestgreen: '#228b22',\n fuchsia: '#ff00ff',\n gainsboro: '#dcdcdc',\n ghostwhite: '#f8f8ff',\n gold: '#ffd700',\n goldenrod: '#daa520',\n gray: '#808080',\n green: '#008000',\n greenyellow: '#adff2f',\n grey: '#808080',\n honeydew: '#f0fff0',\n hotpink: '#ff69b4',\n indianred: '#cd5c5c',\n indigo: '#4b0082',\n ivory: '#fffff0',\n khaki: '#f0e68c',\n laserlemon: '#ffff54',\n lavender: '#e6e6fa',\n lavenderblush: '#fff0f5',\n lawngreen: '#7cfc00',\n lemonchiffon: '#fffacd',\n lightblue: '#add8e6',\n lightcoral: '#f08080',\n lightcyan: '#e0ffff',\n lightgoldenrod: '#fafad2',\n lightgoldenrodyellow: '#fafad2',\n lightgray: '#d3d3d3',\n lightgreen: '#90ee90',\n lightgrey: '#d3d3d3',\n lightpink: '#ffb6c1',\n lightsalmon: '#ffa07a',\n lightseagreen: '#20b2aa',\n lightskyblue: '#87cefa',\n lightslategray: '#778899',\n lightslategrey: '#778899',\n lightsteelblue: '#b0c4de',\n lightyellow: '#ffffe0',\n lime: '#00ff00',\n limegreen: '#32cd32',\n linen: '#faf0e6',\n magenta: '#ff00ff',\n maroon: '#800000',\n maroon2: '#7f0000',\n maroon3: '#b03060',\n mediumaquamarine: '#66cdaa',\n mediumblue: '#0000cd',\n mediumorchid: '#ba55d3',\n mediumpurple: '#9370db',\n mediumseagreen: '#3cb371',\n mediumslateblue: '#7b68ee',\n mediumspringgreen: '#00fa9a',\n mediumturquoise: '#48d1cc',\n mediumvioletred: '#c71585',\n midnightblue: '#191970',\n mintcream: '#f5fffa',\n mistyrose: '#ffe4e1',\n moccasin: '#ffe4b5',\n navajowhite: '#ffdead',\n navy: '#000080',\n oldlace: '#fdf5e6',\n olive: '#808000',\n olivedrab: '#6b8e23',\n orange: '#ffa500',\n orangered: '#ff4500',\n orchid: '#da70d6',\n palegoldenrod: '#eee8aa',\n palegreen: '#98fb98',\n paleturquoise: '#afeeee',\n palevioletred: '#db7093',\n papayawhip: '#ffefd5',\n peachpuff: '#ffdab9',\n peru: '#cd853f',\n pink: '#ffc0cb',\n plum: '#dda0dd',\n powderblue: '#b0e0e6',\n purple: '#800080',\n purple2: '#7f007f',\n purple3: '#a020f0',\n rebeccapurple: '#663399',\n red: '#ff0000',\n rosybrown: '#bc8f8f',\n royalblue: '#4169e1',\n saddlebrown: '#8b4513',\n salmon: '#fa8072',\n sandybrown: '#f4a460',\n seagreen: '#2e8b57',\n seashell: '#fff5ee',\n sienna: '#a0522d',\n silver: '#c0c0c0',\n skyblue: '#87ceeb',\n slateblue: '#6a5acd',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#fffafa',\n springgreen: '#00ff7f',\n steelblue: '#4682b4',\n tan: '#d2b48c',\n teal: '#008080',\n thistle: '#d8bfd8',\n tomato: '#ff6347',\n turquoise: '#40e0d0',\n violet: '#ee82ee',\n wheat: '#f5deb3',\n white: '#ffffff',\n whitesmoke: '#f5f5f5',\n yellow: '#ffff00',\n yellowgreen: '#9acd32'\n };\n var w3cx11_1 = w3cx11;\n var type$b = utils.type;\n\n Color_1.prototype.name = function () {\n var hex = rgb2hex_1(this._rgb, 'rgb');\n\n for (var i = 0, list = Object.keys(w3cx11_1); i < list.length; i += 1) {\n var n = list[i];\n\n if (w3cx11_1[n] === hex) {\n return n.toLowerCase();\n }\n }\n\n return hex;\n };\n\n input.format.named = function (name) {\n name = name.toLowerCase();\n\n if (w3cx11_1[name]) {\n return hex2rgb_1(w3cx11_1[name]);\n }\n\n throw new Error('unknown color name: ' + name);\n };\n\n input.autodetect.push({\n p: 5,\n test: function test(h) {\n var rest = [],\n len = arguments.length - 1;\n\n while (len-- > 0) {\n rest[len] = arguments[len + 1];\n }\n\n if (!rest.length && type$b(h) === 'string' && w3cx11_1[h.toLowerCase()]) {\n return 'named';\n }\n }\n });\n var unpack$t = utils.unpack;\n\n var rgb2num = function rgb2num() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var ref = unpack$t(args, 'rgb');\n var r = ref[0];\n var g = ref[1];\n var b = ref[2];\n return (r << 16) + (g << 8) + b;\n };\n\n var rgb2num_1 = rgb2num;\n var type$c = utils.type;\n\n var num2rgb = function num2rgb(num) {\n if (type$c(num) == \"number\" && num >= 0 && num <= 0xFFFFFF) {\n var r = num >> 16;\n var g = num >> 8 & 0xFF;\n var b = num & 0xFF;\n return [r, g, b, 1];\n }\n\n throw new Error(\"unknown num color: \" + num);\n };\n\n var num2rgb_1 = num2rgb;\n var type$d = utils.type;\n\n Color_1.prototype.num = function () {\n return rgb2num_1(this._rgb);\n };\n\n chroma_1.num = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['num'])))();\n };\n\n input.format.num = num2rgb_1;\n input.autodetect.push({\n p: 5,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n if (args.length === 1 && type$d(args[0]) === 'number' && args[0] >= 0 && args[0] <= 0xFFFFFF) {\n return 'num';\n }\n }\n });\n var unpack$u = utils.unpack;\n var type$e = utils.type;\n var round$5 = Math.round;\n\n Color_1.prototype.rgb = function (rnd) {\n if (rnd === void 0) rnd = true;\n\n if (rnd === false) {\n return this._rgb.slice(0, 3);\n }\n\n return this._rgb.slice(0, 3).map(round$5);\n };\n\n Color_1.prototype.rgba = function (rnd) {\n if (rnd === void 0) rnd = true;\n return this._rgb.slice(0, 4).map(function (v, i) {\n return i < 3 ? rnd === false ? v : round$5(v) : v;\n });\n };\n\n chroma_1.rgb = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['rgb'])))();\n };\n\n input.format.rgb = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var rgba = unpack$u(args, 'rgba');\n\n if (rgba[3] === undefined) {\n rgba[3] = 1;\n }\n\n return rgba;\n };\n\n input.autodetect.push({\n p: 3,\n test: function test() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n args = unpack$u(args, 'rgba');\n\n if (type$e(args) === 'array' && (args.length === 3 || args.length === 4 && type$e(args[3]) == 'number' && args[3] >= 0 && args[3] <= 1)) {\n return 'rgb';\n }\n }\n });\n /*\n * Based on implementation by Neil Bartlett\n * https://github.com/neilbartlett/color-temperature\n */\n\n var log = Math.log;\n\n var temperature2rgb = function temperature2rgb(kelvin) {\n var temp = kelvin / 100;\n var r, g, b;\n\n if (temp < 66) {\n r = 255;\n g = -155.25485562709179 - 0.44596950469579133 * (g = temp - 2) + 104.49216199393888 * log(g);\n b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp - 10) + 115.67994401066147 * log(b);\n } else {\n r = 351.97690566805693 + 0.114206453784165 * (r = temp - 55) - 40.25366309332127 * log(r);\n g = 325.4494125711974 + 0.07943456536662342 * (g = temp - 50) - 28.0852963507957 * log(g);\n b = 255;\n }\n\n return [r, g, b, 1];\n };\n\n var temperature2rgb_1 = temperature2rgb;\n /*\n * Based on implementation by Neil Bartlett\n * https://github.com/neilbartlett/color-temperature\n **/\n\n var unpack$v = utils.unpack;\n var round$6 = Math.round;\n\n var rgb2temperature = function rgb2temperature() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n var rgb = unpack$v(args, 'rgb');\n var r = rgb[0],\n b = rgb[2];\n var minTemp = 1000;\n var maxTemp = 40000;\n var eps = 0.4;\n var temp;\n\n while (maxTemp - minTemp > eps) {\n temp = (maxTemp + minTemp) * 0.5;\n var rgb$1 = temperature2rgb_1(temp);\n\n if (rgb$1[2] / rgb$1[0] >= b / r) {\n maxTemp = temp;\n } else {\n minTemp = temp;\n }\n }\n\n return round$6(temp);\n };\n\n var rgb2temperature_1 = rgb2temperature;\n\n Color_1.prototype.temp = Color_1.prototype.kelvin = Color_1.prototype.temperature = function () {\n return rgb2temperature_1(this._rgb);\n };\n\n chroma_1.temp = chroma_1.kelvin = chroma_1.temperature = function () {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n return new (Function.prototype.bind.apply(Color_1, [null].concat(args, ['temp'])))();\n };\n\n input.format.temp = input.format.kelvin = input.format.temperature = temperature2rgb_1;\n var type$f = utils.type;\n\n Color_1.prototype.alpha = function (a, mutate) {\n if (mutate === void 0) mutate = false;\n\n if (a !== undefined && type$f(a) === 'number') {\n if (mutate) {\n this._rgb[3] = a;\n return this;\n }\n\n return new Color_1([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');\n }\n\n return this._rgb[3];\n };\n\n Color_1.prototype.clipped = function () {\n return this._rgb._clipped || false;\n };\n\n Color_1.prototype.darken = function (amount) {\n if (amount === void 0) amount = 1;\n var me = this;\n var lab = me.lab();\n lab[0] -= labConstants.Kn * amount;\n return new Color_1(lab, 'lab').alpha(me.alpha(), true);\n };\n\n Color_1.prototype.brighten = function (amount) {\n if (amount === void 0) amount = 1;\n return this.darken(-amount);\n };\n\n Color_1.prototype.darker = Color_1.prototype.darken;\n Color_1.prototype.brighter = Color_1.prototype.brighten;\n\n Color_1.prototype.get = function (mc) {\n var ref = mc.split('.');\n var mode = ref[0];\n var channel = ref[1];\n var src = this[mode]();\n\n if (channel) {\n var i = mode.indexOf(channel);\n\n if (i > -1) {\n return src[i];\n }\n\n throw new Error(\"unknown channel \" + channel + \" in mode \" + mode);\n } else {\n return src;\n }\n };\n\n var type$g = utils.type;\n var pow$2 = Math.pow;\n var EPS = 1e-7;\n var MAX_ITER = 20;\n\n Color_1.prototype.luminance = function (lum) {\n if (lum !== undefined && type$g(lum) === 'number') {\n if (lum === 0) {\n // return pure black\n return new Color_1([0, 0, 0, this._rgb[3]], 'rgb');\n }\n\n if (lum === 1) {\n // return pure white\n return new Color_1([255, 255, 255, this._rgb[3]], 'rgb');\n } // compute new color using...\n\n\n var cur_lum = this.luminance();\n var mode = 'rgb';\n var max_iter = MAX_ITER;\n\n var test = function test(low, high) {\n var mid = low.interpolate(high, 0.5, mode);\n var lm = mid.luminance();\n\n if (Math.abs(lum - lm) < EPS || !max_iter--) {\n // close enough\n return mid;\n }\n\n return lm > lum ? test(low, mid) : test(mid, high);\n };\n\n var rgb = (cur_lum > lum ? test(new Color_1([0, 0, 0]), this) : test(this, new Color_1([255, 255, 255]))).rgb();\n return new Color_1(rgb.concat([this._rgb[3]]));\n }\n\n return rgb2luminance.apply(void 0, this._rgb.slice(0, 3));\n };\n\n var rgb2luminance = function rgb2luminance(r, g, b) {\n // relative luminance\n // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef\n r = luminance_x(r);\n g = luminance_x(g);\n b = luminance_x(b);\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n };\n\n var luminance_x = function luminance_x(x) {\n x /= 255;\n return x <= 0.03928 ? x / 12.92 : pow$2((x + 0.055) / 1.055, 2.4);\n };\n\n var interpolator = {};\n var type$h = utils.type;\n\n var mix = function mix(col1, col2, f) {\n if (f === void 0) f = 0.5;\n var rest = [],\n len = arguments.length - 3;\n\n while (len-- > 0) {\n rest[len] = arguments[len + 3];\n }\n\n var mode = rest[0] || 'lrgb';\n\n if (!interpolator[mode] && !rest.length) {\n // fall back to the first supported mode\n mode = Object.keys(interpolator)[0];\n }\n\n if (!interpolator[mode]) {\n throw new Error(\"interpolation mode \" + mode + \" is not defined\");\n }\n\n if (type$h(col1) !== 'object') {\n col1 = new Color_1(col1);\n }\n\n if (type$h(col2) !== 'object') {\n col2 = new Color_1(col2);\n }\n\n return interpolator[mode](col1, col2, f).alpha(col1.alpha() + f * (col2.alpha() - col1.alpha()));\n };\n\n Color_1.prototype.mix = Color_1.prototype.interpolate = function (col2, f) {\n if (f === void 0) f = 0.5;\n var rest = [],\n len = arguments.length - 2;\n\n while (len-- > 0) {\n rest[len] = arguments[len + 2];\n }\n\n return mix.apply(void 0, [this, col2, f].concat(rest));\n };\n\n Color_1.prototype.premultiply = function (mutate) {\n if (mutate === void 0) mutate = false;\n var rgb = this._rgb;\n var a = rgb[3];\n\n if (mutate) {\n this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];\n return this;\n } else {\n return new Color_1([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');\n }\n };\n\n Color_1.prototype.saturate = function (amount) {\n if (amount === void 0) amount = 1;\n var me = this;\n var lch = me.lch();\n lch[1] += labConstants.Kn * amount;\n\n if (lch[1] < 0) {\n lch[1] = 0;\n }\n\n return new Color_1(lch, 'lch').alpha(me.alpha(), true);\n };\n\n Color_1.prototype.desaturate = function (amount) {\n if (amount === void 0) amount = 1;\n return this.saturate(-amount);\n };\n\n var type$i = utils.type;\n\n Color_1.prototype.set = function (mc, value, mutate) {\n if (mutate === void 0) mutate = false;\n var ref = mc.split('.');\n var mode = ref[0];\n var channel = ref[1];\n var src = this[mode]();\n\n if (channel) {\n var i = mode.indexOf(channel);\n\n if (i > -1) {\n if (type$i(value) == 'string') {\n switch (value.charAt(0)) {\n case '+':\n src[i] += +value;\n break;\n\n case '-':\n src[i] += +value;\n break;\n\n case '*':\n src[i] *= +value.substr(1);\n break;\n\n case '/':\n src[i] /= +value.substr(1);\n break;\n\n default:\n src[i] = +value;\n }\n } else if (type$i(value) === 'number') {\n src[i] = value;\n } else {\n throw new Error(\"unsupported value for Color.set\");\n }\n\n var out = new Color_1(src, mode);\n\n if (mutate) {\n this._rgb = out._rgb;\n return this;\n }\n\n return out;\n }\n\n throw new Error(\"unknown channel \" + channel + \" in mode \" + mode);\n } else {\n return src;\n }\n };\n\n var rgb$1 = function rgb$1(col1, col2, f) {\n var xyz0 = col1._rgb;\n var xyz1 = col2._rgb;\n return new Color_1(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), 'rgb');\n }; // register interpolator\n\n\n interpolator.rgb = rgb$1;\n var sqrt$2 = Math.sqrt;\n var pow$3 = Math.pow;\n\n var lrgb = function lrgb(col1, col2, f) {\n var ref = col1._rgb;\n var x1 = ref[0];\n var y1 = ref[1];\n var z1 = ref[2];\n var ref$1 = col2._rgb;\n var x2 = ref$1[0];\n var y2 = ref$1[1];\n var z2 = ref$1[2];\n return new Color_1(sqrt$2(pow$3(x1, 2) * (1 - f) + pow$3(x2, 2) * f), sqrt$2(pow$3(y1, 2) * (1 - f) + pow$3(y2, 2) * f), sqrt$2(pow$3(z1, 2) * (1 - f) + pow$3(z2, 2) * f), 'rgb');\n }; // register interpolator\n\n\n interpolator.lrgb = lrgb;\n\n var lab$1 = function lab$1(col1, col2, f) {\n var xyz0 = col1.lab();\n var xyz1 = col2.lab();\n return new Color_1(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), 'lab');\n }; // register interpolator\n\n\n interpolator.lab = lab$1;\n\n var _hsx = function _hsx(col1, col2, f, m) {\n var assign, assign$1;\n var xyz0, xyz1;\n\n if (m === 'hsl') {\n xyz0 = col1.hsl();\n xyz1 = col2.hsl();\n } else if (m === 'hsv') {\n xyz0 = col1.hsv();\n xyz1 = col2.hsv();\n } else if (m === 'hcg') {\n xyz0 = col1.hcg();\n xyz1 = col2.hcg();\n } else if (m === 'hsi') {\n xyz0 = col1.hsi();\n xyz1 = col2.hsi();\n } else if (m === 'lch' || m === 'hcl') {\n m = 'hcl';\n xyz0 = col1.hcl();\n xyz1 = col2.hcl();\n }\n\n var hue0, hue1, sat0, sat1, lbv0, lbv1;\n\n if (m.substr(0, 1) === 'h') {\n assign = xyz0, hue0 = assign[0], sat0 = assign[1], lbv0 = assign[2];\n assign$1 = xyz1, hue1 = assign$1[0], sat1 = assign$1[1], lbv1 = assign$1[2];\n }\n\n var sat, hue, lbv, dh;\n\n if (!isNaN(hue0) && !isNaN(hue1)) {\n // both colors have hue\n if (hue1 > hue0 && hue1 - hue0 > 180) {\n dh = hue1 - (hue0 + 360);\n } else if (hue1 < hue0 && hue0 - hue1 > 180) {\n dh = hue1 + 360 - hue0;\n } else {\n dh = hue1 - hue0;\n }\n\n hue = hue0 + f * dh;\n } else if (!isNaN(hue0)) {\n hue = hue0;\n\n if ((lbv1 == 1 || lbv1 == 0) && m != 'hsv') {\n sat = sat0;\n }\n } else if (!isNaN(hue1)) {\n hue = hue1;\n\n if ((lbv0 == 1 || lbv0 == 0) && m != 'hsv') {\n sat = sat1;\n }\n } else {\n hue = Number.NaN;\n }\n\n if (sat === undefined) {\n sat = sat0 + f * (sat1 - sat0);\n }\n\n lbv = lbv0 + f * (lbv1 - lbv0);\n return new Color_1([hue, sat, lbv], m);\n };\n\n var lch$1 = function lch$1(col1, col2, f) {\n return _hsx(col1, col2, f, 'lch');\n }; // register interpolator\n\n\n interpolator.lch = lch$1;\n interpolator.hcl = lch$1;\n\n var num$1 = function num$1(col1, col2, f) {\n var c1 = col1.num();\n var c2 = col2.num();\n return new Color_1(c1 + f * (c2 - c1), 'num');\n }; // register interpolator\n\n\n interpolator.num = num$1;\n\n var hcg$1 = function hcg$1(col1, col2, f) {\n return _hsx(col1, col2, f, 'hcg');\n }; // register interpolator\n\n\n interpolator.hcg = hcg$1;\n\n var hsi$1 = function hsi$1(col1, col2, f) {\n return _hsx(col1, col2, f, 'hsi');\n }; // register interpolator\n\n\n interpolator.hsi = hsi$1;\n\n var hsl$1 = function hsl$1(col1, col2, f) {\n return _hsx(col1, col2, f, 'hsl');\n }; // register interpolator\n\n\n interpolator.hsl = hsl$1;\n\n var hsv$1 = function hsv$1(col1, col2, f) {\n return _hsx(col1, col2, f, 'hsv');\n }; // register interpolator\n\n\n interpolator.hsv = hsv$1;\n var clip_rgb$2 = utils.clip_rgb;\n var pow$4 = Math.pow;\n var sqrt$3 = Math.sqrt;\n var PI$1 = Math.PI;\n var cos$2 = Math.cos;\n var sin$1 = Math.sin;\n var atan2$1 = Math.atan2;\n\n var average = function average(colors, mode, weights) {\n if (mode === void 0) mode = 'lrgb';\n if (weights === void 0) weights = null;\n var l = colors.length;\n\n if (!weights) {\n weights = Array.from(new Array(l)).map(function () {\n return 1;\n });\n } // normalize weights\n\n\n var k = l / weights.reduce(function (a, b) {\n return a + b;\n });\n weights.forEach(function (w, i) {\n weights[i] *= k;\n }); // convert colors to Color objects\n\n colors = colors.map(function (c) {\n return new Color_1(c);\n });\n\n if (mode === 'lrgb') {\n return _average_lrgb(colors, weights);\n }\n\n var first = colors.shift();\n var xyz = first.get(mode);\n var cnt = [];\n var dx = 0;\n var dy = 0; // initial color\n\n for (var i = 0; i < xyz.length; i++) {\n xyz[i] = (xyz[i] || 0) * weights[0];\n cnt.push(isNaN(xyz[i]) ? 0 : weights[0]);\n\n if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) {\n var A = xyz[i] / 180 * PI$1;\n dx += cos$2(A) * weights[0];\n dy += sin$1(A) * weights[0];\n }\n }\n\n var alpha = first.alpha() * weights[0];\n colors.forEach(function (c, ci) {\n var xyz2 = c.get(mode);\n alpha += c.alpha() * weights[ci + 1];\n\n for (var i = 0; i < xyz.length; i++) {\n if (!isNaN(xyz2[i])) {\n cnt[i] += weights[ci + 1];\n\n if (mode.charAt(i) === 'h') {\n var A = xyz2[i] / 180 * PI$1;\n dx += cos$2(A) * weights[ci + 1];\n dy += sin$1(A) * weights[ci + 1];\n } else {\n xyz[i] += xyz2[i] * weights[ci + 1];\n }\n }\n }\n });\n\n for (var i$1 = 0; i$1 < xyz.length; i$1++) {\n if (mode.charAt(i$1) === 'h') {\n var A$1 = atan2$1(dy / cnt[i$1], dx / cnt[i$1]) / PI$1 * 180;\n\n while (A$1 < 0) {\n A$1 += 360;\n }\n\n while (A$1 >= 360) {\n A$1 -= 360;\n }\n\n xyz[i$1] = A$1;\n } else {\n xyz[i$1] = xyz[i$1] / cnt[i$1];\n }\n }\n\n alpha /= l;\n return new Color_1(xyz, mode).alpha(alpha > 0.99999 ? 1 : alpha, true);\n };\n\n var _average_lrgb = function _average_lrgb(colors, weights) {\n var l = colors.length;\n var xyz = [0, 0, 0, 0];\n\n for (var i = 0; i < colors.length; i++) {\n var col = colors[i];\n var f = weights[i] / l;\n var rgb = col._rgb;\n xyz[0] += pow$4(rgb[0], 2) * f;\n xyz[1] += pow$4(rgb[1], 2) * f;\n xyz[2] += pow$4(rgb[2], 2) * f;\n xyz[3] += rgb[3] * f;\n }\n\n xyz[0] = sqrt$3(xyz[0]);\n xyz[1] = sqrt$3(xyz[1]);\n xyz[2] = sqrt$3(xyz[2]);\n\n if (xyz[3] > 0.9999999) {\n xyz[3] = 1;\n }\n\n return new Color_1(clip_rgb$2(xyz));\n }; // minimal multi-purpose interface\n // @requires utils color analyze\n\n\n var type$j = utils.type;\n var pow$5 = Math.pow;\n\n var scale = function scale(colors) {\n // constructor\n var _mode = 'rgb';\n\n var _nacol = chroma_1('#ccc');\n\n var _spread = 0; // const _fixed = false;\n\n var _domain = [0, 1];\n var _pos = [];\n var _padding = [0, 0];\n var _classes = false;\n var _colors = [];\n var _out = false;\n var _min = 0;\n var _max = 1;\n var _correctLightness = false;\n var _colorCache = {};\n var _useCache = true;\n var _gamma = 1; // private methods\n\n var setColors = function setColors(colors) {\n colors = colors || ['#fff', '#000'];\n\n if (colors && type$j(colors) === 'string' && chroma_1.brewer && chroma_1.brewer[colors.toLowerCase()]) {\n colors = chroma_1.brewer[colors.toLowerCase()];\n }\n\n if (type$j(colors) === 'array') {\n // handle single color\n if (colors.length === 1) {\n colors = [colors[0], colors[0]];\n } // make a copy of the colors\n\n\n colors = colors.slice(0); // convert to chroma classes\n\n for (var c = 0; c < colors.length; c++) {\n colors[c] = chroma_1(colors[c]);\n } // auto-fill color position\n\n\n _pos.length = 0;\n\n for (var c$1 = 0; c$1 < colors.length; c$1++) {\n _pos.push(c$1 / (colors.length - 1));\n }\n }\n\n resetCache();\n return _colors = colors;\n };\n\n var getClass = function getClass(value) {\n if (_classes != null) {\n var n = _classes.length - 1;\n var i = 0;\n\n while (i < n && value >= _classes[i]) {\n i++;\n }\n\n return i - 1;\n }\n\n return 0;\n };\n\n var tMapLightness = function tMapLightness(t) {\n return t;\n };\n\n var tMapDomain = function tMapDomain(t) {\n return t;\n }; // const classifyValue = function(value) {\n // let val = value;\n // if (_classes.length > 2) {\n // const n = _classes.length-1;\n // const i = getClass(value);\n // const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class\n // const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class\n // val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));\n // }\n // return val;\n // };\n\n\n var getColor = function getColor(val, bypassMap) {\n var col, t;\n\n if (bypassMap == null) {\n bypassMap = false;\n }\n\n if (isNaN(val) || val === null) {\n return _nacol;\n }\n\n if (!bypassMap) {\n if (_classes && _classes.length > 2) {\n // find the class\n var c = getClass(val);\n t = c / (_classes.length - 2);\n } else if (_max !== _min) {\n // just interpolate between min/max\n t = (val - _min) / (_max - _min);\n } else {\n t = 1;\n }\n } else {\n t = val;\n } // domain map\n\n\n t = tMapDomain(t);\n\n if (!bypassMap) {\n t = tMapLightness(t); // lightness correction\n }\n\n if (_gamma !== 1) {\n t = pow$5(t, _gamma);\n }\n\n t = _padding[0] + t * (1 - _padding[0] - _padding[1]);\n t = Math.min(1, Math.max(0, t));\n var k = Math.floor(t * 10000);\n\n if (_useCache && _colorCache[k]) {\n col = _colorCache[k];\n } else {\n if (type$j(_colors) === 'array') {\n //for i in [0.._pos.length-1]\n for (var i = 0; i < _pos.length; i++) {\n var p = _pos[i];\n\n if (t <= p) {\n col = _colors[i];\n break;\n }\n\n if (t >= p && i === _pos.length - 1) {\n col = _colors[i];\n break;\n }\n\n if (t > p && t < _pos[i + 1]) {\n t = (t - p) / (_pos[i + 1] - p);\n col = chroma_1.interpolate(_colors[i], _colors[i + 1], t, _mode);\n break;\n }\n }\n } else if (type$j(_colors) === 'function') {\n col = _colors(t);\n }\n\n if (_useCache) {\n _colorCache[k] = col;\n }\n }\n\n return col;\n };\n\n var resetCache = function resetCache() {\n return _colorCache = {};\n };\n\n setColors(colors); // public interface\n\n var f = function f(v) {\n var c = chroma_1(getColor(v));\n\n if (_out && c[_out]) {\n return c[_out]();\n } else {\n return c;\n }\n };\n\n f.classes = function (classes) {\n if (classes != null) {\n if (type$j(classes) === 'array') {\n _classes = classes;\n _domain = [classes[0], classes[classes.length - 1]];\n } else {\n var d = chroma_1.analyze(_domain);\n\n if (classes === 0) {\n _classes = [d.min, d.max];\n } else {\n _classes = chroma_1.limits(d, 'e', classes);\n }\n }\n\n return f;\n }\n\n return _classes;\n };\n\n f.domain = function (domain) {\n if (!arguments.length) {\n return _domain;\n }\n\n _min = domain[0];\n _max = domain[domain.length - 1];\n _pos = [];\n var k = _colors.length;\n\n if (domain.length === k && _min !== _max) {\n // update positions\n for (var i = 0, list = Array.from(domain); i < list.length; i += 1) {\n var d = list[i];\n\n _pos.push((d - _min) / (_max - _min));\n }\n } else {\n for (var c = 0; c < k; c++) {\n _pos.push(c / (k - 1));\n }\n\n if (domain.length > 2) {\n // set domain map\n var tOut = domain.map(function (d, i) {\n return i / (domain.length - 1);\n });\n var tBreaks = domain.map(function (d) {\n return (d - _min) / (_max - _min);\n });\n\n if (!tBreaks.every(function (val, i) {\n return tOut[i] === val;\n })) {\n tMapDomain = function tMapDomain(t) {\n if (t <= 0 || t >= 1) {\n return t;\n }\n\n var i = 0;\n\n while (t >= tBreaks[i + 1]) {\n i++;\n }\n\n var f = (t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);\n var out = tOut[i] + f * (tOut[i + 1] - tOut[i]);\n return out;\n };\n }\n }\n }\n\n _domain = [_min, _max];\n return f;\n };\n\n f.mode = function (_m) {\n if (!arguments.length) {\n return _mode;\n }\n\n _mode = _m;\n resetCache();\n return f;\n };\n\n f.range = function (colors, _pos) {\n setColors(colors, _pos);\n return f;\n };\n\n f.out = function (_o) {\n _out = _o;\n return f;\n };\n\n f.spread = function (val) {\n if (!arguments.length) {\n return _spread;\n }\n\n _spread = val;\n return f;\n };\n\n f.correctLightness = function (v) {\n if (v == null) {\n v = true;\n }\n\n _correctLightness = v;\n resetCache();\n\n if (_correctLightness) {\n tMapLightness = function tMapLightness(t) {\n var L0 = getColor(0, true).lab()[0];\n var L1 = getColor(1, true).lab()[0];\n var pol = L0 > L1;\n var L_actual = getColor(t, true).lab()[0];\n var L_ideal = L0 + (L1 - L0) * t;\n var L_diff = L_actual - L_ideal;\n var t0 = 0;\n var t1 = 1;\n var max_iter = 20;\n\n while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {\n (function () {\n if (pol) {\n L_diff *= -1;\n }\n\n if (L_diff < 0) {\n t0 = t;\n t += (t1 - t) * 0.5;\n } else {\n t1 = t;\n t += (t0 - t) * 0.5;\n }\n\n L_actual = getColor(t, true).lab()[0];\n return L_diff = L_actual - L_ideal;\n })();\n }\n\n return t;\n };\n } else {\n tMapLightness = function tMapLightness(t) {\n return t;\n };\n }\n\n return f;\n };\n\n f.padding = function (p) {\n if (p != null) {\n if (type$j(p) === 'number') {\n p = [p, p];\n }\n\n _padding = p;\n return f;\n } else {\n return _padding;\n }\n };\n\n f.colors = function (numColors, out) {\n // If no arguments are given, return the original colors that were provided\n if (arguments.length < 2) {\n out = 'hex';\n }\n\n var result = [];\n\n if (arguments.length === 0) {\n result = _colors.slice(0);\n } else if (numColors === 1) {\n result = [f(0.5)];\n } else if (numColors > 1) {\n var dm = _domain[0];\n var dd = _domain[1] - dm;\n result = __range__(0, numColors, false).map(function (i) {\n return f(dm + i / (numColors - 1) * dd);\n });\n } else {\n // returns all colors based on the defined classes\n colors = [];\n var samples = [];\n\n if (_classes && _classes.length > 2) {\n for (var i = 1, end = _classes.length, asc = 1 <= end; asc ? i < end : i > end; asc ? i++ : i--) {\n samples.push((_classes[i - 1] + _classes[i]) * 0.5);\n }\n } else {\n samples = _domain;\n }\n\n result = samples.map(function (v) {\n return f(v);\n });\n }\n\n if (chroma_1[out]) {\n result = result.map(function (c) {\n return c[out]();\n });\n }\n\n return result;\n };\n\n f.cache = function (c) {\n if (c != null) {\n _useCache = c;\n return f;\n } else {\n return _useCache;\n }\n };\n\n f.gamma = function (g) {\n if (g != null) {\n _gamma = g;\n return f;\n } else {\n return _gamma;\n }\n };\n\n f.nodata = function (d) {\n if (d != null) {\n _nacol = chroma_1(d);\n return f;\n } else {\n return _nacol;\n }\n };\n\n return f;\n };\n\n function __range__(left, right, inclusive) {\n var range = [];\n var ascending = left < right;\n var end = !inclusive ? right : ascending ? right + 1 : right - 1;\n\n for (var i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {\n range.push(i);\n }\n\n return range;\n } //\n // interpolates between a set of colors uzing a bezier spline\n //\n // @requires utils lab\n\n\n var bezier = function bezier(colors) {\n var assign, assign$1, assign$2;\n var I, lab0, lab1, lab2;\n colors = colors.map(function (c) {\n return new Color_1(c);\n });\n\n if (colors.length === 2) {\n // linear interpolation\n assign = colors.map(function (c) {\n return c.lab();\n }), lab0 = assign[0], lab1 = assign[1];\n\n I = function I(t) {\n var lab = [0, 1, 2].map(function (i) {\n return lab0[i] + t * (lab1[i] - lab0[i]);\n });\n return new Color_1(lab, 'lab');\n };\n } else if (colors.length === 3) {\n // quadratic bezier interpolation\n assign$1 = colors.map(function (c) {\n return c.lab();\n }), lab0 = assign$1[0], lab1 = assign$1[1], lab2 = assign$1[2];\n\n I = function I(t) {\n var lab = [0, 1, 2].map(function (i) {\n return (1 - t) * (1 - t) * lab0[i] + 2 * (1 - t) * t * lab1[i] + t * t * lab2[i];\n });\n return new Color_1(lab, 'lab');\n };\n } else if (colors.length === 4) {\n // cubic bezier interpolation\n var lab3;\n assign$2 = colors.map(function (c) {\n return c.lab();\n }), lab0 = assign$2[0], lab1 = assign$2[1], lab2 = assign$2[2], lab3 = assign$2[3];\n\n I = function I(t) {\n var lab = [0, 1, 2].map(function (i) {\n return (1 - t) * (1 - t) * (1 - t) * lab0[i] + 3 * (1 - t) * (1 - t) * t * lab1[i] + 3 * (1 - t) * t * t * lab2[i] + t * t * t * lab3[i];\n });\n return new Color_1(lab, 'lab');\n };\n } else if (colors.length === 5) {\n var I0 = bezier(colors.slice(0, 3));\n var I1 = bezier(colors.slice(2, 5));\n\n I = function I(t) {\n if (t < 0.5) {\n return I0(t * 2);\n } else {\n return I1((t - 0.5) * 2);\n }\n };\n }\n\n return I;\n };\n\n var bezier_1 = function bezier_1(colors) {\n var f = bezier(colors);\n\n f.scale = function () {\n return scale(f);\n };\n\n return f;\n };\n /*\n * interpolates between a set of colors uzing a bezier spline\n * blend mode formulas taken from http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/\n */\n\n\n var blend = function blend(bottom, top, mode) {\n if (!blend[mode]) {\n throw new Error('unknown blend mode ' + mode);\n }\n\n return blend[mode](bottom, top);\n };\n\n var blend_f = function blend_f(f) {\n return function (bottom, top) {\n var c0 = chroma_1(top).rgb();\n var c1 = chroma_1(bottom).rgb();\n return chroma_1.rgb(f(c0, c1));\n };\n };\n\n var each = function each(f) {\n return function (c0, c1) {\n var out = [];\n out[0] = f(c0[0], c1[0]);\n out[1] = f(c0[1], c1[1]);\n out[2] = f(c0[2], c1[2]);\n return out;\n };\n };\n\n var normal = function normal(a) {\n return a;\n };\n\n var multiply = function multiply(a, b) {\n return a * b / 255;\n };\n\n var darken$1 = function darken$1(a, b) {\n return a > b ? b : a;\n };\n\n var lighten = function lighten(a, b) {\n return a > b ? a : b;\n };\n\n var screen = function screen(a, b) {\n return 255 * (1 - (1 - a / 255) * (1 - b / 255));\n };\n\n var overlay = function overlay(a, b) {\n return b < 128 ? 2 * a * b / 255 : 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255));\n };\n\n var burn = function burn(a, b) {\n return 255 * (1 - (1 - b / 255) / (a / 255));\n };\n\n var dodge = function dodge(a, b) {\n if (a === 255) {\n return 255;\n }\n\n a = 255 * (b / 255) / (1 - a / 255);\n return a > 255 ? 255 : a;\n }; // # add = (a,b) ->\n // # if (a + b > 255) then 255 else a + b\n\n\n blend.normal = blend_f(each(normal));\n blend.multiply = blend_f(each(multiply));\n blend.screen = blend_f(each(screen));\n blend.overlay = blend_f(each(overlay));\n blend.darken = blend_f(each(darken$1));\n blend.lighten = blend_f(each(lighten));\n blend.dodge = blend_f(each(dodge));\n blend.burn = blend_f(each(burn)); // blend.add = blend_f(each(add));\n\n var blend_1 = blend; // cubehelix interpolation\n // based on D.A. Green \"A colour scheme for the display of astronomical intensity images\"\n // http://astron-soc.in/bulletin/11June/289392011.pdf\n\n var type$k = utils.type;\n var clip_rgb$3 = utils.clip_rgb;\n var TWOPI$2 = utils.TWOPI;\n var pow$6 = Math.pow;\n var sin$2 = Math.sin;\n var cos$3 = Math.cos;\n\n var cubehelix = function cubehelix(start, rotations, hue, gamma, lightness) {\n if (start === void 0) start = 300;\n if (rotations === void 0) rotations = -1.5;\n if (hue === void 0) hue = 1;\n if (gamma === void 0) gamma = 1;\n if (lightness === void 0) lightness = [0, 1];\n var dh = 0,\n dl;\n\n if (type$k(lightness) === 'array') {\n dl = lightness[1] - lightness[0];\n } else {\n dl = 0;\n lightness = [lightness, lightness];\n }\n\n var f = function f(fract) {\n var a = TWOPI$2 * ((start + 120) / 360 + rotations * fract);\n var l = pow$6(lightness[0] + dl * fract, gamma);\n var h = dh !== 0 ? hue[0] + fract * dh : hue;\n var amp = h * l * (1 - l) / 2;\n var cos_a = cos$3(a);\n var sin_a = sin$2(a);\n var r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a);\n var g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a);\n var b = l + amp * (+1.97294 * cos_a);\n return chroma_1(clip_rgb$3([r * 255, g * 255, b * 255, 1]));\n };\n\n f.start = function (s) {\n if (s == null) {\n return start;\n }\n\n start = s;\n return f;\n };\n\n f.rotations = function (r) {\n if (r == null) {\n return rotations;\n }\n\n rotations = r;\n return f;\n };\n\n f.gamma = function (g) {\n if (g == null) {\n return gamma;\n }\n\n gamma = g;\n return f;\n };\n\n f.hue = function (h) {\n if (h == null) {\n return hue;\n }\n\n hue = h;\n\n if (type$k(hue) === 'array') {\n dh = hue[1] - hue[0];\n\n if (dh === 0) {\n hue = hue[1];\n }\n } else {\n dh = 0;\n }\n\n return f;\n };\n\n f.lightness = function (h) {\n if (h == null) {\n return lightness;\n }\n\n if (type$k(h) === 'array') {\n lightness = h;\n dl = h[1] - h[0];\n } else {\n lightness = [h, h];\n dl = 0;\n }\n\n return f;\n };\n\n f.scale = function () {\n return chroma_1.scale(f);\n };\n\n f.hue(hue);\n return f;\n };\n\n var digits = '0123456789abcdef';\n var floor$2 = Math.floor;\n var random = Math.random;\n\n var random_1 = function random_1() {\n var code = '#';\n\n for (var i = 0; i < 6; i++) {\n code += digits.charAt(floor$2(random() * 16));\n }\n\n return new Color_1(code, 'hex');\n };\n\n var log$1 = Math.log;\n var pow$7 = Math.pow;\n var floor$3 = Math.floor;\n var abs = Math.abs;\n\n var analyze = function analyze(data, key) {\n if (key === void 0) key = null;\n var r = {\n min: Number.MAX_VALUE,\n max: Number.MAX_VALUE * -1,\n sum: 0,\n values: [],\n count: 0\n };\n\n if (type(data) === 'object') {\n data = Object.values(data);\n }\n\n data.forEach(function (val) {\n if (key && type(val) === 'object') {\n val = val[key];\n }\n\n if (val !== undefined && val !== null && !isNaN(val)) {\n r.values.push(val);\n r.sum += val;\n\n if (val < r.min) {\n r.min = val;\n }\n\n if (val > r.max) {\n r.max = val;\n }\n\n r.count += 1;\n }\n });\n r.domain = [r.min, r.max];\n\n r.limits = function (mode, num) {\n return limits(r, mode, num);\n };\n\n return r;\n };\n\n var limits = function limits(data, mode, num) {\n if (mode === void 0) mode = 'equal';\n if (num === void 0) num = 7;\n\n if (type(data) == 'array') {\n data = analyze(data);\n }\n\n var min = data.min;\n var max = data.max;\n var values = data.values.sort(function (a, b) {\n return a - b;\n });\n\n if (num === 1) {\n return [min, max];\n }\n\n var limits = [];\n\n if (mode.substr(0, 1) === 'c') {\n // continuous\n limits.push(min);\n limits.push(max);\n }\n\n if (mode.substr(0, 1) === 'e') {\n // equal interval\n limits.push(min);\n\n for (var i = 1; i < num; i++) {\n limits.push(min + i / num * (max - min));\n }\n\n limits.push(max);\n } else if (mode.substr(0, 1) === 'l') {\n // log scale\n if (min <= 0) {\n throw new Error('Logarithmic scales are only possible for values > 0');\n }\n\n var min_log = Math.LOG10E * log$1(min);\n var max_log = Math.LOG10E * log$1(max);\n limits.push(min);\n\n for (var i$1 = 1; i$1 < num; i$1++) {\n limits.push(pow$7(10, min_log + i$1 / num * (max_log - min_log)));\n }\n\n limits.push(max);\n } else if (mode.substr(0, 1) === 'q') {\n // quantile scale\n limits.push(min);\n\n for (var i$2 = 1; i$2 < num; i$2++) {\n var p = (values.length - 1) * i$2 / num;\n var pb = floor$3(p);\n\n if (pb === p) {\n limits.push(values[pb]);\n } else {\n // p > pb\n var pr = p - pb;\n limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);\n }\n }\n\n limits.push(max);\n } else if (mode.substr(0, 1) === 'k') {\n // k-means clustering\n\n /*\n implementation based on\n http://code.google.com/p/figue/source/browse/trunk/figue.js#336\n simplified for 1-d input values\n */\n var cluster;\n var n = values.length;\n var assignments = new Array(n);\n var clusterSizes = new Array(num);\n var repeat = true;\n var nb_iters = 0;\n var centroids = null; // get seed values\n\n centroids = [];\n centroids.push(min);\n\n for (var i$3 = 1; i$3 < num; i$3++) {\n centroids.push(min + i$3 / num * (max - min));\n }\n\n centroids.push(max);\n\n while (repeat) {\n // assignment step\n for (var j = 0; j < num; j++) {\n clusterSizes[j] = 0;\n }\n\n for (var i$4 = 0; i$4 < n; i$4++) {\n var value = values[i$4];\n var mindist = Number.MAX_VALUE;\n var best = void 0;\n\n for (var j$1 = 0; j$1 < num; j$1++) {\n var dist = abs(centroids[j$1] - value);\n\n if (dist < mindist) {\n mindist = dist;\n best = j$1;\n }\n\n clusterSizes[best]++;\n assignments[i$4] = best;\n }\n } // update centroids step\n\n\n var newCentroids = new Array(num);\n\n for (var j$2 = 0; j$2 < num; j$2++) {\n newCentroids[j$2] = null;\n }\n\n for (var i$5 = 0; i$5 < n; i$5++) {\n cluster = assignments[i$5];\n\n if (newCentroids[cluster] === null) {\n newCentroids[cluster] = values[i$5];\n } else {\n newCentroids[cluster] += values[i$5];\n }\n }\n\n for (var j$3 = 0; j$3 < num; j$3++) {\n newCentroids[j$3] *= 1 / clusterSizes[j$3];\n } // check convergence\n\n\n repeat = false;\n\n for (var j$4 = 0; j$4 < num; j$4++) {\n if (newCentroids[j$4] !== centroids[j$4]) {\n repeat = true;\n break;\n }\n }\n\n centroids = newCentroids;\n nb_iters++;\n\n if (nb_iters > 200) {\n repeat = false;\n }\n } // finished k-means clustering\n // the next part is borrowed from gabrielflor.it\n\n\n var kClusters = {};\n\n for (var j$5 = 0; j$5 < num; j$5++) {\n kClusters[j$5] = [];\n }\n\n for (var i$6 = 0; i$6 < n; i$6++) {\n cluster = assignments[i$6];\n kClusters[cluster].push(values[i$6]);\n }\n\n var tmpKMeansBreaks = [];\n\n for (var j$6 = 0; j$6 < num; j$6++) {\n tmpKMeansBreaks.push(kClusters[j$6][0]);\n tmpKMeansBreaks.push(kClusters[j$6][kClusters[j$6].length - 1]);\n }\n\n tmpKMeansBreaks = tmpKMeansBreaks.sort(function (a, b) {\n return a - b;\n });\n limits.push(tmpKMeansBreaks[0]);\n\n for (var i$7 = 1; i$7 < tmpKMeansBreaks.length; i$7 += 2) {\n var v = tmpKMeansBreaks[i$7];\n\n if (!isNaN(v) && limits.indexOf(v) === -1) {\n limits.push(v);\n }\n }\n }\n\n return limits;\n };\n\n var analyze_1 = {\n analyze: analyze,\n limits: limits\n };\n\n var contrast = function contrast(a, b) {\n // WCAG contrast ratio\n // see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef\n a = new Color_1(a);\n b = new Color_1(b);\n var l1 = a.luminance();\n var l2 = b.luminance();\n return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);\n };\n\n var sqrt$4 = Math.sqrt;\n var atan2$2 = Math.atan2;\n var abs$1 = Math.abs;\n var cos$4 = Math.cos;\n var PI$2 = Math.PI;\n\n var deltaE = function deltaE(a, b, L, C) {\n if (L === void 0) L = 1;\n if (C === void 0) C = 1; // Delta E (CMC)\n // see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CMC.html\n\n a = new Color_1(a);\n b = new Color_1(b);\n var ref = Array.from(a.lab());\n var L1 = ref[0];\n var a1 = ref[1];\n var b1 = ref[2];\n var ref$1 = Array.from(b.lab());\n var L2 = ref$1[0];\n var a2 = ref$1[1];\n var b2 = ref$1[2];\n var c1 = sqrt$4(a1 * a1 + b1 * b1);\n var c2 = sqrt$4(a2 * a2 + b2 * b2);\n var sl = L1 < 16.0 ? 0.511 : 0.040975 * L1 / (1.0 + 0.01765 * L1);\n var sc = 0.0638 * c1 / (1.0 + 0.0131 * c1) + 0.638;\n var h1 = c1 < 0.000001 ? 0.0 : atan2$2(b1, a1) * 180.0 / PI$2;\n\n while (h1 < 0) {\n h1 += 360;\n }\n\n while (h1 >= 360) {\n h1 -= 360;\n }\n\n var t = h1 >= 164.0 && h1 <= 345.0 ? 0.56 + abs$1(0.2 * cos$4(PI$2 * (h1 + 168.0) / 180.0)) : 0.36 + abs$1(0.4 * cos$4(PI$2 * (h1 + 35.0) / 180.0));\n var c4 = c1 * c1 * c1 * c1;\n var f = sqrt$4(c4 / (c4 + 1900.0));\n var sh = sc * (f * t + 1.0 - f);\n var delL = L1 - L2;\n var delC = c1 - c2;\n var delA = a1 - a2;\n var delB = b1 - b2;\n var dH2 = delA * delA + delB * delB - delC * delC;\n var v1 = delL / (L * sl);\n var v2 = delC / (C * sc);\n var v3 = sh;\n return sqrt$4(v1 * v1 + v2 * v2 + dH2 / (v3 * v3));\n }; // simple Euclidean distance\n\n\n var distance = function distance(a, b, mode) {\n if (mode === void 0) mode = 'lab'; // Delta E (CIE 1976)\n // see http://www.brucelindbloom.com/index.html?Equations.html\n\n a = new Color_1(a);\n b = new Color_1(b);\n var l1 = a.get(mode);\n var l2 = b.get(mode);\n var sum_sq = 0;\n\n for (var i in l1) {\n var d = (l1[i] || 0) - (l2[i] || 0);\n sum_sq += d * d;\n }\n\n return Math.sqrt(sum_sq);\n };\n\n var valid = function valid() {\n var args = [],\n len = arguments.length;\n\n while (len--) {\n args[len] = arguments[len];\n }\n\n try {\n new (Function.prototype.bind.apply(Color_1, [null].concat(args)))();\n return true;\n } catch (e) {\n return false;\n }\n }; // some pre-defined color scales:\n\n\n var scales = {\n cool: function cool() {\n return scale([chroma_1.hsl(180, 1, .9), chroma_1.hsl(250, .7, .4)]);\n },\n hot: function hot() {\n return scale(['#000', '#f00', '#ff0', '#fff'], [0, .25, .75, 1]).mode('rgb');\n }\n };\n /**\n ColorBrewer colors for chroma.js\n Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The\n Pennsylvania State University.\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n http://www.apache.org/licenses/LICENSE-2.0\n Unless required by applicable law or agreed to in writing, software distributed\n under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n CONDITIONS OF ANY KIND, either express or implied. See the License for the\n specific language governing permissions and limitations under the License.\n */\n\n var colorbrewer = {\n // sequential\n OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],\n PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'],\n BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'],\n Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'],\n BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'],\n YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'],\n YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'],\n Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'],\n RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'],\n Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'],\n YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],\n Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'],\n GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'],\n Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'],\n YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],\n PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'],\n Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'],\n PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'],\n Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'],\n // diverging\n Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],\n RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'],\n RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'],\n PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'],\n PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'],\n RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'],\n BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'],\n RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'],\n PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'],\n // qualitative\n Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'],\n Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'],\n Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'],\n Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],\n Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'],\n Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'],\n Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'],\n Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2']\n }; // add lowercase aliases for case-insensitive matches\n\n for (var i$1 = 0, list$1 = Object.keys(colorbrewer); i$1 < list$1.length; i$1 += 1) {\n var key = list$1[i$1];\n colorbrewer[key.toLowerCase()] = colorbrewer[key];\n }\n\n var colorbrewer_1 = colorbrewer; // feel free to comment out anything to rollup\n // a smaller chroma.js built\n // io --\x3e convert colors\n // operators --\x3e modify existing Colors\n // interpolators\n // generators -- > create new colors\n\n chroma_1.average = average;\n chroma_1.bezier = bezier_1;\n chroma_1.blend = blend_1;\n chroma_1.cubehelix = cubehelix;\n chroma_1.mix = chroma_1.interpolate = mix;\n chroma_1.random = random_1;\n chroma_1.scale = scale; // other utility methods\n\n chroma_1.analyze = analyze_1.analyze;\n chroma_1.contrast = contrast;\n chroma_1.deltaE = deltaE;\n chroma_1.distance = distance;\n chroma_1.limits = analyze_1.limits;\n chroma_1.valid = valid; // scale\n\n chroma_1.scales = scales; // colors\n\n chroma_1.colors = w3cx11_1;\n chroma_1.brewer = colorbrewer_1;\n var chroma_js = chroma_1;\n return chroma_js;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jaHJvbWEtanMvY2hyb21hLmpzP2JmNDQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUVBQW1FO0FBQ25FLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUUsS0FBNEQsZ0NBQWdDLENBQXdGO0FBQ3RMLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsUUFBUTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJOzs7QUFHSjs7QUFFQSxxSEFBcUgsaUJBQWlCO0FBQ3RJO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2Q0FBNkM7O0FBRTdDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7OztBQUdBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLE9BQU87OztBQUdQLDhDQUE4QyxpQkFBaUI7QUFDL0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7OztBQUdMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFFBQVE7QUFDeEI7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsUUFBUTtBQUN4Qjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUJBQXFCLE9BQU87QUFDNUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTyxZQUFZO0FBQ25CO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTs7QUFFQSxxQkFBcUIsT0FBTztBQUM1QjtBQUNBOztBQUVBLGlCQUFpQjs7QUFFakI7QUFDQSxLQUFLOzs7QUFHTDtBQUNBOztBQUVBLHVCQUF1QixTQUFTO0FBQ2hDO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOzs7QUFHTDtBQUNBOztBQUVBLHVCQUF1QixTQUFTO0FBQ2hDO0FBQ0E7O0FBRUEsbUJBQW1COztBQUVuQjtBQUNBLEtBQUs7OztBQUdMO0FBQ0E7O0FBRUEsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOzs7QUFHTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCOztBQUV2QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7O0FBRXhDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyxFQUFFLGFBQWEsRUFBRTtBQUNqRCxpQ0FBaUMsRUFBRSxhQUFhLEVBQUU7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOzs7QUFHUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPOzs7QUFHUDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixNQUFNO0FBQ3RCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlEQUFpRCxpQkFBaUI7QUFDbEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7O0FBR1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOzs7QUFHSjs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FB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OztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQzs7QUFFbkMsc0JBQXNCO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUIsT0FBTztBQUMxQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxQkFBcUIsU0FBUztBQUM5QjtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUIsV0FBVztBQUNsQztBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUEsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjs7QUFFM0I7QUFDQTs7QUFFQSx1QkFBdUIsV0FBVztBQUNsQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSx1QkFBdUIsU0FBUztBQUNoQztBQUNBOztBQUVBLHlCQUF5QixTQUFTO0FBQ2xDO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkIsV0FBVztBQUN0Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOzs7QUFHVDs7QUFFQSx5QkFBeUIsV0FBVztBQUNwQztBQUNBOztBQUVBLHlCQUF5QixTQUFTO0FBQ2xDOztBQUVBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBLHlCQUF5QixXQUFXO0FBQ3BDO0FBQ0EsU0FBUzs7O0FBR1Q7O0FBRUEseUJBQXlCLFdBQVc7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7O0FBR0E7O0FBRUEsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTs7QUFFQSx1QkFBdUIsU0FBUztBQUNoQztBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsdUJBQXVCLFdBQVc7QUFDbEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7O0FBRUEsdUJBQXVCLDhCQUE4QjtBQUNyRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRCQUE0QjtBQUM1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7OztBQUdKO0FBQ0Esc0NBQXNDO0FBQ3RDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSTs7O0FBR0o7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKLHNEQUFzRCxxQkFBcUI7QUFDM0U7QUFDQTtBQUNBOztBQUVBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qjs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qjs7QUFFekIsMkJBQTJCOztBQUUzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMiLCJmaWxlIjoiMzg3My5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogY2hyb21hLmpzIC0gSmF2YVNjcmlwdCBsaWJyYXJ5IGZvciBjb2xvciBjb252ZXJzaW9uc1xuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMS0yMDE5LCBHcmVnb3IgQWlzY2hcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0XG4gKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcbiAqXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiAqIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICpcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAqIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICpcbiAqIDMuIFRoZSBuYW1lIEdyZWdvciBBaXNjaCBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzXG4gKiBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIlxuICogQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuICogSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBHUkVHT1IgQUlTQ0ggT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCxcbiAqIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLFxuICogQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSxcbiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUllcbiAqIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HXG4gKiBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsXG4gKiBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICpcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqXG4gKiBjaHJvbWEuanMgaW5jbHVkZXMgY29sb3JzIGZyb20gY29sb3JicmV3ZXIyLm9yZywgd2hpY2ggYXJlIHJlbGVhc2VkIHVuZGVyXG4gKiB0aGUgZm9sbG93aW5nIGxpY2Vuc2U6XG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDAyIEN5bnRoaWEgQnJld2VyLCBNYXJrIEhhcnJvd2VyLFxuICogYW5kIFRoZSBQZW5uc3lsdmFuaWEgU3RhdGUgVW5pdmVyc2l0eS5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhblxuICogXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCxcbiAqIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljXG4gKiBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICpcbiAqIE5hbWVkIGNvbG9ycyBhcmUgdGFrZW4gZnJvbSBYMTEgQ29sb3IgTmFtZXMuXG4gKiBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLWNvbG9yLyNzdmctY29sb3JcbiAqXG4gKiBAcHJlc2VydmVcbiAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgOiB0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQgPyBkZWZpbmUoZmFjdG9yeSkgOiBnbG9iYWwuY2hyb21hID0gZmFjdG9yeSgpO1xufSkodGhpcywgZnVuY3Rpb24gKCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgdmFyIGxpbWl0ID0gZnVuY3Rpb24gbGltaXQoeCwgbWluLCBtYXgpIHtcbiAgICBpZiAobWluID09PSB2b2lkIDApIG1pbiA9IDA7XG4gICAgaWYgKG1heCA9PT0gdm9pZCAwKSBtYXggPSAxO1xuICAgIHJldHVybiB4IDwgbWluID8gbWluIDogeCA+IG1heCA/IG1heCA6IHg7XG4gIH07XG5cbiAgdmFyIGNsaXBfcmdiID0gZnVuY3Rpb24gY2xpcF9yZ2IocmdiKSB7XG4gICAgcmdiLl9jbGlwcGVkID0gZmFsc2U7XG4gICAgcmdiLl91bmNsaXBwZWQgPSByZ2Iuc2xpY2UoMCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSAzOyBpKyspIHtcbiAgICAgIGlmIChpIDwgMykge1xuICAgICAgICBpZiAocmdiW2ldIDwgMCB8fCByZ2JbaV0gPiAyNTUpIHtcbiAgICAgICAgICByZ2IuX2NsaXBwZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmdiW2ldID0gbGltaXQocmdiW2ldLCAwLCAyNTUpO1xuICAgICAgfSBlbHNlIGlmIChpID09PSAzKSB7XG4gICAgICAgIHJnYltpXSA9IGxpbWl0KHJnYltpXSwgMCwgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJnYjtcbiAgfTsgLy8gcG9ydGVkIGZyb20galF1ZXJ5J3MgJC50eXBlXG5cblxuICB2YXIgY2xhc3NUb1R5cGUgPSB7fTtcblxuICBmb3IgKHZhciBpID0gMCwgbGlzdCA9IFsnQm9vbGVhbicsICdOdW1iZXInLCAnU3RyaW5nJywgJ0Z1bmN0aW9uJywgJ0FycmF5JywgJ0RhdGUnLCAnUmVnRXhwJywgJ1VuZGVmaW5lZCcsICdOdWxsJ107IGkgPCBsaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgdmFyIG5hbWUgPSBsaXN0W2ldO1xuICAgIGNsYXNzVG9UeXBlW1wiW29iamVjdCBcIiArIG5hbWUgKyBcIl1cIl0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICB2YXIgdHlwZSA9IGZ1bmN0aW9uIHR5cGUob2JqKSB7XG4gICAgcmV0dXJuIGNsYXNzVG9UeXBlW09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopXSB8fCBcIm9iamVjdFwiO1xuICB9O1xuXG4gIHZhciB1bnBhY2sgPSBmdW5jdGlvbiB1bnBhY2soYXJncywga2V5T3JkZXIpIHtcbiAgICBpZiAoa2V5T3JkZXIgPT09IHZvaWQgMCkga2V5T3JkZXIgPSBudWxsOyAvLyBpZiBjYWxsZWQgd2l0aCBtb3JlIHRoYW4gMyBhcmd1bWVudHMsIHdlIHJldHVybiB0aGUgYXJndW1lbnRzXG5cbiAgICBpZiAoYXJncy5sZW5ndGggPj0gMykge1xuICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpO1xuICAgIH0gLy8gd2l0aCBsZXNzIHRoYW4gMyBhcmdzIHdlIGNoZWNrIGlmIGZpcnN0IGFyZyBpcyBvYmplY3RcbiAgICAvLyBhbmQgdXNlIHRoZSBrZXlPcmRlciBzdHJpbmcgdG8gZXh0cmFjdCBhbmQgc29ydCBwcm9wZXJ0aWVzXG5cblxuICAgIGlmICh0eXBlKGFyZ3NbMF0pID09ICdvYmplY3QnICYmIGtleU9yZGVyKSB7XG4gICAgICByZXR1cm4ga2V5T3JkZXIuc3BsaXQoJycpLmZpbHRlcihmdW5jdGlvbiAoaykge1xuICAgICAgICByZXR1cm4gYXJnc1swXVtrXSAhPT0gdW5kZWZpbmVkO1xuICAgICAgfSkubWFwKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgIHJldHVybiBhcmdzWzBdW2tdO1xuICAgICAgfSk7XG4gICAgfSAvLyBvdGhlcndpc2Ugd2UganVzdCByZXR1cm4gdGhlIGZpcnN0IGFyZ3VtZW50XG4gICAgLy8gKHdoaWNoIHdlIHN1cHBvc2UgaXMgYW4gYXJyYXkgb2YgYXJncylcblxuXG4gICAgcmV0dXJuIGFyZ3NbMF07XG4gIH07XG5cbiAgdmFyIGxhc3QgPSBmdW5jdGlvbiBsYXN0KGFyZ3MpIHtcbiAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgbCA9IGFyZ3MubGVuZ3RoIC0gMTtcblxuICAgIGlmICh0eXBlKGFyZ3NbbF0pID09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYXJnc1tsXS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHZhciBQSSA9IE1hdGguUEk7XG4gIHZhciB1dGlscyA9IHtcbiAgICBjbGlwX3JnYjogY2xpcF9yZ2IsXG4gICAgbGltaXQ6IGxpbWl0LFxuICAgIHR5cGU6IHR5cGUsXG4gICAgdW5wYWNrOiB1bnBhY2ssXG4gICAgbGFzdDogbGFzdCxcbiAgICBQSTogUEksXG4gICAgVFdPUEk6IFBJICogMixcbiAgICBQSVRISVJEOiBQSSAvIDMsXG4gICAgREVHMlJBRDogUEkgLyAxODAsXG4gICAgUkFEMkRFRzogMTgwIC8gUElcbiAgfTtcbiAgdmFyIGlucHV0ID0ge1xuICAgIGZvcm1hdDoge30sXG4gICAgYXV0b2RldGVjdDogW11cbiAgfTtcbiAgdmFyIGxhc3QkMSA9IHV0aWxzLmxhc3Q7XG4gIHZhciBjbGlwX3JnYiQxID0gdXRpbHMuY2xpcF9yZ2I7XG4gIHZhciB0eXBlJDEgPSB1dGlscy50eXBlO1xuXG4gIHZhciBDb2xvciA9IGZ1bmN0aW9uIENvbG9yKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHZhciBtZSA9IHRoaXM7XG5cbiAgICBpZiAodHlwZSQxKGFyZ3NbMF0pID09PSAnb2JqZWN0JyAmJiBhcmdzWzBdLmNvbnN0cnVjdG9yICYmIGFyZ3NbMF0uY29uc3RydWN0b3IgPT09IHRoaXMuY29uc3RydWN0b3IpIHtcbiAgICAgIC8vIHRoZSBhcmd1bWVudCBpcyBhbHJlYWR5IGEgQ29sb3IgaW5zdGFuY2VcbiAgICAgIHJldHVybiBhcmdzWzBdO1xuICAgIH0gLy8gbGFzdCBhcmd1bWVudCBjb3VsZCBiZSB0aGUgbW9kZVxuXG5cbiAgICB2YXIgbW9kZSA9IGxhc3QkMShhcmdzKTtcbiAgICB2YXIgYXV0b2RldGVjdCA9IGZhbHNlO1xuXG4gICAgaWYgKCFtb2RlKSB7XG4gICAgICBhdXRvZGV0ZWN0ID0gdHJ1ZTtcblxuICAgICAgaWYgKCFpbnB1dC5zb3J0ZWQpIHtcbiAgICAgICAgaW5wdXQuYXV0b2RldGVjdCA9IGlucHV0LmF1dG9kZXRlY3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgIHJldHVybiBiLnAgLSBhLnA7XG4gICAgICAgIH0pO1xuICAgICAgICBpbnB1dC5zb3J0ZWQgPSB0cnVlO1xuICAgICAgfSAvLyBhdXRvLWRldGVjdCBmb3JtYXRcblxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGlzdCA9IGlucHV0LmF1dG9kZXRlY3Q7IGkgPCBsaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHZhciBjaGsgPSBsaXN0W2ldO1xuICAgICAgICBtb2RlID0gY2hrLnRlc3QuYXBwbHkoY2hrLCBhcmdzKTtcblxuICAgICAgICBpZiAobW9kZSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlucHV0LmZvcm1hdFttb2RlXSkge1xuICAgICAgdmFyIHJnYiA9IGlucHV0LmZvcm1hdFttb2RlXS5hcHBseShudWxsLCBhdXRvZGV0ZWN0ID8gYXJncyA6IGFyZ3Muc2xpY2UoMCwgLTEpKTtcbiAgICAgIG1lLl9yZ2IgPSBjbGlwX3JnYiQxKHJnYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBmb3JtYXQ6ICcgKyBhcmdzKTtcbiAgICB9IC8vIGFkZCBhbHBoYSBjaGFubmVsXG5cblxuICAgIGlmIChtZS5fcmdiLmxlbmd0aCA9PT0gMykge1xuICAgICAgbWUuX3JnYi5wdXNoKDEpO1xuICAgIH1cbiAgfTtcblxuICBDb2xvci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICBpZiAodHlwZSQxKHRoaXMuaGV4KSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5oZXgoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gXCJbXCIgKyB0aGlzLl9yZ2Iuam9pbignLCcpICsgXCJdXCI7XG4gIH07XG5cbiAgdmFyIENvbG9yXzEgPSBDb2xvcjtcblxuICB2YXIgY2hyb21hID0gZnVuY3Rpb24gY2hyb21hKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KGNocm9tYS5Db2xvciwgW251bGxdLmNvbmNhdChhcmdzKSkpKCk7XG4gIH07XG5cbiAgY2hyb21hLkNvbG9yID0gQ29sb3JfMTtcbiAgY2hyb21hLnZlcnNpb24gPSAnMi4xLjInO1xuICB2YXIgY2hyb21hXzEgPSBjaHJvbWE7XG4gIHZhciB1bnBhY2skMSA9IHV0aWxzLnVucGFjaztcbiAgdmFyIG1heCA9IE1hdGgubWF4O1xuXG4gIHZhciByZ2IyY215ayA9IGZ1bmN0aW9uIHJnYjJjbXlrKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHZhciByZWYgPSB1bnBhY2skMShhcmdzLCAncmdiJyk7XG4gICAgdmFyIHIgPSByZWZbMF07XG4gICAgdmFyIGcgPSByZWZbMV07XG4gICAgdmFyIGIgPSByZWZbMl07XG4gICAgciA9IHIgLyAyNTU7XG4gICAgZyA9IGcgLyAyNTU7XG4gICAgYiA9IGIgLyAyNTU7XG4gICAgdmFyIGsgPSAxIC0gbWF4KHIsIG1heChnLCBiKSk7XG4gICAgdmFyIGYgPSBrIDwgMSA/IDEgLyAoMSAtIGspIDogMDtcbiAgICB2YXIgYyA9ICgxIC0gciAtIGspICogZjtcbiAgICB2YXIgbSA9ICgxIC0gZyAtIGspICogZjtcbiAgICB2YXIgeSA9ICgxIC0gYiAtIGspICogZjtcbiAgICByZXR1cm4gW2MsIG0sIHksIGtdO1xuICB9O1xuXG4gIHZhciByZ2IyY215a18xID0gcmdiMmNteWs7XG4gIHZhciB1bnBhY2skMiA9IHV0aWxzLnVucGFjaztcblxuICB2YXIgY215azJyZ2IgPSBmdW5jdGlvbiBjbXlrMnJnYigpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICBhcmdzID0gdW5wYWNrJDIoYXJncywgJ2NteWsnKTtcbiAgICB2YXIgYyA9IGFyZ3NbMF07XG4gICAgdmFyIG0gPSBhcmdzWzFdO1xuICAgIHZhciB5ID0gYXJnc1syXTtcbiAgICB2YXIgayA9IGFyZ3NbM107XG4gICAgdmFyIGFscGhhID0gYXJncy5sZW5ndGggPiA0ID8gYXJnc1s0XSA6IDE7XG5cbiAgICBpZiAoayA9PT0gMSkge1xuICAgICAgcmV0dXJuIFswLCAwLCAwLCBhbHBoYV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFtjID49IDEgPyAwIDogMjU1ICogKDEgLSBjKSAqICgxIC0gayksIC8vIHJcbiAgICBtID49IDEgPyAwIDogMjU1ICogKDEgLSBtKSAqICgxIC0gayksIC8vIGdcbiAgICB5ID49IDEgPyAwIDogMjU1ICogKDEgLSB5KSAqICgxIC0gayksIC8vIGJcbiAgICBhbHBoYV07XG4gIH07XG5cbiAgdmFyIGNteWsycmdiXzEgPSBjbXlrMnJnYjtcbiAgdmFyIHVucGFjayQzID0gdXRpbHMudW5wYWNrO1xuICB2YXIgdHlwZSQyID0gdXRpbHMudHlwZTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5jbXlrID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZ2IyY215a18xKHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEuY215ayA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShDb2xvcl8xLCBbbnVsbF0uY29uY2F0KGFyZ3MsIFsnY215ayddKSkpKCk7XG4gIH07XG5cbiAgaW5wdXQuZm9ybWF0LmNteWsgPSBjbXlrMnJnYl8xO1xuICBpbnB1dC5hdXRvZGV0ZWN0LnB1c2goe1xuICAgIHA6IDIsXG4gICAgdGVzdDogZnVuY3Rpb24gdGVzdCgpIHtcbiAgICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgICAgfVxuXG4gICAgICBhcmdzID0gdW5wYWNrJDMoYXJncywgJ2NteWsnKTtcblxuICAgICAgaWYgKHR5cGUkMihhcmdzKSA9PT0gJ2FycmF5JyAmJiBhcmdzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICByZXR1cm4gJ2NteWsnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skNCA9IHV0aWxzLnVucGFjaztcbiAgdmFyIGxhc3QkMiA9IHV0aWxzLmxhc3Q7XG5cbiAgdmFyIHJuZCA9IGZ1bmN0aW9uIHJuZChhKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoYSAqIDEwMCkgLyAxMDA7XG4gIH07XG4gIC8qXG4gICAqIHN1cHBvcnRlZCBhcmd1bWVudHM6XG4gICAqIC0gaHNsMmNzcyhoLHMsbClcbiAgICogLSBoc2wyY3NzKGgscyxsLGEpXG4gICAqIC0gaHNsMmNzcyhbaCxzLGxdLCBtb2RlKVxuICAgKiAtIGhzbDJjc3MoW2gscyxsLGFdLCBtb2RlKVxuICAgKiAtIGhzbDJjc3Moe2gscyxsLGF9LCBtb2RlKVxuICAgKi9cblxuXG4gIHZhciBoc2wyY3NzID0gZnVuY3Rpb24gaHNsMmNzcygpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICB2YXIgaHNsYSA9IHVucGFjayQ0KGFyZ3MsICdoc2xhJyk7XG4gICAgdmFyIG1vZGUgPSBsYXN0JDIoYXJncykgfHwgJ2xzYSc7XG4gICAgaHNsYVswXSA9IHJuZChoc2xhWzBdIHx8IDApO1xuICAgIGhzbGFbMV0gPSBybmQoaHNsYVsxXSAqIDEwMCkgKyAnJSc7XG4gICAgaHNsYVsyXSA9IHJuZChoc2xhWzJdICogMTAwKSArICclJztcblxuICAgIGlmIChtb2RlID09PSAnaHNsYScgfHwgaHNsYS5sZW5ndGggPiAzICYmIGhzbGFbM10gPCAxKSB7XG4gICAgICBoc2xhWzNdID0gaHNsYS5sZW5ndGggPiAzID8gaHNsYVszXSA6IDE7XG4gICAgICBtb2RlID0gJ2hzbGEnO1xuICAgIH0gZWxzZSB7XG4gICAgICBoc2xhLmxlbmd0aCA9IDM7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vZGUgKyBcIihcIiArIGhzbGEuam9pbignLCcpICsgXCIpXCI7XG4gIH07XG5cbiAgdmFyIGhzbDJjc3NfMSA9IGhzbDJjc3M7XG4gIHZhciB1bnBhY2skNSA9IHV0aWxzLnVucGFjaztcbiAgLypcbiAgICogc3VwcG9ydGVkIGFyZ3VtZW50czpcbiAgICogLSByZ2IyaHNsKHIsZyxiKVxuICAgKiAtIHJnYjJoc2wocixnLGIsYSlcbiAgICogLSByZ2IyaHNsKFtyLGcsYl0pXG4gICAqIC0gcmdiMmhzbChbcixnLGIsYV0pXG4gICAqIC0gcmdiMmhzbCh7cixnLGIsYX0pXG4gICAqL1xuXG4gIHZhciByZ2IyaHNsID0gZnVuY3Rpb24gcmdiMmhzbCgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICBhcmdzID0gdW5wYWNrJDUoYXJncywgJ3JnYmEnKTtcbiAgICB2YXIgciA9IGFyZ3NbMF07XG4gICAgdmFyIGcgPSBhcmdzWzFdO1xuICAgIHZhciBiID0gYXJnc1syXTtcbiAgICByIC89IDI1NTtcbiAgICBnIC89IDI1NTtcbiAgICBiIC89IDI1NTtcbiAgICB2YXIgbWluID0gTWF0aC5taW4ociwgZywgYik7XG4gICAgdmFyIG1heCA9IE1hdGgubWF4KHIsIGcsIGIpO1xuICAgIHZhciBsID0gKG1heCArIG1pbikgLyAyO1xuICAgIHZhciBzLCBoO1xuXG4gICAgaWYgKG1heCA9PT0gbWluKSB7XG4gICAgICBzID0gMDtcbiAgICAgIGggPSBOdW1iZXIuTmFOO1xuICAgIH0gZWxzZSB7XG4gICAgICBzID0gbCA8IDAuNSA/IChtYXggLSBtaW4pIC8gKG1heCArIG1pbikgOiAobWF4IC0gbWluKSAvICgyIC0gbWF4IC0gbWluKTtcbiAgICB9XG5cbiAgICBpZiAociA9PSBtYXgpIHtcbiAgICAgIGggPSAoZyAtIGIpIC8gKG1heCAtIG1pbik7XG4gICAgfSBlbHNlIGlmIChnID09IG1heCkge1xuICAgICAgaCA9IDIgKyAoYiAtIHIpIC8gKG1heCAtIG1pbik7XG4gICAgfSBlbHNlIGlmIChiID09IG1heCkge1xuICAgICAgaCA9IDQgKyAociAtIGcpIC8gKG1heCAtIG1pbik7XG4gICAgfVxuXG4gICAgaCAqPSA2MDtcblxuICAgIGlmIChoIDwgMCkge1xuICAgICAgaCArPSAzNjA7XG4gICAgfVxuXG4gICAgaWYgKGFyZ3MubGVuZ3RoID4gMyAmJiBhcmdzWzNdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbaCwgcywgbCwgYXJnc1szXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFtoLCBzLCBsXTtcbiAgfTtcblxuICB2YXIgcmdiMmhzbF8xID0gcmdiMmhzbDtcbiAgdmFyIHVucGFjayQ2ID0gdXRpbHMudW5wYWNrO1xuICB2YXIgbGFzdCQzID0gdXRpbHMubGFzdDtcbiAgdmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcbiAgLypcbiAgICogc3VwcG9ydGVkIGFyZ3VtZW50czpcbiAgICogLSByZ2IyY3NzKHIsZyxiKVxuICAgKiAtIHJnYjJjc3MocixnLGIsYSlcbiAgICogLSByZ2IyY3NzKFtyLGcsYl0sIG1vZGUpXG4gICAqIC0gcmdiMmNzcyhbcixnLGIsYV0sIG1vZGUpXG4gICAqIC0gcmdiMmNzcyh7cixnLGIsYX0sIG1vZGUpXG4gICAqL1xuXG4gIHZhciByZ2IyY3NzID0gZnVuY3Rpb24gcmdiMmNzcygpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICB2YXIgcmdiYSA9IHVucGFjayQ2KGFyZ3MsICdyZ2JhJyk7XG4gICAgdmFyIG1vZGUgPSBsYXN0JDMoYXJncykgfHwgJ3JnYic7XG5cbiAgICBpZiAobW9kZS5zdWJzdHIoMCwgMykgPT0gJ2hzbCcpIHtcbiAgICAgIHJldHVybiBoc2wyY3NzXzEocmdiMmhzbF8xKHJnYmEpLCBtb2RlKTtcbiAgICB9XG5cbiAgICByZ2JhWzBdID0gcm91bmQocmdiYVswXSk7XG4gICAgcmdiYVsxXSA9IHJvdW5kKHJnYmFbMV0pO1xuICAgIHJnYmFbMl0gPSByb3VuZChyZ2JhWzJdKTtcblxuICAgIGlmIChtb2RlID09PSAncmdiYScgfHwgcmdiYS5sZW5ndGggPiAzICYmIHJnYmFbM10gPCAxKSB7XG4gICAgICByZ2JhWzNdID0gcmdiYS5sZW5ndGggPiAzID8gcmdiYVszXSA6IDE7XG4gICAgICBtb2RlID0gJ3JnYmEnO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlICsgXCIoXCIgKyByZ2JhLnNsaWNlKDAsIG1vZGUgPT09ICdyZ2InID8gMyA6IDQpLmpvaW4oJywnKSArIFwiKVwiO1xuICB9O1xuXG4gIHZhciByZ2IyY3NzXzEgPSByZ2IyY3NzO1xuICB2YXIgdW5wYWNrJDcgPSB1dGlscy51bnBhY2s7XG4gIHZhciByb3VuZCQxID0gTWF0aC5yb3VuZDtcblxuICB2YXIgaHNsMnJnYiA9IGZ1bmN0aW9uIGhzbDJyZ2IoKSB7XG4gICAgdmFyIGFzc2lnbjtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICBhcmdzID0gdW5wYWNrJDcoYXJncywgJ2hzbCcpO1xuICAgIHZhciBoID0gYXJnc1swXTtcbiAgICB2YXIgcyA9IGFyZ3NbMV07XG4gICAgdmFyIGwgPSBhcmdzWzJdO1xuICAgIHZhciByLCBnLCBiO1xuXG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIHIgPSBnID0gYiA9IGwgKiAyNTU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB0MyA9IFswLCAwLCAwXTtcbiAgICAgIHZhciBjID0gWzAsIDAsIDBdO1xuICAgICAgdmFyIHQyID0gbCA8IDAuNSA/IGwgKiAoMSArIHMpIDogbCArIHMgLSBsICogcztcbiAgICAgIHZhciB0MSA9IDIgKiBsIC0gdDI7XG4gICAgICB2YXIgaF8gPSBoIC8gMzYwO1xuICAgICAgdDNbMF0gPSBoXyArIDEgLyAzO1xuICAgICAgdDNbMV0gPSBoXztcbiAgICAgIHQzWzJdID0gaF8gLSAxIC8gMztcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcbiAgICAgICAgaWYgKHQzW2ldIDwgMCkge1xuICAgICAgICAgIHQzW2ldICs9IDE7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodDNbaV0gPiAxKSB7XG4gICAgICAgICAgdDNbaV0gLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICg2ICogdDNbaV0gPCAxKSB7XG4gICAgICAgICAgY1tpXSA9IHQxICsgKHQyIC0gdDEpICogNiAqIHQzW2ldO1xuICAgICAgICB9IGVsc2UgaWYgKDIgKiB0M1tpXSA8IDEpIHtcbiAgICAgICAgICBjW2ldID0gdDI7XG4gICAgICAgIH0gZWxzZSBpZiAoMyAqIHQzW2ldIDwgMikge1xuICAgICAgICAgIGNbaV0gPSB0MSArICh0MiAtIHQxKSAqICgyIC8gMyAtIHQzW2ldKSAqIDY7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY1tpXSA9IHQxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGFzc2lnbiA9IFtyb3VuZCQxKGNbMF0gKiAyNTUpLCByb3VuZCQxKGNbMV0gKiAyNTUpLCByb3VuZCQxKGNbMl0gKiAyNTUpXSwgciA9IGFzc2lnblswXSwgZyA9IGFzc2lnblsxXSwgYiA9IGFzc2lnblsyXTtcbiAgICB9XG5cbiAgICBpZiAoYXJncy5sZW5ndGggPiAzKSB7XG4gICAgICAvLyBrZWVwIGFscGhhIGNoYW5uZWxcbiAgICAgIHJldHVybiBbciwgZywgYiwgYXJnc1szXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIFtyLCBnLCBiLCAxXTtcbiAgfTtcblxuICB2YXIgaHNsMnJnYl8xID0gaHNsMnJnYjtcbiAgdmFyIFJFX1JHQiA9IC9ecmdiXFwoXFxzKigtP1xcZCspLFxccyooLT9cXGQrKVxccyosXFxzKigtP1xcZCspXFxzKlxcKSQvO1xuICB2YXIgUkVfUkdCQSA9IC9ecmdiYVxcKFxccyooLT9cXGQrKSxcXHMqKC0/XFxkKylcXHMqLFxccyooLT9cXGQrKVxccyosXFxzKihbMDFdfFswMV0/XFwuXFxkKylcXCkkLztcbiAgdmFyIFJFX1JHQl9QQ1QgPSAvXnJnYlxcKFxccyooLT9cXGQrKD86XFwuXFxkKyk/KSUsXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccyosXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccypcXCkkLztcbiAgdmFyIFJFX1JHQkFfUENUID0gL15yZ2JhXFwoXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJSxcXHMqKC0/XFxkKyg/OlxcLlxcZCspPyklXFxzKixcXHMqKC0/XFxkKyg/OlxcLlxcZCspPyklXFxzKixcXHMqKFswMV18WzAxXT9cXC5cXGQrKVxcKSQvO1xuICB2YXIgUkVfSFNMID0gL15oc2xcXChcXHMqKC0/XFxkKyg/OlxcLlxcZCspPyksXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccyosXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccypcXCkkLztcbiAgdmFyIFJFX0hTTEEgPSAvXmhzbGFcXChcXHMqKC0/XFxkKyg/OlxcLlxcZCspPyksXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccyosXFxzKigtP1xcZCsoPzpcXC5cXGQrKT8pJVxccyosXFxzKihbMDFdfFswMV0/XFwuXFxkKylcXCkkLztcbiAgdmFyIHJvdW5kJDIgPSBNYXRoLnJvdW5kO1xuXG4gIHZhciBjc3MycmdiID0gZnVuY3Rpb24gY3NzMnJnYihjc3MpIHtcbiAgICBjc3MgPSBjc3MudG9Mb3dlckNhc2UoKS50cmltKCk7XG4gICAgdmFyIG07XG5cbiAgICBpZiAoaW5wdXQuZm9ybWF0Lm5hbWVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gaW5wdXQuZm9ybWF0Lm5hbWVkKGNzcyk7XG4gICAgICB9IGNhdGNoIChlKSB7Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICB9XG4gICAgfSAvLyByZ2IoMjUwLDIwLDApXG5cblxuICAgIGlmIChtID0gY3NzLm1hdGNoKFJFX1JHQikpIHtcbiAgICAgIHZhciByZ2IgPSBtLnNsaWNlKDEsIDQpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICByZ2JbaV0gPSArcmdiW2ldO1xuICAgICAgfVxuXG4gICAgICByZ2JbM10gPSAxOyAvLyBkZWZhdWx0IGFscGhhXG5cbiAgICAgIHJldHVybiByZ2I7XG4gICAgfSAvLyByZ2JhKDI1MCwyMCwwLDAuNClcblxuXG4gICAgaWYgKG0gPSBjc3MubWF0Y2goUkVfUkdCQSkpIHtcbiAgICAgIHZhciByZ2IkMSA9IG0uc2xpY2UoMSwgNSk7XG5cbiAgICAgIGZvciAodmFyIGkkMSA9IDA7IGkkMSA8IDQ7IGkkMSsrKSB7XG4gICAgICAgIHJnYiQxW2kkMV0gPSArcmdiJDFbaSQxXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJnYiQxO1xuICAgIH0gLy8gcmdiKDEwMCUsMCUsMCUpXG5cblxuICAgIGlmIChtID0gY3NzLm1hdGNoKFJFX1JHQl9QQ1QpKSB7XG4gICAgICB2YXIgcmdiJDIgPSBtLnNsaWNlKDEsIDQpO1xuXG4gICAgICBmb3IgKHZhciBpJDIgPSAwOyBpJDIgPCAzOyBpJDIrKykge1xuICAgICAgICByZ2IkMltpJDJdID0gcm91bmQkMihyZ2IkMltpJDJdICogMi41NSk7XG4gICAgICB9XG5cbiAgICAgIHJnYiQyWzNdID0gMTsgLy8gZGVmYXVsdCBhbHBoYVxuXG4gICAgICByZXR1cm4gcmdiJDI7XG4gICAgfSAvLyByZ2JhKDEwMCUsMCUsMCUsMC40KVxuXG5cbiAgICBpZiAobSA9IGNzcy5tYXRjaChSRV9SR0JBX1BDVCkpIHtcbiAgICAgIHZhciByZ2IkMyA9IG0uc2xpY2UoMSwgNSk7XG5cbiAgICAgIGZvciAodmFyIGkkMyA9IDA7IGkkMyA8IDM7IGkkMysrKSB7XG4gICAgICAgIHJnYiQzW2kkM10gPSByb3VuZCQyKHJnYiQzW2kkM10gKiAyLjU1KTtcbiAgICAgIH1cblxuICAgICAgcmdiJDNbM10gPSArcmdiJDNbM107XG4gICAgICByZXR1cm4gcmdiJDM7XG4gICAgfSAvLyBoc2woMCwxMDAlLDUwJSlcblxuXG4gICAgaWYgKG0gPSBjc3MubWF0Y2goUkVfSFNMKSkge1xuICAgICAgdmFyIGhzbCA9IG0uc2xpY2UoMSwgNCk7XG4gICAgICBoc2xbMV0gKj0gMC4wMTtcbiAgICAgIGhzbFsyXSAqPSAwLjAxO1xuICAgICAgdmFyIHJnYiQ0ID0gaHNsMnJnYl8xKGhzbCk7XG4gICAgICByZ2IkNFszXSA9IDE7XG4gICAgICByZXR1cm4gcmdiJDQ7XG4gICAgfSAvLyBoc2xhKDAsMTAwJSw1MCUsMC41KVxuXG5cbiAgICBpZiAobSA9IGNzcy5tYXRjaChSRV9IU0xBKSkge1xuICAgICAgdmFyIGhzbCQxID0gbS5zbGljZSgxLCA0KTtcbiAgICAgIGhzbCQxWzFdICo9IDAuMDE7XG4gICAgICBoc2wkMVsyXSAqPSAwLjAxO1xuICAgICAgdmFyIHJnYiQ1ID0gaHNsMnJnYl8xKGhzbCQxKTtcbiAgICAgIHJnYiQ1WzNdID0gK21bNF07IC8vIGRlZmF1bHQgYWxwaGEgPSAxXG5cbiAgICAgIHJldHVybiByZ2IkNTtcbiAgICB9XG4gIH07XG5cbiAgY3NzMnJnYi50ZXN0ID0gZnVuY3Rpb24gKHMpIHtcbiAgICByZXR1cm4gUkVfUkdCLnRlc3QocykgfHwgUkVfUkdCQS50ZXN0KHMpIHx8IFJFX1JHQl9QQ1QudGVzdChzKSB8fCBSRV9SR0JBX1BDVC50ZXN0KHMpIHx8IFJFX0hTTC50ZXN0KHMpIHx8IFJFX0hTTEEudGVzdChzKTtcbiAgfTtcblxuICB2YXIgY3NzMnJnYl8xID0gY3NzMnJnYjtcbiAgdmFyIHR5cGUkMyA9IHV0aWxzLnR5cGU7XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuY3NzID0gZnVuY3Rpb24gKG1vZGUpIHtcbiAgICByZXR1cm4gcmdiMmNzc18xKHRoaXMuX3JnYiwgbW9kZSk7XG4gIH07XG5cbiAgY2hyb21hXzEuY3NzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWydjc3MnXSkpKSgpO1xuICB9O1xuXG4gIGlucHV0LmZvcm1hdC5jc3MgPSBjc3MycmdiXzE7XG4gIGlucHV0LmF1dG9kZXRlY3QucHVzaCh7XG4gICAgcDogNSxcbiAgICB0ZXN0OiBmdW5jdGlvbiB0ZXN0KGgpIHtcbiAgICAgIHZhciByZXN0ID0gW10sXG4gICAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aCAtIDE7XG5cbiAgICAgIHdoaWxlIChsZW4tLSA+IDApIHtcbiAgICAgICAgcmVzdFtsZW5dID0gYXJndW1lbnRzW2xlbiArIDFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJlc3QubGVuZ3RoICYmIHR5cGUkMyhoKSA9PT0gJ3N0cmluZycgJiYgY3NzMnJnYl8xLnRlc3QoaCkpIHtcbiAgICAgICAgcmV0dXJuICdjc3MnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skOCA9IHV0aWxzLnVucGFjaztcblxuICBpbnB1dC5mb3JtYXQuZ2wgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJnYiA9IHVucGFjayQ4KGFyZ3MsICdyZ2JhJyk7XG4gICAgcmdiWzBdICo9IDI1NTtcbiAgICByZ2JbMV0gKj0gMjU1O1xuICAgIHJnYlsyXSAqPSAyNTU7XG4gICAgcmV0dXJuIHJnYjtcbiAgfTtcblxuICBjaHJvbWFfMS5nbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShDb2xvcl8xLCBbbnVsbF0uY29uY2F0KGFyZ3MsIFsnZ2wnXSkpKSgpO1xuICB9O1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmdsID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciByZ2IgPSB0aGlzLl9yZ2I7XG4gICAgcmV0dXJuIFtyZ2JbMF0gLyAyNTUsIHJnYlsxXSAvIDI1NSwgcmdiWzJdIC8gMjU1LCByZ2JbM11dO1xuICB9O1xuXG4gIHZhciB1bnBhY2skOSA9IHV0aWxzLnVucGFjaztcblxuICB2YXIgcmdiMmhjZyA9IGZ1bmN0aW9uIHJnYjJoY2coKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJlZiA9IHVucGFjayQ5KGFyZ3MsICdyZ2InKTtcbiAgICB2YXIgciA9IHJlZlswXTtcbiAgICB2YXIgZyA9IHJlZlsxXTtcbiAgICB2YXIgYiA9IHJlZlsyXTtcbiAgICB2YXIgbWluID0gTWF0aC5taW4ociwgZywgYik7XG4gICAgdmFyIG1heCA9IE1hdGgubWF4KHIsIGcsIGIpO1xuICAgIHZhciBkZWx0YSA9IG1heCAtIG1pbjtcbiAgICB2YXIgYyA9IGRlbHRhICogMTAwIC8gMjU1O1xuXG4gICAgdmFyIF9nID0gbWluIC8gKDI1NSAtIGRlbHRhKSAqIDEwMDtcblxuICAgIHZhciBoO1xuXG4gICAgaWYgKGRlbHRhID09PSAwKSB7XG4gICAgICBoID0gTnVtYmVyLk5hTjtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHIgPT09IG1heCkge1xuICAgICAgICBoID0gKGcgLSBiKSAvIGRlbHRhO1xuICAgICAgfVxuXG4gICAgICBpZiAoZyA9PT0gbWF4KSB7XG4gICAgICAgIGggPSAyICsgKGIgLSByKSAvIGRlbHRhO1xuICAgICAgfVxuXG4gICAgICBpZiAoYiA9PT0gbWF4KSB7XG4gICAgICAgIGggPSA0ICsgKHIgLSBnKSAvIGRlbHRhO1xuICAgICAgfVxuXG4gICAgICBoICo9IDYwO1xuXG4gICAgICBpZiAoaCA8IDApIHtcbiAgICAgICAgaCArPSAzNjA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtoLCBjLCBfZ107XG4gIH07XG5cbiAgdmFyIHJnYjJoY2dfMSA9IHJnYjJoY2c7XG4gIHZhciB1bnBhY2skYSA9IHV0aWxzLnVucGFjaztcbiAgdmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbiAgLypcbiAgICogdGhpcyBpcyBiYXNpY2FsbHkganVzdCBIU1Ygd2l0aCBzb21lIG1pbm9yIHR3ZWFrc1xuICAgKlxuICAgKiBodWUuLiBbMC4uMzYwXVxuICAgKiBjaHJvbWEgLi4gWzAuLjFdXG4gICAqIGdyYXluZXNzIC4uIFswLi4xXVxuICAgKi9cblxuICB2YXIgaGNnMnJnYiA9IGZ1bmN0aW9uIGhjZzJyZ2IoKSB7XG4gICAgdmFyIGFzc2lnbiwgYXNzaWduJDEsIGFzc2lnbiQyLCBhc3NpZ24kMywgYXNzaWduJDQsIGFzc2lnbiQ1O1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIGFyZ3MgPSB1bnBhY2skYShhcmdzLCAnaGNnJyk7XG4gICAgdmFyIGggPSBhcmdzWzBdO1xuICAgIHZhciBjID0gYXJnc1sxXTtcbiAgICB2YXIgX2cgPSBhcmdzWzJdO1xuICAgIHZhciByLCBnLCBiO1xuICAgIF9nID0gX2cgKiAyNTU7XG5cbiAgICB2YXIgX2MgPSBjICogMjU1O1xuXG4gICAgaWYgKGMgPT09IDApIHtcbiAgICAgIHIgPSBnID0gYiA9IF9nO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaCA9PT0gMzYwKSB7XG4gICAgICAgIGggPSAwO1xuICAgICAgfVxuXG4gICAgICBpZiAoaCA+IDM2MCkge1xuICAgICAgICBoIC09IDM2MDtcbiAgICAgIH1cblxuICAgICAgaWYgKGggPCAwKSB7XG4gICAgICAgIGggKz0gMzYwO1xuICAgICAgfVxuXG4gICAgICBoIC89IDYwO1xuICAgICAgdmFyIGkgPSBmbG9vcihoKTtcbiAgICAgIHZhciBmID0gaCAtIGk7XG4gICAgICB2YXIgcCA9IF9nICogKDEgLSBjKTtcbiAgICAgIHZhciBxID0gcCArIF9jICogKDEgLSBmKTtcbiAgICAgIHZhciB0ID0gcCArIF9jICogZjtcbiAgICAgIHZhciB2ID0gcCArIF9jO1xuXG4gICAgICBzd2l0Y2ggKGkpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGFzc2lnbiA9IFt2LCB0LCBwXSwgciA9IGFzc2lnblswXSwgZyA9IGFzc2lnblsxXSwgYiA9IGFzc2lnblsyXTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgYXNzaWduJDEgPSBbcSwgdiwgcF0sIHIgPSBhc3NpZ24kMVswXSwgZyA9IGFzc2lnbiQxWzFdLCBiID0gYXNzaWduJDFbMl07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIGFzc2lnbiQyID0gW3AsIHYsIHRdLCByID0gYXNzaWduJDJbMF0sIGcgPSBhc3NpZ24kMlsxXSwgYiA9IGFzc2lnbiQyWzJdO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBhc3NpZ24kMyA9IFtwLCBxLCB2XSwgciA9IGFzc2lnbiQzWzBdLCBnID0gYXNzaWduJDNbMV0sIGIgPSBhc3NpZ24kM1syXTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgYXNzaWduJDQgPSBbdCwgcCwgdl0sIHIgPSBhc3NpZ24kNFswXSwgZyA9IGFzc2lnbiQ0WzFdLCBiID0gYXNzaWduJDRbMl07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSA1OlxuICAgICAgICAgIGFzc2lnbiQ1ID0gW3YsIHAsIHFdLCByID0gYXNzaWduJDVbMF0sIGcgPSBhc3NpZ24kNVsxXSwgYiA9IGFzc2lnbiQ1WzJdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBbciwgZywgYiwgYXJncy5sZW5ndGggPiAzID8gYXJnc1szXSA6IDFdO1xuICB9O1xuXG4gIHZhciBoY2cycmdiXzEgPSBoY2cycmdiO1xuICB2YXIgdW5wYWNrJGIgPSB1dGlscy51bnBhY2s7XG4gIHZhciB0eXBlJDQgPSB1dGlscy50eXBlO1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmhjZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcmdiMmhjZ18xKHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEuaGNnID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWydoY2cnXSkpKSgpO1xuICB9O1xuXG4gIGlucHV0LmZvcm1hdC5oY2cgPSBoY2cycmdiXzE7XG4gIGlucHV0LmF1dG9kZXRlY3QucHVzaCh7XG4gICAgcDogMSxcbiAgICB0ZXN0OiBmdW5jdGlvbiB0ZXN0KCkge1xuICAgICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgICB9XG5cbiAgICAgIGFyZ3MgPSB1bnBhY2skYihhcmdzLCAnaGNnJyk7XG5cbiAgICAgIGlmICh0eXBlJDQoYXJncykgPT09ICdhcnJheScgJiYgYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuICdoY2cnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skYyA9IHV0aWxzLnVucGFjaztcbiAgdmFyIGxhc3QkNCA9IHV0aWxzLmxhc3Q7XG4gIHZhciByb3VuZCQzID0gTWF0aC5yb3VuZDtcblxuICB2YXIgcmdiMmhleCA9IGZ1bmN0aW9uIHJnYjJoZXgoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJlZiA9IHVucGFjayRjKGFyZ3MsICdyZ2JhJyk7XG4gICAgdmFyIHIgPSByZWZbMF07XG4gICAgdmFyIGcgPSByZWZbMV07XG4gICAgdmFyIGIgPSByZWZbMl07XG4gICAgdmFyIGEgPSByZWZbM107XG4gICAgdmFyIG1vZGUgPSBsYXN0JDQoYXJncykgfHwgJ2F1dG8nO1xuXG4gICAgaWYgKGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYSA9IDE7XG4gICAgfVxuXG4gICAgaWYgKG1vZGUgPT09ICdhdXRvJykge1xuICAgICAgbW9kZSA9IGEgPCAxID8gJ3JnYmEnIDogJ3JnYic7XG4gICAgfVxuXG4gICAgciA9IHJvdW5kJDMocik7XG4gICAgZyA9IHJvdW5kJDMoZyk7XG4gICAgYiA9IHJvdW5kJDMoYik7XG4gICAgdmFyIHUgPSByIDw8IDE2IHwgZyA8PCA4IHwgYjtcbiAgICB2YXIgc3RyID0gXCIwMDAwMDBcIiArIHUudG9TdHJpbmcoMTYpOyAvLyMudG9VcHBlckNhc2UoKTtcblxuICAgIHN0ciA9IHN0ci5zdWJzdHIoc3RyLmxlbmd0aCAtIDYpO1xuICAgIHZhciBoeGEgPSAnMCcgKyByb3VuZCQzKGEgKiAyNTUpLnRvU3RyaW5nKDE2KTtcbiAgICBoeGEgPSBoeGEuc3Vic3RyKGh4YS5sZW5ndGggLSAyKTtcblxuICAgIHN3aXRjaCAobW9kZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICdyZ2JhJzpcbiAgICAgICAgcmV0dXJuIFwiI1wiICsgc3RyICsgaHhhO1xuXG4gICAgICBjYXNlICdhcmdiJzpcbiAgICAgICAgcmV0dXJuIFwiI1wiICsgaHhhICsgc3RyO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gXCIjXCIgKyBzdHI7XG4gICAgfVxuICB9O1xuXG4gIHZhciByZ2IyaGV4XzEgPSByZ2IyaGV4O1xuICB2YXIgUkVfSEVYID0gL14jPyhbQS1GYS1mMC05XXs2fXxbQS1GYS1mMC05XXszfSkkLztcbiAgdmFyIFJFX0hFWEEgPSAvXiM/KFtBLUZhLWYwLTldezh9fFtBLUZhLWYwLTldezR9KSQvO1xuXG4gIHZhciBoZXgycmdiID0gZnVuY3Rpb24gaGV4MnJnYihoZXgpIHtcbiAgICBpZiAoaGV4Lm1hdGNoKFJFX0hFWCkpIHtcbiAgICAgIC8vIHJlbW92ZSBvcHRpb25hbCBsZWFkaW5nICNcbiAgICAgIGlmIChoZXgubGVuZ3RoID09PSA0IHx8IGhleC5sZW5ndGggPT09IDcpIHtcbiAgICAgICAgaGV4ID0gaGV4LnN1YnN0cigxKTtcbiAgICAgIH0gLy8gZXhwYW5kIHNob3J0LW5vdGF0aW9uIHRvIGZ1bGwgc2l4LWRpZ2l0XG5cblxuICAgICAgaWYgKGhleC5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgaGV4ID0gaGV4LnNwbGl0KCcnKTtcbiAgICAgICAgaGV4ID0gaGV4WzBdICsgaGV4WzBdICsgaGV4WzFdICsgaGV4WzFdICsgaGV4WzJdICsgaGV4WzJdO1xuICAgICAgfVxuXG4gICAgICB2YXIgdSA9IHBhcnNlSW50KGhleCwgMTYpO1xuICAgICAgdmFyIHIgPSB1ID4+IDE2O1xuICAgICAgdmFyIGcgPSB1ID4+IDggJiAweEZGO1xuICAgICAgdmFyIGIgPSB1ICYgMHhGRjtcbiAgICAgIHJldHVybiBbciwgZywgYiwgMV07XG4gICAgfSAvLyBtYXRjaCByZ2JhIGhleCBmb3JtYXQsIGVnICNGRjAwMDA3N1xuXG5cbiAgICBpZiAoaGV4Lm1hdGNoKFJFX0hFWEEpKSB7XG4gICAgICBpZiAoaGV4Lmxlbmd0aCA9PT0gNSB8fCBoZXgubGVuZ3RoID09PSA5KSB7XG4gICAgICAgIC8vIHJlbW92ZSBvcHRpb25hbCBsZWFkaW5nICNcbiAgICAgICAgaGV4ID0gaGV4LnN1YnN0cigxKTtcbiAgICAgIH0gLy8gZXhwYW5kIHNob3J0LW5vdGF0aW9uIHRvIGZ1bGwgZWlnaHQtZGlnaXRcblxuXG4gICAgICBpZiAoaGV4Lmxlbmd0aCA9PT0gNCkge1xuICAgICAgICBoZXggPSBoZXguc3BsaXQoJycpO1xuICAgICAgICBoZXggPSBoZXhbMF0gKyBoZXhbMF0gKyBoZXhbMV0gKyBoZXhbMV0gKyBoZXhbMl0gKyBoZXhbMl0gKyBoZXhbM10gKyBoZXhbM107XG4gICAgICB9XG5cbiAgICAgIHZhciB1JDEgPSBwYXJzZUludChoZXgsIDE2KTtcbiAgICAgIHZhciByJDEgPSB1JDEgPj4gMjQgJiAweEZGO1xuICAgICAgdmFyIGckMSA9IHUkMSA+PiAxNiAmIDB4RkY7XG4gICAgICB2YXIgYiQxID0gdSQxID4+IDggJiAweEZGO1xuICAgICAgdmFyIGEgPSBNYXRoLnJvdW5kKCh1JDEgJiAweEZGKSAvIDB4RkYgKiAxMDApIC8gMTAwO1xuICAgICAgcmV0dXJuIFtyJDEsIGckMSwgYiQxLCBhXTtcbiAgICB9IC8vIHdlIHVzZWQgdG8gY2hlY2sgZm9yIGNzcyBjb2xvcnMgaGVyZVxuICAgIC8vIGlmIF9pbnB1dC5jc3M/IGFuZCByZ2IgPSBfaW5wdXQuY3NzIGhleFxuICAgIC8vICAgICByZXR1cm4gcmdiXG5cblxuICAgIHRocm93IG5ldyBFcnJvcihcInVua25vd24gaGV4IGNvbG9yOiBcIiArIGhleCk7XG4gIH07XG5cbiAgdmFyIGhleDJyZ2JfMSA9IGhleDJyZ2I7XG4gIHZhciB0eXBlJDUgPSB1dGlscy50eXBlO1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmhleCA9IGZ1bmN0aW9uIChtb2RlKSB7XG4gICAgcmV0dXJuIHJnYjJoZXhfMSh0aGlzLl9yZ2IsIG1vZGUpO1xuICB9O1xuXG4gIGNocm9tYV8xLmhleCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShDb2xvcl8xLCBbbnVsbF0uY29uY2F0KGFyZ3MsIFsnaGV4J10pKSkoKTtcbiAgfTtcblxuICBpbnB1dC5mb3JtYXQuaGV4ID0gaGV4MnJnYl8xO1xuICBpbnB1dC5hdXRvZGV0ZWN0LnB1c2goe1xuICAgIHA6IDQsXG4gICAgdGVzdDogZnVuY3Rpb24gdGVzdChoKSB7XG4gICAgICB2YXIgcmVzdCA9IFtdLFxuICAgICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGggLSAxO1xuXG4gICAgICB3aGlsZSAobGVuLS0gPiAwKSB7XG4gICAgICAgIHJlc3RbbGVuXSA9IGFyZ3VtZW50c1tsZW4gKyAxXTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFyZXN0Lmxlbmd0aCAmJiB0eXBlJDUoaCkgPT09ICdzdHJpbmcnICYmIFszLCA0LCA1LCA2LCA3LCA4LCA5XS5pbmRleE9mKGgubGVuZ3RoKSA+PSAwKSB7XG4gICAgICAgIHJldHVybiAnaGV4JztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICB2YXIgdW5wYWNrJGQgPSB1dGlscy51bnBhY2s7XG4gIHZhciBUV09QSSA9IHV0aWxzLlRXT1BJO1xuICB2YXIgbWluID0gTWF0aC5taW47XG4gIHZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xuICB2YXIgYWNvcyA9IE1hdGguYWNvcztcblxuICB2YXIgcmdiMmhzaSA9IGZ1bmN0aW9uIHJnYjJoc2koKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuICAgIC8qXG4gICAgYm9ycm93ZWQgZnJvbSBoZXJlOlxuICAgIGh0dHA6Ly9odW1tZXIuc3RhbmZvcmQuZWR1L211c2VpbmZvL2RvYy9leGFtcGxlcy9odW1kcnVtL2tleXNjYXBlMi9yZ2IyaHNpLmNwcFxuICAgICovXG5cblxuICAgIHZhciByZWYgPSB1bnBhY2skZChhcmdzLCAncmdiJyk7XG4gICAgdmFyIHIgPSByZWZbMF07XG4gICAgdmFyIGcgPSByZWZbMV07XG4gICAgdmFyIGIgPSByZWZbMl07XG4gICAgciAvPSAyNTU7XG4gICAgZyAvPSAyNTU7XG4gICAgYiAvPSAyNTU7XG4gICAgdmFyIGg7XG4gICAgdmFyIG1pbl8gPSBtaW4ociwgZywgYik7XG4gICAgdmFyIGkgPSAociArIGcgKyBiKSAvIDM7XG4gICAgdmFyIHMgPSBpID4gMCA/IDEgLSBtaW5fIC8gaSA6IDA7XG5cbiAgICBpZiAocyA9PT0gMCkge1xuICAgICAgaCA9IE5hTjtcbiAgICB9IGVsc2Uge1xuICAgICAgaCA9IChyIC0gZyArIChyIC0gYikpIC8gMjtcbiAgICAgIGggLz0gc3FydCgociAtIGcpICogKHIgLSBnKSArIChyIC0gYikgKiAoZyAtIGIpKTtcbiAgICAgIGggPSBhY29zKGgpO1xuXG4gICAgICBpZiAoYiA+IGcpIHtcbiAgICAgICAgaCA9IFRXT1BJIC0gaDtcbiAgICAgIH1cblxuICAgICAgaCAvPSBUV09QSTtcbiAgICB9XG5cbiAgICByZXR1cm4gW2ggKiAzNjAsIHMsIGldO1xuICB9O1xuXG4gIHZhciByZ2IyaHNpXzEgPSByZ2IyaHNpO1xuICB2YXIgdW5wYWNrJGUgPSB1dGlscy51bnBhY2s7XG4gIHZhciBsaW1pdCQxID0gdXRpbHMubGltaXQ7XG4gIHZhciBUV09QSSQxID0gdXRpbHMuVFdPUEk7XG4gIHZhciBQSVRISVJEID0gdXRpbHMuUElUSElSRDtcbiAgdmFyIGNvcyA9IE1hdGguY29zO1xuICAvKlxuICAgKiBodWUgWzAuLjM2MF1cbiAgICogc2F0dXJhdGlvbiBbMC4uMV1cbiAgICogaW50ZW5zaXR5IFswLi4xXVxuICAgKi9cblxuICB2YXIgaHNpMnJnYiA9IGZ1bmN0aW9uIGhzaTJyZ2IoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuICAgIC8qXG4gICAgYm9ycm93ZWQgZnJvbSBoZXJlOlxuICAgIGh0dHA6Ly9odW1tZXIuc3RhbmZvcmQuZWR1L211c2VpbmZvL2RvYy9leGFtcGxlcy9odW1kcnVtL2tleXNjYXBlMi9oc2kycmdiLmNwcFxuICAgICovXG5cblxuICAgIGFyZ3MgPSB1bnBhY2skZShhcmdzLCAnaHNpJyk7XG4gICAgdmFyIGggPSBhcmdzWzBdO1xuICAgIHZhciBzID0gYXJnc1sxXTtcbiAgICB2YXIgaSA9IGFyZ3NbMl07XG4gICAgdmFyIHIsIGcsIGI7XG5cbiAgICBpZiAoaXNOYU4oaCkpIHtcbiAgICAgIGggPSAwO1xuICAgIH1cblxuICAgIGlmIChpc05hTihzKSkge1xuICAgICAgcyA9IDA7XG4gICAgfSAvLyBub3JtYWxpemUgaHVlXG5cblxuICAgIGlmIChoID4gMzYwKSB7XG4gICAgICBoIC09IDM2MDtcbiAgICB9XG5cbiAgICBpZiAoaCA8IDApIHtcbiAgICAgIGggKz0gMzYwO1xuICAgIH1cblxuICAgIGggLz0gMzYwO1xuXG4gICAgaWYgKGggPCAxIC8gMykge1xuICAgICAgYiA9ICgxIC0gcykgLyAzO1xuICAgICAgciA9ICgxICsgcyAqIGNvcyhUV09QSSQxICogaCkgLyBjb3MoUElUSElSRCAtIFRXT1BJJDEgKiBoKSkgLyAzO1xuICAgICAgZyA9IDEgLSAoYiArIHIpO1xuICAgIH0gZWxzZSBpZiAoaCA8IDIgLyAzKSB7XG4gICAgICBoIC09IDEgLyAzO1xuICAgICAgciA9ICgxIC0gcykgLyAzO1xuICAgICAgZyA9ICgxICsgcyAqIGNvcyhUV09QSSQxICogaCkgLyBjb3MoUElUSElSRCAtIFRXT1BJJDEgKiBoKSkgLyAzO1xuICAgICAgYiA9IDEgLSAociArIGcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBoIC09IDIgLyAzO1xuICAgICAgZyA9ICgxIC0gcykgLyAzO1xuICAgICAgYiA9ICgxICsgcyAqIGNvcyhUV09QSSQxICogaCkgLyBjb3MoUElUSElSRCAtIFRXT1BJJDEgKiBoKSkgLyAzO1xuICAgICAgciA9IDEgLSAoZyArIGIpO1xuICAgIH1cblxuICAgIHIgPSBsaW1pdCQxKGkgKiByICogMyk7XG4gICAgZyA9IGxpbWl0JDEoaSAqIGcgKiAzKTtcbiAgICBiID0gbGltaXQkMShpICogYiAqIDMpO1xuICAgIHJldHVybiBbciAqIDI1NSwgZyAqIDI1NSwgYiAqIDI1NSwgYXJncy5sZW5ndGggPiAzID8gYXJnc1szXSA6IDFdO1xuICB9O1xuXG4gIHZhciBoc2kycmdiXzEgPSBoc2kycmdiO1xuICB2YXIgdW5wYWNrJGYgPSB1dGlscy51bnBhY2s7XG4gIHZhciB0eXBlJDYgPSB1dGlscy50eXBlO1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmhzaSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcmdiMmhzaV8xKHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEuaHNpID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWydoc2knXSkpKSgpO1xuICB9O1xuXG4gIGlucHV0LmZvcm1hdC5oc2kgPSBoc2kycmdiXzE7XG4gIGlucHV0LmF1dG9kZXRlY3QucHVzaCh7XG4gICAgcDogMixcbiAgICB0ZXN0OiBmdW5jdGlvbiB0ZXN0KCkge1xuICAgICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgICB9XG5cbiAgICAgIGFyZ3MgPSB1bnBhY2skZihhcmdzLCAnaHNpJyk7XG5cbiAgICAgIGlmICh0eXBlJDYoYXJncykgPT09ICdhcnJheScgJiYgYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuICdoc2knO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skZyA9IHV0aWxzLnVucGFjaztcbiAgdmFyIHR5cGUkNyA9IHV0aWxzLnR5cGU7XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuaHNsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZ2IyaHNsXzEodGhpcy5fcmdiKTtcbiAgfTtcblxuICBjaHJvbWFfMS5oc2wgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyAoRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuYXBwbHkoQ29sb3JfMSwgW251bGxdLmNvbmNhdChhcmdzLCBbJ2hzbCddKSkpKCk7XG4gIH07XG5cbiAgaW5wdXQuZm9ybWF0LmhzbCA9IGhzbDJyZ2JfMTtcbiAgaW5wdXQuYXV0b2RldGVjdC5wdXNoKHtcbiAgICBwOiAyLFxuICAgIHRlc3Q6IGZ1bmN0aW9uIHRlc3QoKSB7XG4gICAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICAgIH1cblxuICAgICAgYXJncyA9IHVucGFjayRnKGFyZ3MsICdoc2wnKTtcblxuICAgICAgaWYgKHR5cGUkNyhhcmdzKSA9PT0gJ2FycmF5JyAmJiBhcmdzLmxlbmd0aCA9PT0gMykge1xuICAgICAgICByZXR1cm4gJ2hzbCc7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgdmFyIHVucGFjayRoID0gdXRpbHMudW5wYWNrO1xuICB2YXIgbWluJDEgPSBNYXRoLm1pbjtcbiAgdmFyIG1heCQxID0gTWF0aC5tYXg7XG4gIC8qXG4gICAqIHN1cHBvcnRlZCBhcmd1bWVudHM6XG4gICAqIC0gcmdiMmhzdihyLGcsYilcbiAgICogLSByZ2IyaHN2KFtyLGcsYl0pXG4gICAqIC0gcmdiMmhzdih7cixnLGJ9KVxuICAgKi9cblxuICB2YXIgcmdiMmhzbCQxID0gZnVuY3Rpb24gcmdiMmhzbCQxKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIGFyZ3MgPSB1bnBhY2skaChhcmdzLCAncmdiJyk7XG4gICAgdmFyIHIgPSBhcmdzWzBdO1xuICAgIHZhciBnID0gYXJnc1sxXTtcbiAgICB2YXIgYiA9IGFyZ3NbMl07XG4gICAgdmFyIG1pbl8gPSBtaW4kMShyLCBnLCBiKTtcbiAgICB2YXIgbWF4XyA9IG1heCQxKHIsIGcsIGIpO1xuICAgIHZhciBkZWx0YSA9IG1heF8gLSBtaW5fO1xuICAgIHZhciBoLCBzLCB2O1xuICAgIHYgPSBtYXhfIC8gMjU1LjA7XG5cbiAgICBpZiAobWF4XyA9PT0gMCkge1xuICAgICAgaCA9IE51bWJlci5OYU47XG4gICAgICBzID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgcyA9IGRlbHRhIC8gbWF4XztcblxuICAgICAgaWYgKHIgPT09IG1heF8pIHtcbiAgICAgICAgaCA9IChnIC0gYikgLyBkZWx0YTtcbiAgICAgIH1cblxuICAgICAgaWYgKGcgPT09IG1heF8pIHtcbiAgICAgICAgaCA9IDIgKyAoYiAtIHIpIC8gZGVsdGE7XG4gICAgICB9XG5cbiAgICAgIGlmIChiID09PSBtYXhfKSB7XG4gICAgICAgIGggPSA0ICsgKHIgLSBnKSAvIGRlbHRhO1xuICAgICAgfVxuXG4gICAgICBoICo9IDYwO1xuXG4gICAgICBpZiAoaCA8IDApIHtcbiAgICAgICAgaCArPSAzNjA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtoLCBzLCB2XTtcbiAgfTtcblxuICB2YXIgcmdiMmhzdiA9IHJnYjJoc2wkMTtcbiAgdmFyIHVucGFjayRpID0gdXRpbHMudW5wYWNrO1xuICB2YXIgZmxvb3IkMSA9IE1hdGguZmxvb3I7XG5cbiAgdmFyIGhzdjJyZ2IgPSBmdW5jdGlvbiBoc3YycmdiKCkge1xuICAgIHZhciBhc3NpZ24sIGFzc2lnbiQxLCBhc3NpZ24kMiwgYXNzaWduJDMsIGFzc2lnbiQ0LCBhc3NpZ24kNTtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICBhcmdzID0gdW5wYWNrJGkoYXJncywgJ2hzdicpO1xuICAgIHZhciBoID0gYXJnc1swXTtcbiAgICB2YXIgcyA9IGFyZ3NbMV07XG4gICAgdmFyIHYgPSBhcmdzWzJdO1xuICAgIHZhciByLCBnLCBiO1xuICAgIHYgKj0gMjU1O1xuXG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgIHIgPSBnID0gYiA9IHY7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoID09PSAzNjApIHtcbiAgICAgICAgaCA9IDA7XG4gICAgICB9XG5cbiAgICAgIGlmIChoID4gMzYwKSB7XG4gICAgICAgIGggLT0gMzYwO1xuICAgICAgfVxuXG4gICAgICBpZiAoaCA8IDApIHtcbiAgICAgICAgaCArPSAzNjA7XG4gICAgICB9XG5cbiAgICAgIGggLz0gNjA7XG4gICAgICB2YXIgaSA9IGZsb29yJDEoaCk7XG4gICAgICB2YXIgZiA9IGggLSBpO1xuICAgICAgdmFyIHAgPSB2ICogKDEgLSBzKTtcbiAgICAgIHZhciBxID0gdiAqICgxIC0gcyAqIGYpO1xuICAgICAgdmFyIHQgPSB2ICogKDEgLSBzICogKDEgLSBmKSk7XG5cbiAgICAgIHN3aXRjaCAoaSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgYXNzaWduID0gW3YsIHQsIHBdLCByID0gYXNzaWduWzBdLCBnID0gYXNzaWduWzFdLCBiID0gYXNzaWduWzJdO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICBhc3NpZ24kMSA9IFtxLCB2LCBwXSwgciA9IGFzc2lnbiQxWzBdLCBnID0gYXNzaWduJDFbMV0sIGIgPSBhc3NpZ24kMVsyXTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgYXNzaWduJDIgPSBbcCwgdiwgdF0sIHIgPSBhc3NpZ24kMlswXSwgZyA9IGFzc2lnbiQyWzFdLCBiID0gYXNzaWduJDJbMl07XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGFzc2lnbiQzID0gW3AsIHEsIHZdLCByID0gYXNzaWduJDNbMF0sIGcgPSBhc3NpZ24kM1sxXSwgYiA9IGFzc2lnbiQzWzJdO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhc3NpZ24kNCA9IFt0LCBwLCB2XSwgciA9IGFzc2lnbiQ0WzBdLCBnID0gYXNzaWduJDRbMV0sIGIgPSBhc3NpZ24kNFsyXTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgYXNzaWduJDUgPSBbdiwgcCwgcV0sIHIgPSBhc3NpZ24kNVswXSwgZyA9IGFzc2lnbiQ1WzFdLCBiID0gYXNzaWduJDVbMl07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIFtyLCBnLCBiLCBhcmdzLmxlbmd0aCA+IDMgPyBhcmdzWzNdIDogMV07XG4gIH07XG5cbiAgdmFyIGhzdjJyZ2JfMSA9IGhzdjJyZ2I7XG4gIHZhciB1bnBhY2skaiA9IHV0aWxzLnVucGFjaztcbiAgdmFyIHR5cGUkOCA9IHV0aWxzLnR5cGU7XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuaHN2ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZ2IyaHN2KHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEuaHN2ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWydoc3YnXSkpKSgpO1xuICB9O1xuXG4gIGlucHV0LmZvcm1hdC5oc3YgPSBoc3YycmdiXzE7XG4gIGlucHV0LmF1dG9kZXRlY3QucHVzaCh7XG4gICAgcDogMixcbiAgICB0ZXN0OiBmdW5jdGlvbiB0ZXN0KCkge1xuICAgICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgICB9XG5cbiAgICAgIGFyZ3MgPSB1bnBhY2skaihhcmdzLCAnaHN2Jyk7XG5cbiAgICAgIGlmICh0eXBlJDgoYXJncykgPT09ICdhcnJheScgJiYgYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuICdoc3YnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciBsYWJDb25zdGFudHMgPSB7XG4gICAgLy8gQ29ycmVzcG9uZHMgcm91Z2hseSB0byBSR0IgYnJpZ2h0ZXIvZGFya2VyXG4gICAgS246IDE4LFxuICAgIC8vIEQ2NSBzdGFuZGFyZCByZWZlcmVudFxuICAgIFhuOiAwLjk1MDQ3MCxcbiAgICBZbjogMSxcbiAgICBabjogMS4wODg4MzAsXG4gICAgdDA6IDAuMTM3OTMxMDM0LFxuICAgIC8vIDQgLyAyOVxuICAgIHQxOiAwLjIwNjg5NjU1MixcbiAgICAvLyA2IC8gMjlcbiAgICB0MjogMC4xMjg0MTg1NSxcbiAgICAvLyAzICogdDEgKiB0MVxuICAgIHQzOiAwLjAwODg1NjQ1MiAvLyB0MSAqIHQxICogdDFcblxuICB9O1xuICB2YXIgdW5wYWNrJGsgPSB1dGlscy51bnBhY2s7XG4gIHZhciBwb3cgPSBNYXRoLnBvdztcblxuICB2YXIgcmdiMmxhYiA9IGZ1bmN0aW9uIHJnYjJsYWIoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJlZiA9IHVucGFjayRrKGFyZ3MsICdyZ2InKTtcbiAgICB2YXIgciA9IHJlZlswXTtcbiAgICB2YXIgZyA9IHJlZlsxXTtcbiAgICB2YXIgYiA9IHJlZlsyXTtcbiAgICB2YXIgcmVmJDEgPSByZ2IyeHl6KHIsIGcsIGIpO1xuICAgIHZhciB4ID0gcmVmJDFbMF07XG4gICAgdmFyIHkgPSByZWYkMVsxXTtcbiAgICB2YXIgeiA9IHJlZiQxWzJdO1xuICAgIHZhciBsID0gMTE2ICogeSAtIDE2O1xuICAgIHJldHVybiBbbCA8IDAgPyAwIDogbCwgNTAwICogKHggLSB5KSwgMjAwICogKHkgLSB6KV07XG4gIH07XG5cbiAgdmFyIHJnYl94eXogPSBmdW5jdGlvbiByZ2JfeHl6KHIpIHtcbiAgICBpZiAoKHIgLz0gMjU1KSA8PSAwLjA0MDQ1KSB7XG4gICAgICByZXR1cm4gciAvIDEyLjkyO1xuICAgIH1cblxuICAgIHJldHVybiBwb3coKHIgKyAwLjA1NSkgLyAxLjA1NSwgMi40KTtcbiAgfTtcblxuICB2YXIgeHl6X2xhYiA9IGZ1bmN0aW9uIHh5el9sYWIodCkge1xuICAgIGlmICh0ID4gbGFiQ29uc3RhbnRzLnQzKSB7XG4gICAgICByZXR1cm4gcG93KHQsIDEgLyAzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdCAvIGxhYkNvbnN0YW50cy50MiArIGxhYkNvbnN0YW50cy50MDtcbiAgfTtcblxuICB2YXIgcmdiMnh5eiA9IGZ1bmN0aW9uIHJnYjJ4eXoociwgZywgYikge1xuICAgIHIgPSByZ2JfeHl6KHIpO1xuICAgIGcgPSByZ2JfeHl6KGcpO1xuICAgIGIgPSByZ2JfeHl6KGIpO1xuICAgIHZhciB4ID0geHl6X2xhYigoMC40MTI0NTY0ICogciArIDAuMzU3NTc2MSAqIGcgKyAwLjE4MDQzNzUgKiBiKSAvIGxhYkNvbnN0YW50cy5Ybik7XG4gICAgdmFyIHkgPSB4eXpfbGFiKCgwLjIxMjY3MjkgKiByICsgMC43MTUxNTIyICogZyArIDAuMDcyMTc1MCAqIGIpIC8gbGFiQ29uc3RhbnRzLlluKTtcbiAgICB2YXIgeiA9IHh5el9sYWIoKDAuMDE5MzMzOSAqIHIgKyAwLjExOTE5MjAgKiBnICsgMC45NTAzMDQxICogYikgLyBsYWJDb25zdGFudHMuWm4pO1xuICAgIHJldHVybiBbeCwgeSwgel07XG4gIH07XG5cbiAgdmFyIHJnYjJsYWJfMSA9IHJnYjJsYWI7XG4gIHZhciB1bnBhY2skbCA9IHV0aWxzLnVucGFjaztcbiAgdmFyIHBvdyQxID0gTWF0aC5wb3c7XG4gIC8qXG4gICAqIEwqIFswLi4xMDBdXG4gICAqIGEgWy0xMDAuLjEwMF1cbiAgICogYiBbLTEwMC4uMTAwXVxuICAgKi9cblxuICB2YXIgbGFiMnJnYiA9IGZ1bmN0aW9uIGxhYjJyZ2IoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgYXJncyA9IHVucGFjayRsKGFyZ3MsICdsYWInKTtcbiAgICB2YXIgbCA9IGFyZ3NbMF07XG4gICAgdmFyIGEgPSBhcmdzWzFdO1xuICAgIHZhciBiID0gYXJnc1syXTtcbiAgICB2YXIgeCwgeSwgeiwgciwgZywgYl87XG4gICAgeSA9IChsICsgMTYpIC8gMTE2O1xuICAgIHggPSBpc05hTihhKSA/IHkgOiB5ICsgYSAvIDUwMDtcbiAgICB6ID0gaXNOYU4oYikgPyB5IDogeSAtIGIgLyAyMDA7XG4gICAgeSA9IGxhYkNvbnN0YW50cy5ZbiAqIGxhYl94eXooeSk7XG4gICAgeCA9IGxhYkNvbnN0YW50cy5YbiAqIGxhYl94eXooeCk7XG4gICAgeiA9IGxhYkNvbnN0YW50cy5abiAqIGxhYl94eXooeik7XG4gICAgciA9IHh5el9yZ2IoMy4yNDA0NTQyICogeCAtIDEuNTM3MTM4NSAqIHkgLSAwLjQ5ODUzMTQgKiB6KTsgLy8gRDY1IC0+IHNSR0JcblxuICAgIGcgPSB4eXpfcmdiKC0wLjk2OTI2NjAgKiB4ICsgMS44NzYwMTA4ICogeSArIDAuMDQxNTU2MCAqIHopO1xuICAgIGJfID0geHl6X3JnYigwLjA1NTY0MzQgKiB4IC0gMC4yMDQwMjU5ICogeSArIDEuMDU3MjI1MiAqIHopO1xuICAgIHJldHVybiBbciwgZywgYl8sIGFyZ3MubGVuZ3RoID4gMyA/IGFyZ3NbM10gOiAxXTtcbiAgfTtcblxuICB2YXIgeHl6X3JnYiA9IGZ1bmN0aW9uIHh5el9yZ2Iocikge1xuICAgIHJldHVybiAyNTUgKiAociA8PSAwLjAwMzA0ID8gMTIuOTIgKiByIDogMS4wNTUgKiBwb3ckMShyLCAxIC8gMi40KSAtIDAuMDU1KTtcbiAgfTtcblxuICB2YXIgbGFiX3h5eiA9IGZ1bmN0aW9uIGxhYl94eXoodCkge1xuICAgIHJldHVybiB0ID4gbGFiQ29uc3RhbnRzLnQxID8gdCAqIHQgKiB0IDogbGFiQ29uc3RhbnRzLnQyICogKHQgLSBsYWJDb25zdGFudHMudDApO1xuICB9O1xuXG4gIHZhciBsYWIycmdiXzEgPSBsYWIycmdiO1xuICB2YXIgdW5wYWNrJG0gPSB1dGlscy51bnBhY2s7XG4gIHZhciB0eXBlJDkgPSB1dGlscy50eXBlO1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmxhYiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcmdiMmxhYl8xKHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEubGFiID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWydsYWInXSkpKSgpO1xuICB9O1xuXG4gIGlucHV0LmZvcm1hdC5sYWIgPSBsYWIycmdiXzE7XG4gIGlucHV0LmF1dG9kZXRlY3QucHVzaCh7XG4gICAgcDogMixcbiAgICB0ZXN0OiBmdW5jdGlvbiB0ZXN0KCkge1xuICAgICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgICB9XG5cbiAgICAgIGFyZ3MgPSB1bnBhY2skbShhcmdzLCAnbGFiJyk7XG5cbiAgICAgIGlmICh0eXBlJDkoYXJncykgPT09ICdhcnJheScgJiYgYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgcmV0dXJuICdsYWInO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skbiA9IHV0aWxzLnVucGFjaztcbiAgdmFyIFJBRDJERUcgPSB1dGlscy5SQUQyREVHO1xuICB2YXIgc3FydCQxID0gTWF0aC5zcXJ0O1xuICB2YXIgYXRhbjIgPSBNYXRoLmF0YW4yO1xuICB2YXIgcm91bmQkNCA9IE1hdGgucm91bmQ7XG5cbiAgdmFyIGxhYjJsY2ggPSBmdW5jdGlvbiBsYWIybGNoKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHZhciByZWYgPSB1bnBhY2skbihhcmdzLCAnbGFiJyk7XG4gICAgdmFyIGwgPSByZWZbMF07XG4gICAgdmFyIGEgPSByZWZbMV07XG4gICAgdmFyIGIgPSByZWZbMl07XG4gICAgdmFyIGMgPSBzcXJ0JDEoYSAqIGEgKyBiICogYik7XG4gICAgdmFyIGggPSAoYXRhbjIoYiwgYSkgKiBSQUQyREVHICsgMzYwKSAlIDM2MDtcblxuICAgIGlmIChyb3VuZCQ0KGMgKiAxMDAwMCkgPT09IDApIHtcbiAgICAgIGggPSBOdW1iZXIuTmFOO1xuICAgIH1cblxuICAgIHJldHVybiBbbCwgYywgaF07XG4gIH07XG5cbiAgdmFyIGxhYjJsY2hfMSA9IGxhYjJsY2g7XG4gIHZhciB1bnBhY2skbyA9IHV0aWxzLnVucGFjaztcblxuICB2YXIgcmdiMmxjaCA9IGZ1bmN0aW9uIHJnYjJsY2goKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJlZiA9IHVucGFjayRvKGFyZ3MsICdyZ2InKTtcbiAgICB2YXIgciA9IHJlZlswXTtcbiAgICB2YXIgZyA9IHJlZlsxXTtcbiAgICB2YXIgYiA9IHJlZlsyXTtcbiAgICB2YXIgcmVmJDEgPSByZ2IybGFiXzEociwgZywgYik7XG4gICAgdmFyIGwgPSByZWYkMVswXTtcbiAgICB2YXIgYSA9IHJlZiQxWzFdO1xuICAgIHZhciBiXyA9IHJlZiQxWzJdO1xuICAgIHJldHVybiBsYWIybGNoXzEobCwgYSwgYl8pO1xuICB9O1xuXG4gIHZhciByZ2IybGNoXzEgPSByZ2IybGNoO1xuICB2YXIgdW5wYWNrJHAgPSB1dGlscy51bnBhY2s7XG4gIHZhciBERUcyUkFEID0gdXRpbHMuREVHMlJBRDtcbiAgdmFyIHNpbiA9IE1hdGguc2luO1xuICB2YXIgY29zJDEgPSBNYXRoLmNvcztcblxuICB2YXIgbGNoMmxhYiA9IGZ1bmN0aW9uIGxjaDJsYWIoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuICAgIC8qXG4gICAgQ29udmVydCBmcm9tIGEgcXVhbGl0YXRpdmUgcGFyYW1ldGVyIGggYW5kIGEgcXVhbnRpdGF0aXZlIHBhcmFtZXRlciBsIHRvIGEgMjQtYml0IHBpeGVsLlxuICAgIFRoZXNlIGZvcm11bGFzIHdlcmUgaW52ZW50ZWQgYnkgRGF2aWQgRGFscnltcGxlIHRvIG9idGFpbiBtYXhpbXVtIGNvbnRyYXN0IHdpdGhvdXQgZ29pbmdcbiAgICBvdXQgb2YgZ2FtdXQgaWYgdGhlIHBhcmFtZXRlcnMgYXJlIGluIHRoZSByYW5nZSAwLTEuXG4gICAgIEEgc2F0dXJhdGlvbiBtdWx0aXBsaWVyIHdhcyBhZGRlZCBieSBHcmVnb3IgQWlzY2hcbiAgICAqL1xuXG5cbiAgICB2YXIgcmVmID0gdW5wYWNrJHAoYXJncywgJ2xjaCcpO1xuICAgIHZhciBsID0gcmVmWzBdO1xuICAgIHZhciBjID0gcmVmWzFdO1xuICAgIHZhciBoID0gcmVmWzJdO1xuXG4gICAgaWYgKGlzTmFOKGgpKSB7XG4gICAgICBoID0gMDtcbiAgICB9XG5cbiAgICBoID0gaCAqIERFRzJSQUQ7XG4gICAgcmV0dXJuIFtsLCBjb3MkMShoKSAqIGMsIHNpbihoKSAqIGNdO1xuICB9O1xuXG4gIHZhciBsY2gybGFiXzEgPSBsY2gybGFiO1xuICB2YXIgdW5wYWNrJHEgPSB1dGlscy51bnBhY2s7XG5cbiAgdmFyIGxjaDJyZ2IgPSBmdW5jdGlvbiBsY2gycmdiKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIGFyZ3MgPSB1bnBhY2skcShhcmdzLCAnbGNoJyk7XG4gICAgdmFyIGwgPSBhcmdzWzBdO1xuICAgIHZhciBjID0gYXJnc1sxXTtcbiAgICB2YXIgaCA9IGFyZ3NbMl07XG4gICAgdmFyIHJlZiA9IGxjaDJsYWJfMShsLCBjLCBoKTtcbiAgICB2YXIgTCA9IHJlZlswXTtcbiAgICB2YXIgYSA9IHJlZlsxXTtcbiAgICB2YXIgYl8gPSByZWZbMl07XG4gICAgdmFyIHJlZiQxID0gbGFiMnJnYl8xKEwsIGEsIGJfKTtcbiAgICB2YXIgciA9IHJlZiQxWzBdO1xuICAgIHZhciBnID0gcmVmJDFbMV07XG4gICAgdmFyIGIgPSByZWYkMVsyXTtcbiAgICByZXR1cm4gW3IsIGcsIGIsIGFyZ3MubGVuZ3RoID4gMyA/IGFyZ3NbM10gOiAxXTtcbiAgfTtcblxuICB2YXIgbGNoMnJnYl8xID0gbGNoMnJnYjtcbiAgdmFyIHVucGFjayRyID0gdXRpbHMudW5wYWNrO1xuXG4gIHZhciBoY2wycmdiID0gZnVuY3Rpb24gaGNsMnJnYigpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICB2YXIgaGNsID0gdW5wYWNrJHIoYXJncywgJ2hjbCcpLnJldmVyc2UoKTtcbiAgICByZXR1cm4gbGNoMnJnYl8xLmFwcGx5KHZvaWQgMCwgaGNsKTtcbiAgfTtcblxuICB2YXIgaGNsMnJnYl8xID0gaGNsMnJnYjtcbiAgdmFyIHVucGFjayRzID0gdXRpbHMudW5wYWNrO1xuICB2YXIgdHlwZSRhID0gdXRpbHMudHlwZTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5sY2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHJnYjJsY2hfMSh0aGlzLl9yZ2IpO1xuICB9O1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmhjbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcmdiMmxjaF8xKHRoaXMuX3JnYikucmV2ZXJzZSgpO1xuICB9O1xuXG4gIGNocm9tYV8xLmxjaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShDb2xvcl8xLCBbbnVsbF0uY29uY2F0KGFyZ3MsIFsnbGNoJ10pKSkoKTtcbiAgfTtcblxuICBjaHJvbWFfMS5oY2wgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyAoRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuYXBwbHkoQ29sb3JfMSwgW251bGxdLmNvbmNhdChhcmdzLCBbJ2hjbCddKSkpKCk7XG4gIH07XG5cbiAgaW5wdXQuZm9ybWF0LmxjaCA9IGxjaDJyZ2JfMTtcbiAgaW5wdXQuZm9ybWF0LmhjbCA9IGhjbDJyZ2JfMTtcbiAgWydsY2gnLCAnaGNsJ10uZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgIHJldHVybiBpbnB1dC5hdXRvZGV0ZWN0LnB1c2goe1xuICAgICAgcDogMixcbiAgICAgIHRlc3Q6IGZ1bmN0aW9uIHRlc3QoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgICAgICB9XG5cbiAgICAgICAgYXJncyA9IHVucGFjayRzKGFyZ3MsIG0pO1xuXG4gICAgICAgIGlmICh0eXBlJGEoYXJncykgPT09ICdhcnJheScgJiYgYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbiAgLyoqXG4gIFx0WDExIGNvbG9yIG5hbWVzXG4gICBcdGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtY29sb3IvI3N2Zy1jb2xvclxuICAqL1xuXG4gIHZhciB3M2N4MTEgPSB7XG4gICAgYWxpY2VibHVlOiAnI2YwZjhmZicsXG4gICAgYW50aXF1ZXdoaXRlOiAnI2ZhZWJkNycsXG4gICAgYXF1YTogJyMwMGZmZmYnLFxuICAgIGFxdWFtYXJpbmU6ICcjN2ZmZmQ0JyxcbiAgICBhenVyZTogJyNmMGZmZmYnLFxuICAgIGJlaWdlOiAnI2Y1ZjVkYycsXG4gICAgYmlzcXVlOiAnI2ZmZTRjNCcsXG4gICAgYmxhY2s6ICcjMDAwMDAwJyxcbiAgICBibGFuY2hlZGFsbW9uZDogJyNmZmViY2QnLFxuICAgIGJsdWU6ICcjMDAwMGZmJyxcbiAgICBibHVldmlvbGV0OiAnIzhhMmJlMicsXG4gICAgYnJvd246ICcjYTUyYTJhJyxcbiAgICBidXJseXdvb2Q6ICcjZGViODg3JyxcbiAgICBjYWRldGJsdWU6ICcjNWY5ZWEwJyxcbiAgICBjaGFydHJldXNlOiAnIzdmZmYwMCcsXG4gICAgY2hvY29sYXRlOiAnI2QyNjkxZScsXG4gICAgY29yYWw6ICcjZmY3ZjUwJyxcbiAgICBjb3JuZmxvd2VyOiAnIzY0OTVlZCcsXG4gICAgY29ybmZsb3dlcmJsdWU6ICcjNjQ5NWVkJyxcbiAgICBjb3Juc2lsazogJyNmZmY4ZGMnLFxuICAgIGNyaW1zb246ICcjZGMxNDNjJyxcbiAgICBjeWFuOiAnIzAwZmZmZicsXG4gICAgZGFya2JsdWU6ICcjMDAwMDhiJyxcbiAgICBkYXJrY3lhbjogJyMwMDhiOGInLFxuICAgIGRhcmtnb2xkZW5yb2Q6ICcjYjg4NjBiJyxcbiAgICBkYXJrZ3JheTogJyNhOWE5YTknLFxuICAgIGRhcmtncmVlbjogJyMwMDY0MDAnLFxuICAgIGRhcmtncmV5OiAnI2E5YTlhOScsXG4gICAgZGFya2toYWtpOiAnI2JkYjc2YicsXG4gICAgZGFya21hZ2VudGE6ICcjOGIwMDhiJyxcbiAgICBkYXJrb2xpdmVncmVlbjogJyM1NTZiMmYnLFxuICAgIGRhcmtvcmFuZ2U6ICcjZmY4YzAwJyxcbiAgICBkYXJrb3JjaGlkOiAnIzk5MzJjYycsXG4gICAgZGFya3JlZDogJyM4YjAwMDAnLFxuICAgIGRhcmtzYWxtb246ICcjZTk5NjdhJyxcbiAgICBkYXJrc2VhZ3JlZW46ICcjOGZiYzhmJyxcbiAgICBkYXJrc2xhdGVibHVlOiAnIzQ4M2Q4YicsXG4gICAgZGFya3NsYXRlZ3JheTogJyMyZjRmNGYnLFxuICAgIGRhcmtzbGF0ZWdyZXk6ICcjMmY0ZjRmJyxcbiAgICBkYXJrdHVycXVvaXNlOiAnIzAwY2VkMScsXG4gICAgZGFya3Zpb2xldDogJyM5NDAwZDMnLFxuICAgIGRlZXBwaW5rOiAnI2ZmMTQ5MycsXG4gICAgZGVlcHNreWJsdWU6ICcjMDBiZmZmJyxcbiAgICBkaW1ncmF5OiAnIzY5Njk2OScsXG4gICAgZGltZ3JleTogJyM2OTY5NjknLFxuICAgIGRvZGdlcmJsdWU6ICcjMWU5MGZmJyxcbiAgICBmaXJlYnJpY2s6ICcjYjIyMjIyJyxcbiAgICBmbG9yYWx3aGl0ZTogJyNmZmZhZjAnLFxuICAgIGZvcmVzdGdyZWVuOiAnIzIyOGIyMicsXG4gICAgZnVjaHNpYTogJyNmZjAwZmYnLFxuICAgIGdhaW5zYm9ybzogJyNkY2RjZGMnLFxuICAgIGdob3N0d2hpdGU6ICcjZjhmOGZmJyxcbiAgICBnb2xkOiAnI2ZmZDcwMCcsXG4gICAgZ29sZGVucm9kOiAnI2RhYTUyMCcsXG4gICAgZ3JheTogJyM4MDgwODAnLFxuICAgIGdyZWVuOiAnIzAwODAwMCcsXG4gICAgZ3JlZW55ZWxsb3c6ICcjYWRmZjJmJyxcbiAgICBncmV5OiAnIzgwODA4MCcsXG4gICAgaG9uZXlkZXc6ICcjZjBmZmYwJyxcbiAgICBob3RwaW5rOiAnI2ZmNjliNCcsXG4gICAgaW5kaWFucmVkOiAnI2NkNWM1YycsXG4gICAgaW5kaWdvOiAnIzRiMDA4MicsXG4gICAgaXZvcnk6ICcjZmZmZmYwJyxcbiAgICBraGFraTogJyNmMGU2OGMnLFxuICAgIGxhc2VybGVtb246ICcjZmZmZjU0JyxcbiAgICBsYXZlbmRlcjogJyNlNmU2ZmEnLFxuICAgIGxhdmVuZGVyYmx1c2g6ICcjZmZmMGY1JyxcbiAgICBsYXduZ3JlZW46ICcjN2NmYzAwJyxcbiAgICBsZW1vbmNoaWZmb246ICcjZmZmYWNkJyxcbiAgICBsaWdodGJsdWU6ICcjYWRkOGU2JyxcbiAgICBsaWdodGNvcmFsOiAnI2YwODA4MCcsXG4gICAgbGlnaHRjeWFuOiAnI2UwZmZmZicsXG4gICAgbGlnaHRnb2xkZW5yb2Q6ICcjZmFmYWQyJyxcbiAgICBsaWdodGdvbGRlbnJvZHllbGxvdzogJyNmYWZhZDInLFxuICAgIGxpZ2h0Z3JheTogJyNkM2QzZDMnLFxuICAgIGxpZ2h0Z3JlZW46ICcjOTBlZTkwJyxcbiAgICBsaWdodGdyZXk6ICcjZDNkM2QzJyxcbiAgICBsaWdodHBpbms6ICcjZmZiNmMxJyxcbiAgICBsaWdodHNhbG1vbjogJyNmZmEwN2EnLFxuICAgIGxpZ2h0c2VhZ3JlZW46ICcjMjBiMmFhJyxcbiAgICBsaWdodHNreWJsdWU6ICcjODdjZWZhJyxcbiAgICBsaWdodHNsYXRlZ3JheTogJyM3Nzg4OTknLFxuICAgIGxpZ2h0c2xhdGVncmV5OiAnIzc3ODg5OScsXG4gICAgbGlnaHRzdGVlbGJsdWU6ICcjYjBjNGRlJyxcbiAgICBsaWdodHllbGxvdzogJyNmZmZmZTAnLFxuICAgIGxpbWU6ICcjMDBmZjAwJyxcbiAgICBsaW1lZ3JlZW46ICcjMzJjZDMyJyxcbiAgICBsaW5lbjogJyNmYWYwZTYnLFxuICAgIG1hZ2VudGE6ICcjZmYwMGZmJyxcbiAgICBtYXJvb246ICcjODAwMDAwJyxcbiAgICBtYXJvb24yOiAnIzdmMDAwMCcsXG4gICAgbWFyb29uMzogJyNiMDMwNjAnLFxuICAgIG1lZGl1bWFxdWFtYXJpbmU6ICcjNjZjZGFhJyxcbiAgICBtZWRpdW1ibHVlOiAnIzAwMDBjZCcsXG4gICAgbWVkaXVtb3JjaGlkOiAnI2JhNTVkMycsXG4gICAgbWVkaXVtcHVycGxlOiAnIzkzNzBkYicsXG4gICAgbWVkaXVtc2VhZ3JlZW46ICcjM2NiMzcxJyxcbiAgICBtZWRpdW1zbGF0ZWJsdWU6ICcjN2I2OGVlJyxcbiAgICBtZWRpdW1zcHJpbmdncmVlbjogJyMwMGZhOWEnLFxuICAgIG1lZGl1bXR1cnF1b2lzZTogJyM0OGQxY2MnLFxuICAgIG1lZGl1bXZpb2xldHJlZDogJyNjNzE1ODUnLFxuICAgIG1pZG5pZ2h0Ymx1ZTogJyMxOTE5NzAnLFxuICAgIG1pbnRjcmVhbTogJyNmNWZmZmEnLFxuICAgIG1pc3R5cm9zZTogJyNmZmU0ZTEnLFxuICAgIG1vY2Nhc2luOiAnI2ZmZTRiNScsXG4gICAgbmF2YWpvd2hpdGU6ICcjZmZkZWFkJyxcbiAgICBuYXZ5OiAnIzAwMDA4MCcsXG4gICAgb2xkbGFjZTogJyNmZGY1ZTYnLFxuICAgIG9saXZlOiAnIzgwODAwMCcsXG4gICAgb2xpdmVkcmFiOiAnIzZiOGUyMycsXG4gICAgb3JhbmdlOiAnI2ZmYTUwMCcsXG4gICAgb3JhbmdlcmVkOiAnI2ZmNDUwMCcsXG4gICAgb3JjaGlkOiAnI2RhNzBkNicsXG4gICAgcGFsZWdvbGRlbnJvZDogJyNlZWU4YWEnLFxuICAgIHBhbGVncmVlbjogJyM5OGZiOTgnLFxuICAgIHBhbGV0dXJxdW9pc2U6ICcjYWZlZWVlJyxcbiAgICBwYWxldmlvbGV0cmVkOiAnI2RiNzA5MycsXG4gICAgcGFwYXlhd2hpcDogJyNmZmVmZDUnLFxuICAgIHBlYWNocHVmZjogJyNmZmRhYjknLFxuICAgIHBlcnU6ICcjY2Q4NTNmJyxcbiAgICBwaW5rOiAnI2ZmYzBjYicsXG4gICAgcGx1bTogJyNkZGEwZGQnLFxuICAgIHBvd2RlcmJsdWU6ICcjYjBlMGU2JyxcbiAgICBwdXJwbGU6ICcjODAwMDgwJyxcbiAgICBwdXJwbGUyOiAnIzdmMDA3ZicsXG4gICAgcHVycGxlMzogJyNhMDIwZjAnLFxuICAgIHJlYmVjY2FwdXJwbGU6ICcjNjYzMzk5JyxcbiAgICByZWQ6ICcjZmYwMDAwJyxcbiAgICByb3N5YnJvd246ICcjYmM4ZjhmJyxcbiAgICByb3lhbGJsdWU6ICcjNDE2OWUxJyxcbiAgICBzYWRkbGVicm93bjogJyM4YjQ1MTMnLFxuICAgIHNhbG1vbjogJyNmYTgwNzInLFxuICAgIHNhbmR5YnJvd246ICcjZjRhNDYwJyxcbiAgICBzZWFncmVlbjogJyMyZThiNTcnLFxuICAgIHNlYXNoZWxsOiAnI2ZmZjVlZScsXG4gICAgc2llbm5hOiAnI2EwNTIyZCcsXG4gICAgc2lsdmVyOiAnI2MwYzBjMCcsXG4gICAgc2t5Ymx1ZTogJyM4N2NlZWInLFxuICAgIHNsYXRlYmx1ZTogJyM2YTVhY2QnLFxuICAgIHNsYXRlZ3JheTogJyM3MDgwOTAnLFxuICAgIHNsYXRlZ3JleTogJyM3MDgwOTAnLFxuICAgIHNub3c6ICcjZmZmYWZhJyxcbiAgICBzcHJpbmdncmVlbjogJyMwMGZmN2YnLFxuICAgIHN0ZWVsYmx1ZTogJyM0NjgyYjQnLFxuICAgIHRhbjogJyNkMmI0OGMnLFxuICAgIHRlYWw6ICcjMDA4MDgwJyxcbiAgICB0aGlzdGxlOiAnI2Q4YmZkOCcsXG4gICAgdG9tYXRvOiAnI2ZmNjM0NycsXG4gICAgdHVycXVvaXNlOiAnIzQwZTBkMCcsXG4gICAgdmlvbGV0OiAnI2VlODJlZScsXG4gICAgd2hlYXQ6ICcjZjVkZWIzJyxcbiAgICB3aGl0ZTogJyNmZmZmZmYnLFxuICAgIHdoaXRlc21va2U6ICcjZjVmNWY1JyxcbiAgICB5ZWxsb3c6ICcjZmZmZjAwJyxcbiAgICB5ZWxsb3dncmVlbjogJyM5YWNkMzInXG4gIH07XG4gIHZhciB3M2N4MTFfMSA9IHczY3gxMTtcbiAgdmFyIHR5cGUkYiA9IHV0aWxzLnR5cGU7XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUubmFtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGV4ID0gcmdiMmhleF8xKHRoaXMuX3JnYiwgJ3JnYicpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxpc3QgPSBPYmplY3Qua2V5cyh3M2N4MTFfMSk7IGkgPCBsaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2YXIgbiA9IGxpc3RbaV07XG5cbiAgICAgIGlmICh3M2N4MTFfMVtuXSA9PT0gaGV4KSB7XG4gICAgICAgIHJldHVybiBuLnRvTG93ZXJDYXNlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhleDtcbiAgfTtcblxuICBpbnB1dC5mb3JtYXQubmFtZWQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAodzNjeDExXzFbbmFtZV0pIHtcbiAgICAgIHJldHVybiBoZXgycmdiXzEodzNjeDExXzFbbmFtZV0pO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBjb2xvciBuYW1lOiAnICsgbmFtZSk7XG4gIH07XG5cbiAgaW5wdXQuYXV0b2RldGVjdC5wdXNoKHtcbiAgICBwOiA1LFxuICAgIHRlc3Q6IGZ1bmN0aW9uIHRlc3QoaCkge1xuICAgICAgdmFyIHJlc3QgPSBbXSxcbiAgICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoIC0gMTtcblxuICAgICAgd2hpbGUgKGxlbi0tID4gMCkge1xuICAgICAgICByZXN0W2xlbl0gPSBhcmd1bWVudHNbbGVuICsgMV07XG4gICAgICB9XG5cbiAgICAgIGlmICghcmVzdC5sZW5ndGggJiYgdHlwZSRiKGgpID09PSAnc3RyaW5nJyAmJiB3M2N4MTFfMVtoLnRvTG93ZXJDYXNlKCldKSB7XG4gICAgICAgIHJldHVybiAnbmFtZWQnO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHZhciB1bnBhY2skdCA9IHV0aWxzLnVucGFjaztcblxuICB2YXIgcmdiMm51bSA9IGZ1bmN0aW9uIHJnYjJudW0oKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJlZiA9IHVucGFjayR0KGFyZ3MsICdyZ2InKTtcbiAgICB2YXIgciA9IHJlZlswXTtcbiAgICB2YXIgZyA9IHJlZlsxXTtcbiAgICB2YXIgYiA9IHJlZlsyXTtcbiAgICByZXR1cm4gKHIgPDwgMTYpICsgKGcgPDwgOCkgKyBiO1xuICB9O1xuXG4gIHZhciByZ2IybnVtXzEgPSByZ2IybnVtO1xuICB2YXIgdHlwZSRjID0gdXRpbHMudHlwZTtcblxuICB2YXIgbnVtMnJnYiA9IGZ1bmN0aW9uIG51bTJyZ2IobnVtKSB7XG4gICAgaWYgKHR5cGUkYyhudW0pID09IFwibnVtYmVyXCIgJiYgbnVtID49IDAgJiYgbnVtIDw9IDB4RkZGRkZGKSB7XG4gICAgICB2YXIgciA9IG51bSA+PiAxNjtcbiAgICAgIHZhciBnID0gbnVtID4+IDggJiAweEZGO1xuICAgICAgdmFyIGIgPSBudW0gJiAweEZGO1xuICAgICAgcmV0dXJuIFtyLCBnLCBiLCAxXTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIG51bSBjb2xvcjogXCIgKyBudW0pO1xuICB9O1xuXG4gIHZhciBudW0ycmdiXzEgPSBudW0ycmdiO1xuICB2YXIgdHlwZSRkID0gdXRpbHMudHlwZTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5udW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHJnYjJudW1fMSh0aGlzLl9yZ2IpO1xuICB9O1xuXG4gIGNocm9tYV8xLm51bSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShDb2xvcl8xLCBbbnVsbF0uY29uY2F0KGFyZ3MsIFsnbnVtJ10pKSkoKTtcbiAgfTtcblxuICBpbnB1dC5mb3JtYXQubnVtID0gbnVtMnJnYl8xO1xuICBpbnB1dC5hdXRvZGV0ZWN0LnB1c2goe1xuICAgIHA6IDUsXG4gICAgdGVzdDogZnVuY3Rpb24gdGVzdCgpIHtcbiAgICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgdHlwZSRkKGFyZ3NbMF0pID09PSAnbnVtYmVyJyAmJiBhcmdzWzBdID49IDAgJiYgYXJnc1swXSA8PSAweEZGRkZGRikge1xuICAgICAgICByZXR1cm4gJ251bSc7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgdmFyIHVucGFjayR1ID0gdXRpbHMudW5wYWNrO1xuICB2YXIgdHlwZSRlID0gdXRpbHMudHlwZTtcbiAgdmFyIHJvdW5kJDUgPSBNYXRoLnJvdW5kO1xuXG4gIENvbG9yXzEucHJvdG90eXBlLnJnYiA9IGZ1bmN0aW9uIChybmQpIHtcbiAgICBpZiAocm5kID09PSB2b2lkIDApIHJuZCA9IHRydWU7XG5cbiAgICBpZiAocm5kID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JnYi5zbGljZSgwLCAzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fcmdiLnNsaWNlKDAsIDMpLm1hcChyb3VuZCQ1KTtcbiAgfTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5yZ2JhID0gZnVuY3Rpb24gKHJuZCkge1xuICAgIGlmIChybmQgPT09IHZvaWQgMCkgcm5kID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5fcmdiLnNsaWNlKDAsIDQpLm1hcChmdW5jdGlvbiAodiwgaSkge1xuICAgICAgcmV0dXJuIGkgPCAzID8gcm5kID09PSBmYWxzZSA/IHYgOiByb3VuZCQ1KHYpIDogdjtcbiAgICB9KTtcbiAgfTtcblxuICBjaHJvbWFfMS5yZ2IgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyAoRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuYXBwbHkoQ29sb3JfMSwgW251bGxdLmNvbmNhdChhcmdzLCBbJ3JnYiddKSkpKCk7XG4gIH07XG5cbiAgaW5wdXQuZm9ybWF0LnJnYiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYXJncyA9IFtdLFxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICBhcmdzW2xlbl0gPSBhcmd1bWVudHNbbGVuXTtcbiAgICB9XG5cbiAgICB2YXIgcmdiYSA9IHVucGFjayR1KGFyZ3MsICdyZ2JhJyk7XG5cbiAgICBpZiAocmdiYVszXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZ2JhWzNdID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmdiYTtcbiAgfTtcblxuICBpbnB1dC5hdXRvZGV0ZWN0LnB1c2goe1xuICAgIHA6IDMsXG4gICAgdGVzdDogZnVuY3Rpb24gdGVzdCgpIHtcbiAgICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgICAgfVxuXG4gICAgICBhcmdzID0gdW5wYWNrJHUoYXJncywgJ3JnYmEnKTtcblxuICAgICAgaWYgKHR5cGUkZShhcmdzKSA9PT0gJ2FycmF5JyAmJiAoYXJncy5sZW5ndGggPT09IDMgfHwgYXJncy5sZW5ndGggPT09IDQgJiYgdHlwZSRlKGFyZ3NbM10pID09ICdudW1iZXInICYmIGFyZ3NbM10gPj0gMCAmJiBhcmdzWzNdIDw9IDEpKSB7XG4gICAgICAgIHJldHVybiAncmdiJztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAvKlxuICAgKiBCYXNlZCBvbiBpbXBsZW1lbnRhdGlvbiBieSBOZWlsIEJhcnRsZXR0XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWlsYmFydGxldHQvY29sb3ItdGVtcGVyYXR1cmVcbiAgICovXG5cbiAgdmFyIGxvZyA9IE1hdGgubG9nO1xuXG4gIHZhciB0ZW1wZXJhdHVyZTJyZ2IgPSBmdW5jdGlvbiB0ZW1wZXJhdHVyZTJyZ2Ioa2VsdmluKSB7XG4gICAgdmFyIHRlbXAgPSBrZWx2aW4gLyAxMDA7XG4gICAgdmFyIHIsIGcsIGI7XG5cbiAgICBpZiAodGVtcCA8IDY2KSB7XG4gICAgICByID0gMjU1O1xuICAgICAgZyA9IC0xNTUuMjU0ODU1NjI3MDkxNzkgLSAwLjQ0NTk2OTUwNDY5NTc5MTMzICogKGcgPSB0ZW1wIC0gMikgKyAxMDQuNDkyMTYxOTkzOTM4ODggKiBsb2coZyk7XG4gICAgICBiID0gdGVtcCA8IDIwID8gMCA6IC0yNTQuNzY5MzUxODQxMjA5MDIgKyAwLjgyNzQwOTYwNjQwMDczOTUgKiAoYiA9IHRlbXAgLSAxMCkgKyAxMTUuNjc5OTQ0MDEwNjYxNDcgKiBsb2coYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHIgPSAzNTEuOTc2OTA1NjY4MDU2OTMgKyAwLjExNDIwNjQ1Mzc4NDE2NSAqIChyID0gdGVtcCAtIDU1KSAtIDQwLjI1MzY2MzA5MzMyMTI3ICogbG9nKHIpO1xuICAgICAgZyA9IDMyNS40NDk0MTI1NzExOTc0ICsgMC4wNzk0MzQ1NjUzNjY2MjM0MiAqIChnID0gdGVtcCAtIDUwKSAtIDI4LjA4NTI5NjM1MDc5NTcgKiBsb2coZyk7XG4gICAgICBiID0gMjU1O1xuICAgIH1cblxuICAgIHJldHVybiBbciwgZywgYiwgMV07XG4gIH07XG5cbiAgdmFyIHRlbXBlcmF0dXJlMnJnYl8xID0gdGVtcGVyYXR1cmUycmdiO1xuICAvKlxuICAgKiBCYXNlZCBvbiBpbXBsZW1lbnRhdGlvbiBieSBOZWlsIEJhcnRsZXR0XG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWlsYmFydGxldHQvY29sb3ItdGVtcGVyYXR1cmVcbiAgICoqL1xuXG4gIHZhciB1bnBhY2skdiA9IHV0aWxzLnVucGFjaztcbiAgdmFyIHJvdW5kJDYgPSBNYXRoLnJvdW5kO1xuXG4gIHZhciByZ2IydGVtcGVyYXR1cmUgPSBmdW5jdGlvbiByZ2IydGVtcGVyYXR1cmUoKSB7XG4gICAgdmFyIGFyZ3MgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgYXJnc1tsZW5dID0gYXJndW1lbnRzW2xlbl07XG4gICAgfVxuXG4gICAgdmFyIHJnYiA9IHVucGFjayR2KGFyZ3MsICdyZ2InKTtcbiAgICB2YXIgciA9IHJnYlswXSxcbiAgICAgICAgYiA9IHJnYlsyXTtcbiAgICB2YXIgbWluVGVtcCA9IDEwMDA7XG4gICAgdmFyIG1heFRlbXAgPSA0MDAwMDtcbiAgICB2YXIgZXBzID0gMC40O1xuICAgIHZhciB0ZW1wO1xuXG4gICAgd2hpbGUgKG1heFRlbXAgLSBtaW5UZW1wID4gZXBzKSB7XG4gICAgICB0ZW1wID0gKG1heFRlbXAgKyBtaW5UZW1wKSAqIDAuNTtcbiAgICAgIHZhciByZ2IkMSA9IHRlbXBlcmF0dXJlMnJnYl8xKHRlbXApO1xuXG4gICAgICBpZiAocmdiJDFbMl0gLyByZ2IkMVswXSA+PSBiIC8gcikge1xuICAgICAgICBtYXhUZW1wID0gdGVtcDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pblRlbXAgPSB0ZW1wO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByb3VuZCQ2KHRlbXApO1xuICB9O1xuXG4gIHZhciByZ2IydGVtcGVyYXR1cmVfMSA9IHJnYjJ0ZW1wZXJhdHVyZTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS50ZW1wID0gQ29sb3JfMS5wcm90b3R5cGUua2VsdmluID0gQ29sb3JfMS5wcm90b3R5cGUudGVtcGVyYXR1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHJnYjJ0ZW1wZXJhdHVyZV8xKHRoaXMuX3JnYik7XG4gIH07XG5cbiAgY2hyb21hXzEudGVtcCA9IGNocm9tYV8xLmtlbHZpbiA9IGNocm9tYV8xLnRlbXBlcmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncywgWyd0ZW1wJ10pKSkoKTtcbiAgfTtcblxuICBpbnB1dC5mb3JtYXQudGVtcCA9IGlucHV0LmZvcm1hdC5rZWx2aW4gPSBpbnB1dC5mb3JtYXQudGVtcGVyYXR1cmUgPSB0ZW1wZXJhdHVyZTJyZ2JfMTtcbiAgdmFyIHR5cGUkZiA9IHV0aWxzLnR5cGU7XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuYWxwaGEgPSBmdW5jdGlvbiAoYSwgbXV0YXRlKSB7XG4gICAgaWYgKG11dGF0ZSA9PT0gdm9pZCAwKSBtdXRhdGUgPSBmYWxzZTtcblxuICAgIGlmIChhICE9PSB1bmRlZmluZWQgJiYgdHlwZSRmKGEpID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKG11dGF0ZSkge1xuICAgICAgICB0aGlzLl9yZ2JbM10gPSBhO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBDb2xvcl8xKFt0aGlzLl9yZ2JbMF0sIHRoaXMuX3JnYlsxXSwgdGhpcy5fcmdiWzJdLCBhXSwgJ3JnYicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9yZ2JbM107XG4gIH07XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuY2xpcHBlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmdiLl9jbGlwcGVkIHx8IGZhbHNlO1xuICB9O1xuXG4gIENvbG9yXzEucHJvdG90eXBlLmRhcmtlbiA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICBpZiAoYW1vdW50ID09PSB2b2lkIDApIGFtb3VudCA9IDE7XG4gICAgdmFyIG1lID0gdGhpcztcbiAgICB2YXIgbGFiID0gbWUubGFiKCk7XG4gICAgbGFiWzBdIC09IGxhYkNvbnN0YW50cy5LbiAqIGFtb3VudDtcbiAgICByZXR1cm4gbmV3IENvbG9yXzEobGFiLCAnbGFiJykuYWxwaGEobWUuYWxwaGEoKSwgdHJ1ZSk7XG4gIH07XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuYnJpZ2h0ZW4gPSBmdW5jdGlvbiAoYW1vdW50KSB7XG4gICAgaWYgKGFtb3VudCA9PT0gdm9pZCAwKSBhbW91bnQgPSAxO1xuICAgIHJldHVybiB0aGlzLmRhcmtlbigtYW1vdW50KTtcbiAgfTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5kYXJrZXIgPSBDb2xvcl8xLnByb3RvdHlwZS5kYXJrZW47XG4gIENvbG9yXzEucHJvdG90eXBlLmJyaWdodGVyID0gQ29sb3JfMS5wcm90b3R5cGUuYnJpZ2h0ZW47XG5cbiAgQ29sb3JfMS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG1jKSB7XG4gICAgdmFyIHJlZiA9IG1jLnNwbGl0KCcuJyk7XG4gICAgdmFyIG1vZGUgPSByZWZbMF07XG4gICAgdmFyIGNoYW5uZWwgPSByZWZbMV07XG4gICAgdmFyIHNyYyA9IHRoaXNbbW9kZV0oKTtcblxuICAgIGlmIChjaGFubmVsKSB7XG4gICAgICB2YXIgaSA9IG1vZGUuaW5kZXhPZihjaGFubmVsKTtcblxuICAgICAgaWYgKGkgPiAtMSkge1xuICAgICAgICByZXR1cm4gc3JjW2ldO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bmtub3duIGNoYW5uZWwgXCIgKyBjaGFubmVsICsgXCIgaW4gbW9kZSBcIiArIG1vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3JjO1xuICAgIH1cbiAgfTtcblxuICB2YXIgdHlwZSRnID0gdXRpbHMudHlwZTtcbiAgdmFyIHBvdyQyID0gTWF0aC5wb3c7XG4gIHZhciBFUFMgPSAxZS03O1xuICB2YXIgTUFYX0lURVIgPSAyMDtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5sdW1pbmFuY2UgPSBmdW5jdGlvbiAobHVtKSB7XG4gICAgaWYgKGx1bSAhPT0gdW5kZWZpbmVkICYmIHR5cGUkZyhsdW0pID09PSAnbnVtYmVyJykge1xuICAgICAgaWYgKGx1bSA9PT0gMCkge1xuICAgICAgICAvLyByZXR1cm4gcHVyZSBibGFja1xuICAgICAgICByZXR1cm4gbmV3IENvbG9yXzEoWzAsIDAsIDAsIHRoaXMuX3JnYlszXV0sICdyZ2InKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGx1bSA9PT0gMSkge1xuICAgICAgICAvLyByZXR1cm4gcHVyZSB3aGl0ZVxuICAgICAgICByZXR1cm4gbmV3IENvbG9yXzEoWzI1NSwgMjU1LCAyNTUsIHRoaXMuX3JnYlszXV0sICdyZ2InKTtcbiAgICAgIH0gLy8gY29tcHV0ZSBuZXcgY29sb3IgdXNpbmcuLi5cblxuXG4gICAgICB2YXIgY3VyX2x1bSA9IHRoaXMubHVtaW5hbmNlKCk7XG4gICAgICB2YXIgbW9kZSA9ICdyZ2InO1xuICAgICAgdmFyIG1heF9pdGVyID0gTUFYX0lURVI7XG5cbiAgICAgIHZhciB0ZXN0ID0gZnVuY3Rpb24gdGVzdChsb3csIGhpZ2gpIHtcbiAgICAgICAgdmFyIG1pZCA9IGxvdy5pbnRlcnBvbGF0ZShoaWdoLCAwLjUsIG1vZGUpO1xuICAgICAgICB2YXIgbG0gPSBtaWQubHVtaW5hbmNlKCk7XG5cbiAgICAgICAgaWYgKE1hdGguYWJzKGx1bSAtIGxtKSA8IEVQUyB8fCAhbWF4X2l0ZXItLSkge1xuICAgICAgICAgIC8vIGNsb3NlIGVub3VnaFxuICAgICAgICAgIHJldHVybiBtaWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbG0gPiBsdW0gPyB0ZXN0KGxvdywgbWlkKSA6IHRlc3QobWlkLCBoaWdoKTtcbiAgICAgIH07XG5cbiAgICAgIHZhciByZ2IgPSAoY3VyX2x1bSA+IGx1bSA/IHRlc3QobmV3IENvbG9yXzEoWzAsIDAsIDBdKSwgdGhpcykgOiB0ZXN0KHRoaXMsIG5ldyBDb2xvcl8xKFsyNTUsIDI1NSwgMjU1XSkpKS5yZ2IoKTtcbiAgICAgIHJldHVybiBuZXcgQ29sb3JfMShyZ2IuY29uY2F0KFt0aGlzLl9yZ2JbM11dKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJnYjJsdW1pbmFuY2UuYXBwbHkodm9pZCAwLCB0aGlzLl9yZ2Iuc2xpY2UoMCwgMykpO1xuICB9O1xuXG4gIHZhciByZ2IybHVtaW5hbmNlID0gZnVuY3Rpb24gcmdiMmx1bWluYW5jZShyLCBnLCBiKSB7XG4gICAgLy8gcmVsYXRpdmUgbHVtaW5hbmNlXG4gICAgLy8gc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDgvUkVDLVdDQUcyMC0yMDA4MTIxMS8jcmVsYXRpdmVsdW1pbmFuY2VkZWZcbiAgICByID0gbHVtaW5hbmNlX3gocik7XG4gICAgZyA9IGx1bWluYW5jZV94KGcpO1xuICAgIGIgPSBsdW1pbmFuY2VfeChiKTtcbiAgICByZXR1cm4gMC4yMTI2ICogciArIDAuNzE1MiAqIGcgKyAwLjA3MjIgKiBiO1xuICB9O1xuXG4gIHZhciBsdW1pbmFuY2VfeCA9IGZ1bmN0aW9uIGx1bWluYW5jZV94KHgpIHtcbiAgICB4IC89IDI1NTtcbiAgICByZXR1cm4geCA8PSAwLjAzOTI4ID8geCAvIDEyLjkyIDogcG93JDIoKHggKyAwLjA1NSkgLyAxLjA1NSwgMi40KTtcbiAgfTtcblxuICB2YXIgaW50ZXJwb2xhdG9yID0ge307XG4gIHZhciB0eXBlJGggPSB1dGlscy50eXBlO1xuXG4gIHZhciBtaXggPSBmdW5jdGlvbiBtaXgoY29sMSwgY29sMiwgZikge1xuICAgIGlmIChmID09PSB2b2lkIDApIGYgPSAwLjU7XG4gICAgdmFyIHJlc3QgPSBbXSxcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aCAtIDM7XG5cbiAgICB3aGlsZSAobGVuLS0gPiAwKSB7XG4gICAgICByZXN0W2xlbl0gPSBhcmd1bWVudHNbbGVuICsgM107XG4gICAgfVxuXG4gICAgdmFyIG1vZGUgPSByZXN0WzBdIHx8ICdscmdiJztcblxuICAgIGlmICghaW50ZXJwb2xhdG9yW21vZGVdICYmICFyZXN0Lmxlbmd0aCkge1xuICAgICAgLy8gZmFsbCBiYWNrIHRvIHRoZSBmaXJzdCBzdXBwb3J0ZWQgbW9kZVxuICAgICAgbW9kZSA9IE9iamVjdC5rZXlzKGludGVycG9sYXRvcilbMF07XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnBvbGF0b3JbbW9kZV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImludGVycG9sYXRpb24gbW9kZSBcIiArIG1vZGUgKyBcIiBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZSRoKGNvbDEpICE9PSAnb2JqZWN0Jykge1xuICAgICAgY29sMSA9IG5ldyBDb2xvcl8xKGNvbDEpO1xuICAgIH1cblxuICAgIGlmICh0eXBlJGgoY29sMikgIT09ICdvYmplY3QnKSB7XG4gICAgICBjb2wyID0gbmV3IENvbG9yXzEoY29sMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVycG9sYXRvclttb2RlXShjb2wxLCBjb2wyLCBmKS5hbHBoYShjb2wxLmFscGhhKCkgKyBmICogKGNvbDIuYWxwaGEoKSAtIGNvbDEuYWxwaGEoKSkpO1xuICB9O1xuXG4gIENvbG9yXzEucHJvdG90eXBlLm1peCA9IENvbG9yXzEucHJvdG90eXBlLmludGVycG9sYXRlID0gZnVuY3Rpb24gKGNvbDIsIGYpIHtcbiAgICBpZiAoZiA9PT0gdm9pZCAwKSBmID0gMC41O1xuICAgIHZhciByZXN0ID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGggLSAyO1xuXG4gICAgd2hpbGUgKGxlbi0tID4gMCkge1xuICAgICAgcmVzdFtsZW5dID0gYXJndW1lbnRzW2xlbiArIDJdO1xuICAgIH1cblxuICAgIHJldHVybiBtaXguYXBwbHkodm9pZCAwLCBbdGhpcywgY29sMiwgZl0uY29uY2F0KHJlc3QpKTtcbiAgfTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5wcmVtdWx0aXBseSA9IGZ1bmN0aW9uIChtdXRhdGUpIHtcbiAgICBpZiAobXV0YXRlID09PSB2b2lkIDApIG11dGF0ZSA9IGZhbHNlO1xuICAgIHZhciByZ2IgPSB0aGlzLl9yZ2I7XG4gICAgdmFyIGEgPSByZ2JbM107XG5cbiAgICBpZiAobXV0YXRlKSB7XG4gICAgICB0aGlzLl9yZ2IgPSBbcmdiWzBdICogYSwgcmdiWzFdICogYSwgcmdiWzJdICogYSwgYV07XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG5ldyBDb2xvcl8xKFtyZ2JbMF0gKiBhLCByZ2JbMV0gKiBhLCByZ2JbMl0gKiBhLCBhXSwgJ3JnYicpO1xuICAgIH1cbiAgfTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5zYXR1cmF0ZSA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICBpZiAoYW1vdW50ID09PSB2b2lkIDApIGFtb3VudCA9IDE7XG4gICAgdmFyIG1lID0gdGhpcztcbiAgICB2YXIgbGNoID0gbWUubGNoKCk7XG4gICAgbGNoWzFdICs9IGxhYkNvbnN0YW50cy5LbiAqIGFtb3VudDtcblxuICAgIGlmIChsY2hbMV0gPCAwKSB7XG4gICAgICBsY2hbMV0gPSAwO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQ29sb3JfMShsY2gsICdsY2gnKS5hbHBoYShtZS5hbHBoYSgpLCB0cnVlKTtcbiAgfTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5kZXNhdHVyYXRlID0gZnVuY3Rpb24gKGFtb3VudCkge1xuICAgIGlmIChhbW91bnQgPT09IHZvaWQgMCkgYW1vdW50ID0gMTtcbiAgICByZXR1cm4gdGhpcy5zYXR1cmF0ZSgtYW1vdW50KTtcbiAgfTtcblxuICB2YXIgdHlwZSRpID0gdXRpbHMudHlwZTtcblxuICBDb2xvcl8xLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAobWMsIHZhbHVlLCBtdXRhdGUpIHtcbiAgICBpZiAobXV0YXRlID09PSB2b2lkIDApIG11dGF0ZSA9IGZhbHNlO1xuICAgIHZhciByZWYgPSBtYy5zcGxpdCgnLicpO1xuICAgIHZhciBtb2RlID0gcmVmWzBdO1xuICAgIHZhciBjaGFubmVsID0gcmVmWzFdO1xuICAgIHZhciBzcmMgPSB0aGlzW21vZGVdKCk7XG5cbiAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgdmFyIGkgPSBtb2RlLmluZGV4T2YoY2hhbm5lbCk7XG5cbiAgICAgIGlmIChpID4gLTEpIHtcbiAgICAgICAgaWYgKHR5cGUkaSh2YWx1ZSkgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBzd2l0Y2ggKHZhbHVlLmNoYXJBdCgwKSkge1xuICAgICAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgICAgICAgIHNyY1tpXSArPSArdmFsdWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICAgICAgc3JjW2ldICs9ICt2YWx1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJyonOlxuICAgICAgICAgICAgICBzcmNbaV0gKj0gK3ZhbHVlLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgJy8nOlxuICAgICAgICAgICAgICBzcmNbaV0gLz0gK3ZhbHVlLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHNyY1tpXSA9ICt2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSRpKHZhbHVlKSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBzcmNbaV0gPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnN1cHBvcnRlZCB2YWx1ZSBmb3IgQ29sb3Iuc2V0XCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG91dCA9IG5ldyBDb2xvcl8xKHNyYywgbW9kZSk7XG5cbiAgICAgICAgaWYgKG11dGF0ZSkge1xuICAgICAgICAgIHRoaXMuX3JnYiA9IG91dC5fcmdiO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biBjaGFubmVsIFwiICsgY2hhbm5lbCArIFwiIGluIG1vZGUgXCIgKyBtb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNyYztcbiAgICB9XG4gIH07XG5cbiAgdmFyIHJnYiQxID0gZnVuY3Rpb24gcmdiJDEoY29sMSwgY29sMiwgZikge1xuICAgIHZhciB4eXowID0gY29sMS5fcmdiO1xuICAgIHZhciB4eXoxID0gY29sMi5fcmdiO1xuICAgIHJldHVybiBuZXcgQ29sb3JfMSh4eXowWzBdICsgZiAqICh4eXoxWzBdIC0geHl6MFswXSksIHh5ejBbMV0gKyBmICogKHh5ejFbMV0gLSB4eXowWzFdKSwgeHl6MFsyXSArIGYgKiAoeHl6MVsyXSAtIHh5ejBbMl0pLCAncmdiJyk7XG4gIH07IC8vIHJlZ2lzdGVyIGludGVycG9sYXRvclxuXG5cbiAgaW50ZXJwb2xhdG9yLnJnYiA9IHJnYiQxO1xuICB2YXIgc3FydCQyID0gTWF0aC5zcXJ0O1xuICB2YXIgcG93JDMgPSBNYXRoLnBvdztcblxuICB2YXIgbHJnYiA9IGZ1bmN0aW9uIGxyZ2IoY29sMSwgY29sMiwgZikge1xuICAgIHZhciByZWYgPSBjb2wxLl9yZ2I7XG4gICAgdmFyIHgxID0gcmVmWzBdO1xuICAgIHZhciB5MSA9IHJlZlsxXTtcbiAgICB2YXIgejEgPSByZWZbMl07XG4gICAgdmFyIHJlZiQxID0gY29sMi5fcmdiO1xuICAgIHZhciB4MiA9IHJlZiQxWzBdO1xuICAgIHZhciB5MiA9IHJlZiQxWzFdO1xuICAgIHZhciB6MiA9IHJlZiQxWzJdO1xuICAgIHJldHVybiBuZXcgQ29sb3JfMShzcXJ0JDIocG93JDMoeDEsIDIpICogKDEgLSBmKSArIHBvdyQzKHgyLCAyKSAqIGYpLCBzcXJ0JDIocG93JDMoeTEsIDIpICogKDEgLSBmKSArIHBvdyQzKHkyLCAyKSAqIGYpLCBzcXJ0JDIocG93JDMoejEsIDIpICogKDEgLSBmKSArIHBvdyQzKHoyLCAyKSAqIGYpLCAncmdiJyk7XG4gIH07IC8vIHJlZ2lzdGVyIGludGVycG9sYXRvclxuXG5cbiAgaW50ZXJwb2xhdG9yLmxyZ2IgPSBscmdiO1xuXG4gIHZhciBsYWIkMSA9IGZ1bmN0aW9uIGxhYiQxKGNvbDEsIGNvbDIsIGYpIHtcbiAgICB2YXIgeHl6MCA9IGNvbDEubGFiKCk7XG4gICAgdmFyIHh5ejEgPSBjb2wyLmxhYigpO1xuICAgIHJldHVybiBuZXcgQ29sb3JfMSh4eXowWzBdICsgZiAqICh4eXoxWzBdIC0geHl6MFswXSksIHh5ejBbMV0gKyBmICogKHh5ejFbMV0gLSB4eXowWzFdKSwgeHl6MFsyXSArIGYgKiAoeHl6MVsyXSAtIHh5ejBbMl0pLCAnbGFiJyk7XG4gIH07IC8vIHJlZ2lzdGVyIGludGVycG9sYXRvclxuXG5cbiAgaW50ZXJwb2xhdG9yLmxhYiA9IGxhYiQxO1xuXG4gIHZhciBfaHN4ID0gZnVuY3Rpb24gX2hzeChjb2wxLCBjb2wyLCBmLCBtKSB7XG4gICAgdmFyIGFzc2lnbiwgYXNzaWduJDE7XG4gICAgdmFyIHh5ejAsIHh5ejE7XG5cbiAgICBpZiAobSA9PT0gJ2hzbCcpIHtcbiAgICAgIHh5ejAgPSBjb2wxLmhzbCgpO1xuICAgICAgeHl6MSA9IGNvbDIuaHNsKCk7XG4gICAgfSBlbHNlIGlmIChtID09PSAnaHN2Jykge1xuICAgICAgeHl6MCA9IGNvbDEuaHN2KCk7XG4gICAgICB4eXoxID0gY29sMi5oc3YoKTtcbiAgICB9IGVsc2UgaWYgKG0gPT09ICdoY2cnKSB7XG4gICAgICB4eXowID0gY29sMS5oY2coKTtcbiAgICAgIHh5ejEgPSBjb2wyLmhjZygpO1xuICAgIH0gZWxzZSBpZiAobSA9PT0gJ2hzaScpIHtcbiAgICAgIHh5ejAgPSBjb2wxLmhzaSgpO1xuICAgICAgeHl6MSA9IGNvbDIuaHNpKCk7XG4gICAgfSBlbHNlIGlmIChtID09PSAnbGNoJyB8fCBtID09PSAnaGNsJykge1xuICAgICAgbSA9ICdoY2wnO1xuICAgICAgeHl6MCA9IGNvbDEuaGNsKCk7XG4gICAgICB4eXoxID0gY29sMi5oY2woKTtcbiAgICB9XG5cbiAgICB2YXIgaHVlMCwgaHVlMSwgc2F0MCwgc2F0MSwgbGJ2MCwgbGJ2MTtcblxuICAgIGlmIChtLnN1YnN0cigwLCAxKSA9PT0gJ2gnKSB7XG4gICAgICBhc3NpZ24gPSB4eXowLCBodWUwID0gYXNzaWduWzBdLCBzYXQwID0gYXNzaWduWzFdLCBsYnYwID0gYXNzaWduWzJdO1xuICAgICAgYXNzaWduJDEgPSB4eXoxLCBodWUxID0gYXNzaWduJDFbMF0sIHNhdDEgPSBhc3NpZ24kMVsxXSwgbGJ2MSA9IGFzc2lnbiQxWzJdO1xuICAgIH1cblxuICAgIHZhciBzYXQsIGh1ZSwgbGJ2LCBkaDtcblxuICAgIGlmICghaXNOYU4oaHVlMCkgJiYgIWlzTmFOKGh1ZTEpKSB7XG4gICAgICAvLyBib3RoIGNvbG9ycyBoYXZlIGh1ZVxuICAgICAgaWYgKGh1ZTEgPiBodWUwICYmIGh1ZTEgLSBodWUwID4gMTgwKSB7XG4gICAgICAgIGRoID0gaHVlMSAtIChodWUwICsgMzYwKTtcbiAgICAgIH0gZWxzZSBpZiAoaHVlMSA8IGh1ZTAgJiYgaHVlMCAtIGh1ZTEgPiAxODApIHtcbiAgICAgICAgZGggPSBodWUxICsgMzYwIC0gaHVlMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRoID0gaHVlMSAtIGh1ZTA7XG4gICAgICB9XG5cbiAgICAgIGh1ZSA9IGh1ZTAgKyBmICogZGg7XG4gICAgfSBlbHNlIGlmICghaXNOYU4oaHVlMCkpIHtcbiAgICAgIGh1ZSA9IGh1ZTA7XG5cbiAgICAgIGlmICgobGJ2MSA9PSAxIHx8IGxidjEgPT0gMCkgJiYgbSAhPSAnaHN2Jykge1xuICAgICAgICBzYXQgPSBzYXQwO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWlzTmFOKGh1ZTEpKSB7XG4gICAgICBodWUgPSBodWUxO1xuXG4gICAgICBpZiAoKGxidjAgPT0gMSB8fCBsYnYwID09IDApICYmIG0gIT0gJ2hzdicpIHtcbiAgICAgICAgc2F0ID0gc2F0MTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaHVlID0gTnVtYmVyLk5hTjtcbiAgICB9XG5cbiAgICBpZiAoc2F0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNhdCA9IHNhdDAgKyBmICogKHNhdDEgLSBzYXQwKTtcbiAgICB9XG5cbiAgICBsYnYgPSBsYnYwICsgZiAqIChsYnYxIC0gbGJ2MCk7XG4gICAgcmV0dXJuIG5ldyBDb2xvcl8xKFtodWUsIHNhdCwgbGJ2XSwgbSk7XG4gIH07XG5cbiAgdmFyIGxjaCQxID0gZnVuY3Rpb24gbGNoJDEoY29sMSwgY29sMiwgZikge1xuICAgIHJldHVybiBfaHN4KGNvbDEsIGNvbDIsIGYsICdsY2gnKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IubGNoID0gbGNoJDE7XG4gIGludGVycG9sYXRvci5oY2wgPSBsY2gkMTtcblxuICB2YXIgbnVtJDEgPSBmdW5jdGlvbiBudW0kMShjb2wxLCBjb2wyLCBmKSB7XG4gICAgdmFyIGMxID0gY29sMS5udW0oKTtcbiAgICB2YXIgYzIgPSBjb2wyLm51bSgpO1xuICAgIHJldHVybiBuZXcgQ29sb3JfMShjMSArIGYgKiAoYzIgLSBjMSksICdudW0nKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IubnVtID0gbnVtJDE7XG5cbiAgdmFyIGhjZyQxID0gZnVuY3Rpb24gaGNnJDEoY29sMSwgY29sMiwgZikge1xuICAgIHJldHVybiBfaHN4KGNvbDEsIGNvbDIsIGYsICdoY2cnKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IuaGNnID0gaGNnJDE7XG5cbiAgdmFyIGhzaSQxID0gZnVuY3Rpb24gaHNpJDEoY29sMSwgY29sMiwgZikge1xuICAgIHJldHVybiBfaHN4KGNvbDEsIGNvbDIsIGYsICdoc2knKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IuaHNpID0gaHNpJDE7XG5cbiAgdmFyIGhzbCQxID0gZnVuY3Rpb24gaHNsJDEoY29sMSwgY29sMiwgZikge1xuICAgIHJldHVybiBfaHN4KGNvbDEsIGNvbDIsIGYsICdoc2wnKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IuaHNsID0gaHNsJDE7XG5cbiAgdmFyIGhzdiQxID0gZnVuY3Rpb24gaHN2JDEoY29sMSwgY29sMiwgZikge1xuICAgIHJldHVybiBfaHN4KGNvbDEsIGNvbDIsIGYsICdoc3YnKTtcbiAgfTsgLy8gcmVnaXN0ZXIgaW50ZXJwb2xhdG9yXG5cblxuICBpbnRlcnBvbGF0b3IuaHN2ID0gaHN2JDE7XG4gIHZhciBjbGlwX3JnYiQyID0gdXRpbHMuY2xpcF9yZ2I7XG4gIHZhciBwb3ckNCA9IE1hdGgucG93O1xuICB2YXIgc3FydCQzID0gTWF0aC5zcXJ0O1xuICB2YXIgUEkkMSA9IE1hdGguUEk7XG4gIHZhciBjb3MkMiA9IE1hdGguY29zO1xuICB2YXIgc2luJDEgPSBNYXRoLnNpbjtcbiAgdmFyIGF0YW4yJDEgPSBNYXRoLmF0YW4yO1xuXG4gIHZhciBhdmVyYWdlID0gZnVuY3Rpb24gYXZlcmFnZShjb2xvcnMsIG1vZGUsIHdlaWdodHMpIHtcbiAgICBpZiAobW9kZSA9PT0gdm9pZCAwKSBtb2RlID0gJ2xyZ2InO1xuICAgIGlmICh3ZWlnaHRzID09PSB2b2lkIDApIHdlaWdodHMgPSBudWxsO1xuICAgIHZhciBsID0gY29sb3JzLmxlbmd0aDtcblxuICAgIGlmICghd2VpZ2h0cykge1xuICAgICAgd2VpZ2h0cyA9IEFycmF5LmZyb20obmV3IEFycmF5KGwpKS5tYXAoZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0pO1xuICAgIH0gLy8gbm9ybWFsaXplIHdlaWdodHNcblxuXG4gICAgdmFyIGsgPSBsIC8gd2VpZ2h0cy5yZWR1Y2UoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhICsgYjtcbiAgICB9KTtcbiAgICB3ZWlnaHRzLmZvckVhY2goZnVuY3Rpb24gKHcsIGkpIHtcbiAgICAgIHdlaWdodHNbaV0gKj0gaztcbiAgICB9KTsgLy8gY29udmVydCBjb2xvcnMgdG8gQ29sb3Igb2JqZWN0c1xuXG4gICAgY29sb3JzID0gY29sb3JzLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgcmV0dXJuIG5ldyBDb2xvcl8xKGMpO1xuICAgIH0pO1xuXG4gICAgaWYgKG1vZGUgPT09ICdscmdiJykge1xuICAgICAgcmV0dXJuIF9hdmVyYWdlX2xyZ2IoY29sb3JzLCB3ZWlnaHRzKTtcbiAgICB9XG5cbiAgICB2YXIgZmlyc3QgPSBjb2xvcnMuc2hpZnQoKTtcbiAgICB2YXIgeHl6ID0gZmlyc3QuZ2V0KG1vZGUpO1xuICAgIHZhciBjbnQgPSBbXTtcbiAgICB2YXIgZHggPSAwO1xuICAgIHZhciBkeSA9IDA7IC8vIGluaXRpYWwgY29sb3JcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHl6Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB4eXpbaV0gPSAoeHl6W2ldIHx8IDApICogd2VpZ2h0c1swXTtcbiAgICAgIGNudC5wdXNoKGlzTmFOKHh5eltpXSkgPyAwIDogd2VpZ2h0c1swXSk7XG5cbiAgICAgIGlmIChtb2RlLmNoYXJBdChpKSA9PT0gJ2gnICYmICFpc05hTih4eXpbaV0pKSB7XG4gICAgICAgIHZhciBBID0geHl6W2ldIC8gMTgwICogUEkkMTtcbiAgICAgICAgZHggKz0gY29zJDIoQSkgKiB3ZWlnaHRzWzBdO1xuICAgICAgICBkeSArPSBzaW4kMShBKSAqIHdlaWdodHNbMF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGFscGhhID0gZmlyc3QuYWxwaGEoKSAqIHdlaWdodHNbMF07XG4gICAgY29sb3JzLmZvckVhY2goZnVuY3Rpb24gKGMsIGNpKSB7XG4gICAgICB2YXIgeHl6MiA9IGMuZ2V0KG1vZGUpO1xuICAgICAgYWxwaGEgKz0gYy5hbHBoYSgpICogd2VpZ2h0c1tjaSArIDFdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHh5ei5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWlzTmFOKHh5ejJbaV0pKSB7XG4gICAgICAgICAgY250W2ldICs9IHdlaWdodHNbY2kgKyAxXTtcblxuICAgICAgICAgIGlmIChtb2RlLmNoYXJBdChpKSA9PT0gJ2gnKSB7XG4gICAgICAgICAgICB2YXIgQSA9IHh5ejJbaV0gLyAxODAgKiBQSSQxO1xuICAgICAgICAgICAgZHggKz0gY29zJDIoQSkgKiB3ZWlnaHRzW2NpICsgMV07XG4gICAgICAgICAgICBkeSArPSBzaW4kMShBKSAqIHdlaWdodHNbY2kgKyAxXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgeHl6W2ldICs9IHh5ejJbaV0gKiB3ZWlnaHRzW2NpICsgMV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBmb3IgKHZhciBpJDEgPSAwOyBpJDEgPCB4eXoubGVuZ3RoOyBpJDErKykge1xuICAgICAgaWYgKG1vZGUuY2hhckF0KGkkMSkgPT09ICdoJykge1xuICAgICAgICB2YXIgQSQxID0gYXRhbjIkMShkeSAvIGNudFtpJDFdLCBkeCAvIGNudFtpJDFdKSAvIFBJJDEgKiAxODA7XG5cbiAgICAgICAgd2hpbGUgKEEkMSA8IDApIHtcbiAgICAgICAgICBBJDEgKz0gMzYwO1xuICAgICAgICB9XG5cbiAgICAgICAgd2hpbGUgKEEkMSA+PSAzNjApIHtcbiAgICAgICAgICBBJDEgLT0gMzYwO1xuICAgICAgICB9XG5cbiAgICAgICAgeHl6W2kkMV0gPSBBJDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4eXpbaSQxXSA9IHh5eltpJDFdIC8gY250W2kkMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgYWxwaGEgLz0gbDtcbiAgICByZXR1cm4gbmV3IENvbG9yXzEoeHl6LCBtb2RlKS5hbHBoYShhbHBoYSA+IDAuOTk5OTkgPyAxIDogYWxwaGEsIHRydWUpO1xuICB9O1xuXG4gIHZhciBfYXZlcmFnZV9scmdiID0gZnVuY3Rpb24gX2F2ZXJhZ2VfbHJnYihjb2xvcnMsIHdlaWdodHMpIHtcbiAgICB2YXIgbCA9IGNvbG9ycy5sZW5ndGg7XG4gICAgdmFyIHh5eiA9IFswLCAwLCAwLCAwXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29sb3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY29sID0gY29sb3JzW2ldO1xuICAgICAgdmFyIGYgPSB3ZWlnaHRzW2ldIC8gbDtcbiAgICAgIHZhciByZ2IgPSBjb2wuX3JnYjtcbiAgICAgIHh5elswXSArPSBwb3ckNChyZ2JbMF0sIDIpICogZjtcbiAgICAgIHh5elsxXSArPSBwb3ckNChyZ2JbMV0sIDIpICogZjtcbiAgICAgIHh5elsyXSArPSBwb3ckNChyZ2JbMl0sIDIpICogZjtcbiAgICAgIHh5elszXSArPSByZ2JbM10gKiBmO1xuICAgIH1cblxuICAgIHh5elswXSA9IHNxcnQkMyh4eXpbMF0pO1xuICAgIHh5elsxXSA9IHNxcnQkMyh4eXpbMV0pO1xuICAgIHh5elsyXSA9IHNxcnQkMyh4eXpbMl0pO1xuXG4gICAgaWYgKHh5elszXSA+IDAuOTk5OTk5OSkge1xuICAgICAgeHl6WzNdID0gMTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IENvbG9yXzEoY2xpcF9yZ2IkMih4eXopKTtcbiAgfTsgLy8gbWluaW1hbCBtdWx0aS1wdXJwb3NlIGludGVyZmFjZVxuICAvLyBAcmVxdWlyZXMgdXRpbHMgY29sb3IgYW5hbHl6ZVxuXG5cbiAgdmFyIHR5cGUkaiA9IHV0aWxzLnR5cGU7XG4gIHZhciBwb3ckNSA9IE1hdGgucG93O1xuXG4gIHZhciBzY2FsZSA9IGZ1bmN0aW9uIHNjYWxlKGNvbG9ycykge1xuICAgIC8vIGNvbnN0cnVjdG9yXG4gICAgdmFyIF9tb2RlID0gJ3JnYic7XG5cbiAgICB2YXIgX25hY29sID0gY2hyb21hXzEoJyNjY2MnKTtcblxuICAgIHZhciBfc3ByZWFkID0gMDsgLy8gY29uc3QgX2ZpeGVkID0gZmFsc2U7XG5cbiAgICB2YXIgX2RvbWFpbiA9IFswLCAxXTtcbiAgICB2YXIgX3BvcyA9IFtdO1xuICAgIHZhciBfcGFkZGluZyA9IFswLCAwXTtcbiAgICB2YXIgX2NsYXNzZXMgPSBmYWxzZTtcbiAgICB2YXIgX2NvbG9ycyA9IFtdO1xuICAgIHZhciBfb3V0ID0gZmFsc2U7XG4gICAgdmFyIF9taW4gPSAwO1xuICAgIHZhciBfbWF4ID0gMTtcbiAgICB2YXIgX2NvcnJlY3RMaWdodG5lc3MgPSBmYWxzZTtcbiAgICB2YXIgX2NvbG9yQ2FjaGUgPSB7fTtcbiAgICB2YXIgX3VzZUNhY2hlID0gdHJ1ZTtcbiAgICB2YXIgX2dhbW1hID0gMTsgLy8gcHJpdmF0ZSBtZXRob2RzXG5cbiAgICB2YXIgc2V0Q29sb3JzID0gZnVuY3Rpb24gc2V0Q29sb3JzKGNvbG9ycykge1xuICAgICAgY29sb3JzID0gY29sb3JzIHx8IFsnI2ZmZicsICcjMDAwJ107XG5cbiAgICAgIGlmIChjb2xvcnMgJiYgdHlwZSRqKGNvbG9ycykgPT09ICdzdHJpbmcnICYmIGNocm9tYV8xLmJyZXdlciAmJiBjaHJvbWFfMS5icmV3ZXJbY29sb3JzLnRvTG93ZXJDYXNlKCldKSB7XG4gICAgICAgIGNvbG9ycyA9IGNocm9tYV8xLmJyZXdlcltjb2xvcnMudG9Mb3dlckNhc2UoKV07XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlJGooY29sb3JzKSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAvLyBoYW5kbGUgc2luZ2xlIGNvbG9yXG4gICAgICAgIGlmIChjb2xvcnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgY29sb3JzID0gW2NvbG9yc1swXSwgY29sb3JzWzBdXTtcbiAgICAgICAgfSAvLyBtYWtlIGEgY29weSBvZiB0aGUgY29sb3JzXG5cblxuICAgICAgICBjb2xvcnMgPSBjb2xvcnMuc2xpY2UoMCk7IC8vIGNvbnZlcnQgdG8gY2hyb21hIGNsYXNzZXNcblxuICAgICAgICBmb3IgKHZhciBjID0gMDsgYyA8IGNvbG9ycy5sZW5ndGg7IGMrKykge1xuICAgICAgICAgIGNvbG9yc1tjXSA9IGNocm9tYV8xKGNvbG9yc1tjXSk7XG4gICAgICAgIH0gLy8gYXV0by1maWxsIGNvbG9yIHBvc2l0aW9uXG5cblxuICAgICAgICBfcG9zLmxlbmd0aCA9IDA7XG5cbiAgICAgICAgZm9yICh2YXIgYyQxID0gMDsgYyQxIDwgY29sb3JzLmxlbmd0aDsgYyQxKyspIHtcbiAgICAgICAgICBfcG9zLnB1c2goYyQxIC8gKGNvbG9ycy5sZW5ndGggLSAxKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVzZXRDYWNoZSgpO1xuICAgICAgcmV0dXJuIF9jb2xvcnMgPSBjb2xvcnM7XG4gICAgfTtcblxuICAgIHZhciBnZXRDbGFzcyA9IGZ1bmN0aW9uIGdldENsYXNzKHZhbHVlKSB7XG4gICAgICBpZiAoX2NsYXNzZXMgIT0gbnVsbCkge1xuICAgICAgICB2YXIgbiA9IF9jbGFzc2VzLmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciBpID0gMDtcblxuICAgICAgICB3aGlsZSAoaSA8IG4gJiYgdmFsdWUgPj0gX2NsYXNzZXNbaV0pIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaSAtIDE7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAwO1xuICAgIH07XG5cbiAgICB2YXIgdE1hcExpZ2h0bmVzcyA9IGZ1bmN0aW9uIHRNYXBMaWdodG5lc3ModCkge1xuICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcblxuICAgIHZhciB0TWFwRG9tYWluID0gZnVuY3Rpb24gdE1hcERvbWFpbih0KSB7XG4gICAgICByZXR1cm4gdDtcbiAgICB9OyAvLyBjb25zdCBjbGFzc2lmeVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAvLyAgICAgbGV0IHZhbCA9IHZhbHVlO1xuICAgIC8vICAgICBpZiAoX2NsYXNzZXMubGVuZ3RoID4gMikge1xuICAgIC8vICAgICAgICAgY29uc3QgbiA9IF9jbGFzc2VzLmxlbmd0aC0xO1xuICAgIC8vICAgICAgICAgY29uc3QgaSA9IGdldENsYXNzKHZhbHVlKTtcbiAgICAvLyAgICAgICAgIGNvbnN0IG1pbmMgPSBfY2xhc3Nlc1swXSArICgoX2NsYXNzZXNbMV0tX2NsYXNzZXNbMF0pICogKDAgKyAoX3NwcmVhZCAqIDAuNSkpKTsgIC8vIGNlbnRlciBvZiAxc3QgY2xhc3NcbiAgICAvLyAgICAgICAgIGNvbnN0IG1heGMgPSBfY2xhc3Nlc1tuLTFdICsgKChfY2xhc3Nlc1tuXS1fY2xhc3Nlc1tuLTFdKSAqICgxIC0gKF9zcHJlYWQgKiAwLjUpKSk7ICAvLyBjZW50ZXIgb2YgbGFzdCBjbGFzc1xuICAgIC8vICAgICAgICAgdmFsID0gX21pbiArICgoKChfY2xhc3Nlc1tpXSArICgoX2NsYXNzZXNbaSsxXSAtIF9jbGFzc2VzW2ldKSAqIDAuNSkpIC0gbWluYykgLyAobWF4Yy1taW5jKSkgKiAoX21heCAtIF9taW4pKTtcbiAgICAvLyAgICAgfVxuICAgIC8vICAgICByZXR1cm4gdmFsO1xuICAgIC8vIH07XG5cblxuICAgIHZhciBnZXRDb2xvciA9IGZ1bmN0aW9uIGdldENvbG9yKHZhbCwgYnlwYXNzTWFwKSB7XG4gICAgICB2YXIgY29sLCB0O1xuXG4gICAgICBpZiAoYnlwYXNzTWFwID09IG51bGwpIHtcbiAgICAgICAgYnlwYXNzTWFwID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc05hTih2YWwpIHx8IHZhbCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gX25hY29sO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWJ5cGFzc01hcCkge1xuICAgICAgICBpZiAoX2NsYXNzZXMgJiYgX2NsYXNzZXMubGVuZ3RoID4gMikge1xuICAgICAgICAgIC8vIGZpbmQgdGhlIGNsYXNzXG4gICAgICAgICAgdmFyIGMgPSBnZXRDbGFzcyh2YWwpO1xuICAgICAgICAgIHQgPSBjIC8gKF9jbGFzc2VzLmxlbmd0aCAtIDIpO1xuICAgICAgICB9IGVsc2UgaWYgKF9tYXggIT09IF9taW4pIHtcbiAgICAgICAgICAvLyBqdXN0IGludGVycG9sYXRlIGJldHdlZW4gbWluL21heFxuICAgICAgICAgIHQgPSAodmFsIC0gX21pbikgLyAoX21heCAtIF9taW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHQgPSAxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ID0gdmFsO1xuICAgICAgfSAvLyBkb21haW4gbWFwXG5cblxuICAgICAgdCA9IHRNYXBEb21haW4odCk7XG5cbiAgICAgIGlmICghYnlwYXNzTWFwKSB7XG4gICAgICAgIHQgPSB0TWFwTGlnaHRuZXNzKHQpOyAvLyBsaWdodG5lc3MgY29ycmVjdGlvblxuICAgICAgfVxuXG4gICAgICBpZiAoX2dhbW1hICE9PSAxKSB7XG4gICAgICAgIHQgPSBwb3ckNSh0LCBfZ2FtbWEpO1xuICAgICAgfVxuXG4gICAgICB0ID0gX3BhZGRpbmdbMF0gKyB0ICogKDEgLSBfcGFkZGluZ1swXSAtIF9wYWRkaW5nWzFdKTtcbiAgICAgIHQgPSBNYXRoLm1pbigxLCBNYXRoLm1heCgwLCB0KSk7XG4gICAgICB2YXIgayA9IE1hdGguZmxvb3IodCAqIDEwMDAwKTtcblxuICAgICAgaWYgKF91c2VDYWNoZSAmJiBfY29sb3JDYWNoZVtrXSkge1xuICAgICAgICBjb2wgPSBfY29sb3JDYWNoZVtrXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0eXBlJGooX2NvbG9ycykgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAvL2ZvciBpIGluIFswLi5fcG9zLmxlbmd0aC0xXVxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgX3Bvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHAgPSBfcG9zW2ldO1xuXG4gICAgICAgICAgICBpZiAodCA8PSBwKSB7XG4gICAgICAgICAgICAgIGNvbCA9IF9jb2xvcnNbaV07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodCA+PSBwICYmIGkgPT09IF9wb3MubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICBjb2wgPSBfY29sb3JzW2ldO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHQgPiBwICYmIHQgPCBfcG9zW2kgKyAxXSkge1xuICAgICAgICAgICAgICB0ID0gKHQgLSBwKSAvIChfcG9zW2kgKyAxXSAtIHApO1xuICAgICAgICAgICAgICBjb2wgPSBjaHJvbWFfMS5pbnRlcnBvbGF0ZShfY29sb3JzW2ldLCBfY29sb3JzW2kgKyAxXSwgdCwgX21vZGUpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSRqKF9jb2xvcnMpID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgY29sID0gX2NvbG9ycyh0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfdXNlQ2FjaGUpIHtcbiAgICAgICAgICBfY29sb3JDYWNoZVtrXSA9IGNvbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29sO1xuICAgIH07XG5cbiAgICB2YXIgcmVzZXRDYWNoZSA9IGZ1bmN0aW9uIHJlc2V0Q2FjaGUoKSB7XG4gICAgICByZXR1cm4gX2NvbG9yQ2FjaGUgPSB7fTtcbiAgICB9O1xuXG4gICAgc2V0Q29sb3JzKGNvbG9ycyk7IC8vIHB1YmxpYyBpbnRlcmZhY2VcblxuICAgIHZhciBmID0gZnVuY3Rpb24gZih2KSB7XG4gICAgICB2YXIgYyA9IGNocm9tYV8xKGdldENvbG9yKHYpKTtcblxuICAgICAgaWYgKF9vdXQgJiYgY1tfb3V0XSkge1xuICAgICAgICByZXR1cm4gY1tfb3V0XSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGM7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGYuY2xhc3NlcyA9IGZ1bmN0aW9uIChjbGFzc2VzKSB7XG4gICAgICBpZiAoY2xhc3NlcyAhPSBudWxsKSB7XG4gICAgICAgIGlmICh0eXBlJGooY2xhc3NlcykgPT09ICdhcnJheScpIHtcbiAgICAgICAgICBfY2xhc3NlcyA9IGNsYXNzZXM7XG4gICAgICAgICAgX2RvbWFpbiA9IFtjbGFzc2VzWzBdLCBjbGFzc2VzW2NsYXNzZXMubGVuZ3RoIC0gMV1dO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBkID0gY2hyb21hXzEuYW5hbHl6ZShfZG9tYWluKTtcblxuICAgICAgICAgIGlmIChjbGFzc2VzID09PSAwKSB7XG4gICAgICAgICAgICBfY2xhc3NlcyA9IFtkLm1pbiwgZC5tYXhdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBfY2xhc3NlcyA9IGNocm9tYV8xLmxpbWl0cyhkLCAnZScsIGNsYXNzZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gX2NsYXNzZXM7XG4gICAgfTtcblxuICAgIGYuZG9tYWluID0gZnVuY3Rpb24gKGRvbWFpbikge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBfZG9tYWluO1xuICAgICAgfVxuXG4gICAgICBfbWluID0gZG9tYWluWzBdO1xuICAgICAgX21heCA9IGRvbWFpbltkb21haW4ubGVuZ3RoIC0gMV07XG4gICAgICBfcG9zID0gW107XG4gICAgICB2YXIgayA9IF9jb2xvcnMubGVuZ3RoO1xuXG4gICAgICBpZiAoZG9tYWluLmxlbmd0aCA9PT0gayAmJiBfbWluICE9PSBfbWF4KSB7XG4gICAgICAgIC8vIHVwZGF0ZSBwb3NpdGlvbnNcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxpc3QgPSBBcnJheS5mcm9tKGRvbWFpbik7IGkgPCBsaXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgdmFyIGQgPSBsaXN0W2ldO1xuXG4gICAgICAgICAgX3Bvcy5wdXNoKChkIC0gX21pbikgLyAoX21heCAtIF9taW4pKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgYyA9IDA7IGMgPCBrOyBjKyspIHtcbiAgICAgICAgICBfcG9zLnB1c2goYyAvIChrIC0gMSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbi5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgLy8gc2V0IGRvbWFpbiBtYXBcbiAgICAgICAgICB2YXIgdE91dCA9IGRvbWFpbi5tYXAoZnVuY3Rpb24gKGQsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiBpIC8gKGRvbWFpbi5sZW5ndGggLSAxKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB2YXIgdEJyZWFrcyA9IGRvbWFpbi5tYXAoZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHJldHVybiAoZCAtIF9taW4pIC8gKF9tYXggLSBfbWluKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghdEJyZWFrcy5ldmVyeShmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICAgICAgICByZXR1cm4gdE91dFtpXSA9PT0gdmFsO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICB0TWFwRG9tYWluID0gZnVuY3Rpb24gdE1hcERvbWFpbih0KSB7XG4gICAgICAgICAgICAgIGlmICh0IDw9IDAgfHwgdCA+PSAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHQ7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB2YXIgaSA9IDA7XG5cbiAgICAgICAgICAgICAgd2hpbGUgKHQgPj0gdEJyZWFrc1tpICsgMV0pIHtcbiAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB2YXIgZiA9ICh0IC0gdEJyZWFrc1tpXSkgLyAodEJyZWFrc1tpICsgMV0gLSB0QnJlYWtzW2ldKTtcbiAgICAgICAgICAgICAgdmFyIG91dCA9IHRPdXRbaV0gKyBmICogKHRPdXRbaSArIDFdIC0gdE91dFtpXSk7XG4gICAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBfZG9tYWluID0gW19taW4sIF9tYXhdO1xuICAgICAgcmV0dXJuIGY7XG4gICAgfTtcblxuICAgIGYubW9kZSA9IGZ1bmN0aW9uIChfbSkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBfbW9kZTtcbiAgICAgIH1cblxuICAgICAgX21vZGUgPSBfbTtcbiAgICAgIHJlc2V0Q2FjaGUoKTtcbiAgICAgIHJldHVybiBmO1xuICAgIH07XG5cbiAgICBmLnJhbmdlID0gZnVuY3Rpb24gKGNvbG9ycywgX3Bvcykge1xuICAgICAgc2V0Q29sb3JzKGNvbG9ycywgX3Bvcyk7XG4gICAgICByZXR1cm4gZjtcbiAgICB9O1xuXG4gICAgZi5vdXQgPSBmdW5jdGlvbiAoX28pIHtcbiAgICAgIF9vdXQgPSBfbztcbiAgICAgIHJldHVybiBmO1xuICAgIH07XG5cbiAgICBmLnNwcmVhZCA9IGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gX3NwcmVhZDtcbiAgICAgIH1cblxuICAgICAgX3NwcmVhZCA9IHZhbDtcbiAgICAgIHJldHVybiBmO1xuICAgIH07XG5cbiAgICBmLmNvcnJlY3RMaWdodG5lc3MgPSBmdW5jdGlvbiAodikge1xuICAgICAgaWYgKHYgPT0gbnVsbCkge1xuICAgICAgICB2ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgX2NvcnJlY3RMaWdodG5lc3MgPSB2O1xuICAgICAgcmVzZXRDYWNoZSgpO1xuXG4gICAgICBpZiAoX2NvcnJlY3RMaWdodG5lc3MpIHtcbiAgICAgICAgdE1hcExpZ2h0bmVzcyA9IGZ1bmN0aW9uIHRNYXBMaWdodG5lc3ModCkge1xuICAgICAgICAgIHZhciBMMCA9IGdldENvbG9yKDAsIHRydWUpLmxhYigpWzBdO1xuICAgICAgICAgIHZhciBMMSA9IGdldENvbG9yKDEsIHRydWUpLmxhYigpWzBdO1xuICAgICAgICAgIHZhciBwb2wgPSBMMCA+IEwxO1xuICAgICAgICAgIHZhciBMX2FjdHVhbCA9IGdldENvbG9yKHQsIHRydWUpLmxhYigpWzBdO1xuICAgICAgICAgIHZhciBMX2lkZWFsID0gTDAgKyAoTDEgLSBMMCkgKiB0O1xuICAgICAgICAgIHZhciBMX2RpZmYgPSBMX2FjdHVhbCAtIExfaWRlYWw7XG4gICAgICAgICAgdmFyIHQwID0gMDtcbiAgICAgICAgICB2YXIgdDEgPSAxO1xuICAgICAgICAgIHZhciBtYXhfaXRlciA9IDIwO1xuXG4gICAgICAgICAgd2hpbGUgKE1hdGguYWJzKExfZGlmZikgPiAxZS0yICYmIG1heF9pdGVyLS0gPiAwKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAocG9sKSB7XG4gICAgICAgICAgICAgICAgTF9kaWZmICo9IC0xO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKExfZGlmZiA8IDApIHtcbiAgICAgICAgICAgICAgICB0MCA9IHQ7XG4gICAgICAgICAgICAgICAgdCArPSAodDEgLSB0KSAqIDAuNTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0MSA9IHQ7XG4gICAgICAgICAgICAgICAgdCArPSAodDAgLSB0KSAqIDAuNTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIExfYWN0dWFsID0gZ2V0Q29sb3IodCwgdHJ1ZSkubGFiKClbMF07XG4gICAgICAgICAgICAgIHJldHVybiBMX2RpZmYgPSBMX2FjdHVhbCAtIExfaWRlYWw7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdE1hcExpZ2h0bmVzcyA9IGZ1bmN0aW9uIHRNYXBMaWdodG5lc3ModCkge1xuICAgICAgICAgIHJldHVybiB0O1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZjtcbiAgICB9O1xuXG4gICAgZi5wYWRkaW5nID0gZnVuY3Rpb24gKHApIHtcbiAgICAgIGlmIChwICE9IG51bGwpIHtcbiAgICAgICAgaWYgKHR5cGUkaihwKSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBwID0gW3AsIHBdO1xuICAgICAgICB9XG5cbiAgICAgICAgX3BhZGRpbmcgPSBwO1xuICAgICAgICByZXR1cm4gZjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBfcGFkZGluZztcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZi5jb2xvcnMgPSBmdW5jdGlvbiAobnVtQ29sb3JzLCBvdXQpIHtcbiAgICAgIC8vIElmIG5vIGFyZ3VtZW50cyBhcmUgZ2l2ZW4sIHJldHVybiB0aGUgb3JpZ2luYWwgY29sb3JzIHRoYXQgd2VyZSBwcm92aWRlZFxuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgICAgIG91dCA9ICdoZXgnO1xuICAgICAgfVxuXG4gICAgICB2YXIgcmVzdWx0ID0gW107XG5cbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJlc3VsdCA9IF9jb2xvcnMuc2xpY2UoMCk7XG4gICAgICB9IGVsc2UgaWYgKG51bUNvbG9ycyA9PT0gMSkge1xuICAgICAgICByZXN1bHQgPSBbZigwLjUpXTtcbiAgICAgIH0gZWxzZSBpZiAobnVtQ29sb3JzID4gMSkge1xuICAgICAgICB2YXIgZG0gPSBfZG9tYWluWzBdO1xuICAgICAgICB2YXIgZGQgPSBfZG9tYWluWzFdIC0gZG07XG4gICAgICAgIHJlc3VsdCA9IF9fcmFuZ2VfXygwLCBudW1Db2xvcnMsIGZhbHNlKS5tYXAoZnVuY3Rpb24gKGkpIHtcbiAgICAgICAgICByZXR1cm4gZihkbSArIGkgLyAobnVtQ29sb3JzIC0gMSkgKiBkZCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gcmV0dXJucyBhbGwgY29sb3JzIGJhc2VkIG9uIHRoZSBkZWZpbmVkIGNsYXNzZXNcbiAgICAgICAgY29sb3JzID0gW107XG4gICAgICAgIHZhciBzYW1wbGVzID0gW107XG5cbiAgICAgICAgaWYgKF9jbGFzc2VzICYmIF9jbGFzc2VzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMSwgZW5kID0gX2NsYXNzZXMubGVuZ3RoLCBhc2MgPSAxIDw9IGVuZDsgYXNjID8gaSA8IGVuZCA6IGkgPiBlbmQ7IGFzYyA/IGkrKyA6IGktLSkge1xuICAgICAgICAgICAgc2FtcGxlcy5wdXNoKChfY2xhc3Nlc1tpIC0gMV0gKyBfY2xhc3Nlc1tpXSkgKiAwLjUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzYW1wbGVzID0gX2RvbWFpbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdCA9IHNhbXBsZXMubWFwKGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgcmV0dXJuIGYodik7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hyb21hXzFbb3V0XSkge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgcmV0dXJuIGNbb3V0XSgpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgZi5jYWNoZSA9IGZ1bmN0aW9uIChjKSB7XG4gICAgICBpZiAoYyAhPSBudWxsKSB7XG4gICAgICAgIF91c2VDYWNoZSA9IGM7XG4gICAgICAgIHJldHVybiBmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIF91c2VDYWNoZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZi5nYW1tYSA9IGZ1bmN0aW9uIChnKSB7XG4gICAgICBpZiAoZyAhPSBudWxsKSB7XG4gICAgICAgIF9nYW1tYSA9IGc7XG4gICAgICAgIHJldHVybiBmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIF9nYW1tYTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZi5ub2RhdGEgPSBmdW5jdGlvbiAoZCkge1xuICAgICAgaWYgKGQgIT0gbnVsbCkge1xuICAgICAgICBfbmFjb2wgPSBjaHJvbWFfMShkKTtcbiAgICAgICAgcmV0dXJuIGY7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gX25hY29sO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gZjtcbiAgfTtcblxuICBmdW5jdGlvbiBfX3JhbmdlX18obGVmdCwgcmlnaHQsIGluY2x1c2l2ZSkge1xuICAgIHZhciByYW5nZSA9IFtdO1xuICAgIHZhciBhc2NlbmRpbmcgPSBsZWZ0IDwgcmlnaHQ7XG4gICAgdmFyIGVuZCA9ICFpbmNsdXNpdmUgPyByaWdodCA6IGFzY2VuZGluZyA/IHJpZ2h0ICsgMSA6IHJpZ2h0IC0gMTtcblxuICAgIGZvciAodmFyIGkgPSBsZWZ0OyBhc2NlbmRpbmcgPyBpIDwgZW5kIDogaSA+IGVuZDsgYXNjZW5kaW5nID8gaSsrIDogaS0tKSB7XG4gICAgICByYW5nZS5wdXNoKGkpO1xuICAgIH1cblxuICAgIHJldHVybiByYW5nZTtcbiAgfSAvL1xuICAvLyBpbnRlcnBvbGF0ZXMgYmV0d2VlbiBhIHNldCBvZiBjb2xvcnMgdXppbmcgYSBiZXppZXIgc3BsaW5lXG4gIC8vXG4gIC8vIEByZXF1aXJlcyB1dGlscyBsYWJcblxuXG4gIHZhciBiZXppZXIgPSBmdW5jdGlvbiBiZXppZXIoY29sb3JzKSB7XG4gICAgdmFyIGFzc2lnbiwgYXNzaWduJDEsIGFzc2lnbiQyO1xuICAgIHZhciBJLCBsYWIwLCBsYWIxLCBsYWIyO1xuICAgIGNvbG9ycyA9IGNvbG9ycy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgIHJldHVybiBuZXcgQ29sb3JfMShjKTtcbiAgICB9KTtcblxuICAgIGlmIChjb2xvcnMubGVuZ3RoID09PSAyKSB7XG4gICAgICAvLyBsaW5lYXIgaW50ZXJwb2xhdGlvblxuICAgICAgYXNzaWduID0gY29sb3JzLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICByZXR1cm4gYy5sYWIoKTtcbiAgICAgIH0pLCBsYWIwID0gYXNzaWduWzBdLCBsYWIxID0gYXNzaWduWzFdO1xuXG4gICAgICBJID0gZnVuY3Rpb24gSSh0KSB7XG4gICAgICAgIHZhciBsYWIgPSBbMCwgMSwgMl0ubWFwKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgcmV0dXJuIGxhYjBbaV0gKyB0ICogKGxhYjFbaV0gLSBsYWIwW2ldKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgQ29sb3JfMShsYWIsICdsYWInKTtcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChjb2xvcnMubGVuZ3RoID09PSAzKSB7XG4gICAgICAvLyBxdWFkcmF0aWMgYmV6aWVyIGludGVycG9sYXRpb25cbiAgICAgIGFzc2lnbiQxID0gY29sb3JzLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICByZXR1cm4gYy5sYWIoKTtcbiAgICAgIH0pLCBsYWIwID0gYXNzaWduJDFbMF0sIGxhYjEgPSBhc3NpZ24kMVsxXSwgbGFiMiA9IGFzc2lnbiQxWzJdO1xuXG4gICAgICBJID0gZnVuY3Rpb24gSSh0KSB7XG4gICAgICAgIHZhciBsYWIgPSBbMCwgMSwgMl0ubWFwKGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgcmV0dXJuICgxIC0gdCkgKiAoMSAtIHQpICogbGFiMFtpXSArIDIgKiAoMSAtIHQpICogdCAqIGxhYjFbaV0gKyB0ICogdCAqIGxhYjJbaV07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IENvbG9yXzEobGFiLCAnbGFiJyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoY29sb3JzLmxlbmd0aCA9PT0gNCkge1xuICAgICAgLy8gY3ViaWMgYmV6aWVyIGludGVycG9sYXRpb25cbiAgICAgIHZhciBsYWIzO1xuICAgICAgYXNzaWduJDIgPSBjb2xvcnMubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgIHJldHVybiBjLmxhYigpO1xuICAgICAgfSksIGxhYjAgPSBhc3NpZ24kMlswXSwgbGFiMSA9IGFzc2lnbiQyWzFdLCBsYWIyID0gYXNzaWduJDJbMl0sIGxhYjMgPSBhc3NpZ24kMlszXTtcblxuICAgICAgSSA9IGZ1bmN0aW9uIEkodCkge1xuICAgICAgICB2YXIgbGFiID0gWzAsIDEsIDJdLm1hcChmdW5jdGlvbiAoaSkge1xuICAgICAgICAgIHJldHVybiAoMSAtIHQpICogKDEgLSB0KSAqICgxIC0gdCkgKiBsYWIwW2ldICsgMyAqICgxIC0gdCkgKiAoMSAtIHQpICogdCAqIGxhYjFbaV0gKyAzICogKDEgLSB0KSAqIHQgKiB0ICogbGFiMltpXSArIHQgKiB0ICogdCAqIGxhYjNbaV07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV3IENvbG9yXzEobGFiLCAnbGFiJyk7XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoY29sb3JzLmxlbmd0aCA9PT0gNSkge1xuICAgICAgdmFyIEkwID0gYmV6aWVyKGNvbG9ycy5zbGljZSgwLCAzKSk7XG4gICAgICB2YXIgSTEgPSBiZXppZXIoY29sb3JzLnNsaWNlKDIsIDUpKTtcblxuICAgICAgSSA9IGZ1bmN0aW9uIEkodCkge1xuICAgICAgICBpZiAodCA8IDAuNSkge1xuICAgICAgICAgIHJldHVybiBJMCh0ICogMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEkxKCh0IC0gMC41KSAqIDIpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBJO1xuICB9O1xuXG4gIHZhciBiZXppZXJfMSA9IGZ1bmN0aW9uIGJlemllcl8xKGNvbG9ycykge1xuICAgIHZhciBmID0gYmV6aWVyKGNvbG9ycyk7XG5cbiAgICBmLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHNjYWxlKGYpO1xuICAgIH07XG5cbiAgICByZXR1cm4gZjtcbiAgfTtcbiAgLypcbiAgICogaW50ZXJwb2xhdGVzIGJldHdlZW4gYSBzZXQgb2YgY29sb3JzIHV6aW5nIGEgYmV6aWVyIHNwbGluZVxuICAgKiBibGVuZCBtb2RlIGZvcm11bGFzIHRha2VuIGZyb20gaHR0cDovL3d3dy52ZW50dXJlLXdhcmUuY29tL2tldmluL2NvZGluZy9sZXRzLWxlYXJuLW1hdGgtcGhvdG9zaG9wLWJsZW5kLW1vZGVzL1xuICAgKi9cblxuXG4gIHZhciBibGVuZCA9IGZ1bmN0aW9uIGJsZW5kKGJvdHRvbSwgdG9wLCBtb2RlKSB7XG4gICAgaWYgKCFibGVuZFttb2RlXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIGJsZW5kIG1vZGUgJyArIG1vZGUpO1xuICAgIH1cblxuICAgIHJldHVybiBibGVuZFttb2RlXShib3R0b20sIHRvcCk7XG4gIH07XG5cbiAgdmFyIGJsZW5kX2YgPSBmdW5jdGlvbiBibGVuZF9mKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGJvdHRvbSwgdG9wKSB7XG4gICAgICB2YXIgYzAgPSBjaHJvbWFfMSh0b3ApLnJnYigpO1xuICAgICAgdmFyIGMxID0gY2hyb21hXzEoYm90dG9tKS5yZ2IoKTtcbiAgICAgIHJldHVybiBjaHJvbWFfMS5yZ2IoZihjMCwgYzEpKTtcbiAgICB9O1xuICB9O1xuXG4gIHZhciBlYWNoID0gZnVuY3Rpb24gZWFjaChmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChjMCwgYzEpIHtcbiAgICAgIHZhciBvdXQgPSBbXTtcbiAgICAgIG91dFswXSA9IGYoYzBbMF0sIGMxWzBdKTtcbiAgICAgIG91dFsxXSA9IGYoYzBbMV0sIGMxWzFdKTtcbiAgICAgIG91dFsyXSA9IGYoYzBbMl0sIGMxWzJdKTtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfTtcbiAgfTtcblxuICB2YXIgbm9ybWFsID0gZnVuY3Rpb24gbm9ybWFsKGEpIHtcbiAgICByZXR1cm4gYTtcbiAgfTtcblxuICB2YXIgbXVsdGlwbHkgPSBmdW5jdGlvbiBtdWx0aXBseShhLCBiKSB7XG4gICAgcmV0dXJuIGEgKiBiIC8gMjU1O1xuICB9O1xuXG4gIHZhciBkYXJrZW4kMSA9IGZ1bmN0aW9uIGRhcmtlbiQxKGEsIGIpIHtcbiAgICByZXR1cm4gYSA+IGIgPyBiIDogYTtcbiAgfTtcblxuICB2YXIgbGlnaHRlbiA9IGZ1bmN0aW9uIGxpZ2h0ZW4oYSwgYikge1xuICAgIHJldHVybiBhID4gYiA/IGEgOiBiO1xuICB9O1xuXG4gIHZhciBzY3JlZW4gPSBmdW5jdGlvbiBzY3JlZW4oYSwgYikge1xuICAgIHJldHVybiAyNTUgKiAoMSAtICgxIC0gYSAvIDI1NSkgKiAoMSAtIGIgLyAyNTUpKTtcbiAgfTtcblxuICB2YXIgb3ZlcmxheSA9IGZ1bmN0aW9uIG92ZXJsYXkoYSwgYikge1xuICAgIHJldHVybiBiIDwgMTI4ID8gMiAqIGEgKiBiIC8gMjU1IDogMjU1ICogKDEgLSAyICogKDEgLSBhIC8gMjU1KSAqICgxIC0gYiAvIDI1NSkpO1xuICB9O1xuXG4gIHZhciBidXJuID0gZnVuY3Rpb24gYnVybihhLCBiKSB7XG4gICAgcmV0dXJuIDI1NSAqICgxIC0gKDEgLSBiIC8gMjU1KSAvIChhIC8gMjU1KSk7XG4gIH07XG5cbiAgdmFyIGRvZGdlID0gZnVuY3Rpb24gZG9kZ2UoYSwgYikge1xuICAgIGlmIChhID09PSAyNTUpIHtcbiAgICAgIHJldHVybiAyNTU7XG4gICAgfVxuXG4gICAgYSA9IDI1NSAqIChiIC8gMjU1KSAvICgxIC0gYSAvIDI1NSk7XG4gICAgcmV0dXJuIGEgPiAyNTUgPyAyNTUgOiBhO1xuICB9OyAvLyAjIGFkZCA9IChhLGIpIC0+XG4gIC8vICMgICAgIGlmIChhICsgYiA+IDI1NSkgdGhlbiAyNTUgZWxzZSBhICsgYlxuXG5cbiAgYmxlbmQubm9ybWFsID0gYmxlbmRfZihlYWNoKG5vcm1hbCkpO1xuICBibGVuZC5tdWx0aXBseSA9IGJsZW5kX2YoZWFjaChtdWx0aXBseSkpO1xuICBibGVuZC5zY3JlZW4gPSBibGVuZF9mKGVhY2goc2NyZWVuKSk7XG4gIGJsZW5kLm92ZXJsYXkgPSBibGVuZF9mKGVhY2gob3ZlcmxheSkpO1xuICBibGVuZC5kYXJrZW4gPSBibGVuZF9mKGVhY2goZGFya2VuJDEpKTtcbiAgYmxlbmQubGlnaHRlbiA9IGJsZW5kX2YoZWFjaChsaWdodGVuKSk7XG4gIGJsZW5kLmRvZGdlID0gYmxlbmRfZihlYWNoKGRvZGdlKSk7XG4gIGJsZW5kLmJ1cm4gPSBibGVuZF9mKGVhY2goYnVybikpOyAvLyBibGVuZC5hZGQgPSBibGVuZF9mKGVhY2goYWRkKSk7XG5cbiAgdmFyIGJsZW5kXzEgPSBibGVuZDsgLy8gY3ViZWhlbGl4IGludGVycG9sYXRpb25cbiAgLy8gYmFzZWQgb24gRC5BLiBHcmVlbiBcIkEgY29sb3VyIHNjaGVtZSBmb3IgdGhlIGRpc3BsYXkgb2YgYXN0cm9ub21pY2FsIGludGVuc2l0eSBpbWFnZXNcIlxuICAvLyBodHRwOi8vYXN0cm9uLXNvYy5pbi9idWxsZXRpbi8xMUp1bmUvMjg5MzkyMDExLnBkZlxuXG4gIHZhciB0eXBlJGsgPSB1dGlscy50eXBlO1xuICB2YXIgY2xpcF9yZ2IkMyA9IHV0aWxzLmNsaXBfcmdiO1xuICB2YXIgVFdPUEkkMiA9IHV0aWxzLlRXT1BJO1xuICB2YXIgcG93JDYgPSBNYXRoLnBvdztcbiAgdmFyIHNpbiQyID0gTWF0aC5zaW47XG4gIHZhciBjb3MkMyA9IE1hdGguY29zO1xuXG4gIHZhciBjdWJlaGVsaXggPSBmdW5jdGlvbiBjdWJlaGVsaXgoc3RhcnQsIHJvdGF0aW9ucywgaHVlLCBnYW1tYSwgbGlnaHRuZXNzKSB7XG4gICAgaWYgKHN0YXJ0ID09PSB2b2lkIDApIHN0YXJ0ID0gMzAwO1xuICAgIGlmIChyb3RhdGlvbnMgPT09IHZvaWQgMCkgcm90YXRpb25zID0gLTEuNTtcbiAgICBpZiAoaHVlID09PSB2b2lkIDApIGh1ZSA9IDE7XG4gICAgaWYgKGdhbW1hID09PSB2b2lkIDApIGdhbW1hID0gMTtcbiAgICBpZiAobGlnaHRuZXNzID09PSB2b2lkIDApIGxpZ2h0bmVzcyA9IFswLCAxXTtcbiAgICB2YXIgZGggPSAwLFxuICAgICAgICBkbDtcblxuICAgIGlmICh0eXBlJGsobGlnaHRuZXNzKSA9PT0gJ2FycmF5Jykge1xuICAgICAgZGwgPSBsaWdodG5lc3NbMV0gLSBsaWdodG5lc3NbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRsID0gMDtcbiAgICAgIGxpZ2h0bmVzcyA9IFtsaWdodG5lc3MsIGxpZ2h0bmVzc107XG4gICAgfVxuXG4gICAgdmFyIGYgPSBmdW5jdGlvbiBmKGZyYWN0KSB7XG4gICAgICB2YXIgYSA9IFRXT1BJJDIgKiAoKHN0YXJ0ICsgMTIwKSAvIDM2MCArIHJvdGF0aW9ucyAqIGZyYWN0KTtcbiAgICAgIHZhciBsID0gcG93JDYobGlnaHRuZXNzWzBdICsgZGwgKiBmcmFjdCwgZ2FtbWEpO1xuICAgICAgdmFyIGggPSBkaCAhPT0gMCA/IGh1ZVswXSArIGZyYWN0ICogZGggOiBodWU7XG4gICAgICB2YXIgYW1wID0gaCAqIGwgKiAoMSAtIGwpIC8gMjtcbiAgICAgIHZhciBjb3NfYSA9IGNvcyQzKGEpO1xuICAgICAgdmFyIHNpbl9hID0gc2luJDIoYSk7XG4gICAgICB2YXIgciA9IGwgKyBhbXAgKiAoLTAuMTQ4NjEgKiBjb3NfYSArIDEuNzgyNzcgKiBzaW5fYSk7XG4gICAgICB2YXIgZyA9IGwgKyBhbXAgKiAoLTAuMjkyMjcgKiBjb3NfYSAtIDAuOTA2NDkgKiBzaW5fYSk7XG4gICAgICB2YXIgYiA9IGwgKyBhbXAgKiAoKzEuOTcyOTQgKiBjb3NfYSk7XG4gICAgICByZXR1cm4gY2hyb21hXzEoY2xpcF9yZ2IkMyhbciAqIDI1NSwgZyAqIDI1NSwgYiAqIDI1NSwgMV0pKTtcbiAgICB9O1xuXG4gICAgZi5zdGFydCA9IGZ1bmN0aW9uIChzKSB7XG4gICAgICBpZiAocyA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBzdGFydDtcbiAgICAgIH1cblxuICAgICAgc3RhcnQgPSBzO1xuICAgICAgcmV0dXJuIGY7XG4gICAgfTtcblxuICAgIGYucm90YXRpb25zID0gZnVuY3Rpb24gKHIpIHtcbiAgICAgIGlmIChyID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHJvdGF0aW9ucztcbiAgICAgIH1cblxuICAgICAgcm90YXRpb25zID0gcjtcbiAgICAgIHJldHVybiBmO1xuICAgIH07XG5cbiAgICBmLmdhbW1hID0gZnVuY3Rpb24gKGcpIHtcbiAgICAgIGlmIChnID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGdhbW1hO1xuICAgICAgfVxuXG4gICAgICBnYW1tYSA9IGc7XG4gICAgICByZXR1cm4gZjtcbiAgICB9O1xuXG4gICAgZi5odWUgPSBmdW5jdGlvbiAoaCkge1xuICAgICAgaWYgKGggPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gaHVlO1xuICAgICAgfVxuXG4gICAgICBodWUgPSBoO1xuXG4gICAgICBpZiAodHlwZSRrKGh1ZSkgPT09ICdhcnJheScpIHtcbiAgICAgICAgZGggPSBodWVbMV0gLSBodWVbMF07XG5cbiAgICAgICAgaWYgKGRoID09PSAwKSB7XG4gICAgICAgICAgaHVlID0gaHVlWzFdO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaCA9IDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmO1xuICAgIH07XG5cbiAgICBmLmxpZ2h0bmVzcyA9IGZ1bmN0aW9uIChoKSB7XG4gICAgICBpZiAoaCA9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBsaWdodG5lc3M7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlJGsoaCkgPT09ICdhcnJheScpIHtcbiAgICAgICAgbGlnaHRuZXNzID0gaDtcbiAgICAgICAgZGwgPSBoWzFdIC0gaFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpZ2h0bmVzcyA9IFtoLCBoXTtcbiAgICAgICAgZGwgPSAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZjtcbiAgICB9O1xuXG4gICAgZi5zY2FsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBjaHJvbWFfMS5zY2FsZShmKTtcbiAgICB9O1xuXG4gICAgZi5odWUoaHVlKTtcbiAgICByZXR1cm4gZjtcbiAgfTtcblxuICB2YXIgZGlnaXRzID0gJzAxMjM0NTY3ODlhYmNkZWYnO1xuICB2YXIgZmxvb3IkMiA9IE1hdGguZmxvb3I7XG4gIHZhciByYW5kb20gPSBNYXRoLnJhbmRvbTtcblxuICB2YXIgcmFuZG9tXzEgPSBmdW5jdGlvbiByYW5kb21fMSgpIHtcbiAgICB2YXIgY29kZSA9ICcjJztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNjsgaSsrKSB7XG4gICAgICBjb2RlICs9IGRpZ2l0cy5jaGFyQXQoZmxvb3IkMihyYW5kb20oKSAqIDE2KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBDb2xvcl8xKGNvZGUsICdoZXgnKTtcbiAgfTtcblxuICB2YXIgbG9nJDEgPSBNYXRoLmxvZztcbiAgdmFyIHBvdyQ3ID0gTWF0aC5wb3c7XG4gIHZhciBmbG9vciQzID0gTWF0aC5mbG9vcjtcbiAgdmFyIGFicyA9IE1hdGguYWJzO1xuXG4gIHZhciBhbmFseXplID0gZnVuY3Rpb24gYW5hbHl6ZShkYXRhLCBrZXkpIHtcbiAgICBpZiAoa2V5ID09PSB2b2lkIDApIGtleSA9IG51bGw7XG4gICAgdmFyIHIgPSB7XG4gICAgICBtaW46IE51bWJlci5NQVhfVkFMVUUsXG4gICAgICBtYXg6IE51bWJlci5NQVhfVkFMVUUgKiAtMSxcbiAgICAgIHN1bTogMCxcbiAgICAgIHZhbHVlczogW10sXG4gICAgICBjb3VudDogMFxuICAgIH07XG5cbiAgICBpZiAodHlwZShkYXRhKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGRhdGEgPSBPYmplY3QudmFsdWVzKGRhdGEpO1xuICAgIH1cblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAodmFsKSB7XG4gICAgICBpZiAoa2V5ICYmIHR5cGUodmFsKSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdmFsID0gdmFsW2tleV07XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCAmJiB2YWwgIT09IG51bGwgJiYgIWlzTmFOKHZhbCkpIHtcbiAgICAgICAgci52YWx1ZXMucHVzaCh2YWwpO1xuICAgICAgICByLnN1bSArPSB2YWw7XG5cbiAgICAgICAgaWYgKHZhbCA8IHIubWluKSB7XG4gICAgICAgICAgci5taW4gPSB2YWw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsID4gci5tYXgpIHtcbiAgICAgICAgICByLm1heCA9IHZhbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHIuY291bnQgKz0gMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByLmRvbWFpbiA9IFtyLm1pbiwgci5tYXhdO1xuXG4gICAgci5saW1pdHMgPSBmdW5jdGlvbiAobW9kZSwgbnVtKSB7XG4gICAgICByZXR1cm4gbGltaXRzKHIsIG1vZGUsIG51bSk7XG4gICAgfTtcblxuICAgIHJldHVybiByO1xuICB9O1xuXG4gIHZhciBsaW1pdHMgPSBmdW5jdGlvbiBsaW1pdHMoZGF0YSwgbW9kZSwgbnVtKSB7XG4gICAgaWYgKG1vZGUgPT09IHZvaWQgMCkgbW9kZSA9ICdlcXVhbCc7XG4gICAgaWYgKG51bSA9PT0gdm9pZCAwKSBudW0gPSA3O1xuXG4gICAgaWYgKHR5cGUoZGF0YSkgPT0gJ2FycmF5Jykge1xuICAgICAgZGF0YSA9IGFuYWx5emUoZGF0YSk7XG4gICAgfVxuXG4gICAgdmFyIG1pbiA9IGRhdGEubWluO1xuICAgIHZhciBtYXggPSBkYXRhLm1heDtcbiAgICB2YXIgdmFsdWVzID0gZGF0YS52YWx1ZXMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuXG4gICAgaWYgKG51bSA9PT0gMSkge1xuICAgICAgcmV0dXJuIFttaW4sIG1heF07XG4gICAgfVxuXG4gICAgdmFyIGxpbWl0cyA9IFtdO1xuXG4gICAgaWYgKG1vZGUuc3Vic3RyKDAsIDEpID09PSAnYycpIHtcbiAgICAgIC8vIGNvbnRpbnVvdXNcbiAgICAgIGxpbWl0cy5wdXNoKG1pbik7XG4gICAgICBsaW1pdHMucHVzaChtYXgpO1xuICAgIH1cblxuICAgIGlmIChtb2RlLnN1YnN0cigwLCAxKSA9PT0gJ2UnKSB7XG4gICAgICAvLyBlcXVhbCBpbnRlcnZhbFxuICAgICAgbGltaXRzLnB1c2gobWluKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBudW07IGkrKykge1xuICAgICAgICBsaW1pdHMucHVzaChtaW4gKyBpIC8gbnVtICogKG1heCAtIG1pbikpO1xuICAgICAgfVxuXG4gICAgICBsaW1pdHMucHVzaChtYXgpO1xuICAgIH0gZWxzZSBpZiAobW9kZS5zdWJzdHIoMCwgMSkgPT09ICdsJykge1xuICAgICAgLy8gbG9nIHNjYWxlXG4gICAgICBpZiAobWluIDw9IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2dhcml0aG1pYyBzY2FsZXMgYXJlIG9ubHkgcG9zc2libGUgZm9yIHZhbHVlcyA+IDAnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIG1pbl9sb2cgPSBNYXRoLkxPRzEwRSAqIGxvZyQxKG1pbik7XG4gICAgICB2YXIgbWF4X2xvZyA9IE1hdGguTE9HMTBFICogbG9nJDEobWF4KTtcbiAgICAgIGxpbWl0cy5wdXNoKG1pbik7XG5cbiAgICAgIGZvciAodmFyIGkkMSA9IDE7IGkkMSA8IG51bTsgaSQxKyspIHtcbiAgICAgICAgbGltaXRzLnB1c2gocG93JDcoMTAsIG1pbl9sb2cgKyBpJDEgLyBudW0gKiAobWF4X2xvZyAtIG1pbl9sb2cpKSk7XG4gICAgICB9XG5cbiAgICAgIGxpbWl0cy5wdXNoKG1heCk7XG4gICAgfSBlbHNlIGlmIChtb2RlLnN1YnN0cigwLCAxKSA9PT0gJ3EnKSB7XG4gICAgICAvLyBxdWFudGlsZSBzY2FsZVxuICAgICAgbGltaXRzLnB1c2gobWluKTtcblxuICAgICAgZm9yICh2YXIgaSQyID0gMTsgaSQyIDwgbnVtOyBpJDIrKykge1xuICAgICAgICB2YXIgcCA9ICh2YWx1ZXMubGVuZ3RoIC0gMSkgKiBpJDIgLyBudW07XG4gICAgICAgIHZhciBwYiA9IGZsb29yJDMocCk7XG5cbiAgICAgICAgaWYgKHBiID09PSBwKSB7XG4gICAgICAgICAgbGltaXRzLnB1c2godmFsdWVzW3BiXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gcCA+IHBiXG4gICAgICAgICAgdmFyIHByID0gcCAtIHBiO1xuICAgICAgICAgIGxpbWl0cy5wdXNoKHZhbHVlc1twYl0gKiAoMSAtIHByKSArIHZhbHVlc1twYiArIDFdICogcHIpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxpbWl0cy5wdXNoKG1heCk7XG4gICAgfSBlbHNlIGlmIChtb2RlLnN1YnN0cigwLCAxKSA9PT0gJ2snKSB7XG4gICAgICAvLyBrLW1lYW5zIGNsdXN0ZXJpbmdcblxuICAgICAgLypcbiAgICAgIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uXG4gICAgICBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvZmlndWUvc291cmNlL2Jyb3dzZS90cnVuay9maWd1ZS5qcyMzMzZcbiAgICAgIHNpbXBsaWZpZWQgZm9yIDEtZCBpbnB1dCB2YWx1ZXNcbiAgICAgICovXG4gICAgICB2YXIgY2x1c3RlcjtcbiAgICAgIHZhciBuID0gdmFsdWVzLmxlbmd0aDtcbiAgICAgIHZhciBhc3NpZ25tZW50cyA9IG5ldyBBcnJheShuKTtcbiAgICAgIHZhciBjbHVzdGVyU2l6ZXMgPSBuZXcgQXJyYXkobnVtKTtcbiAgICAgIHZhciByZXBlYXQgPSB0cnVlO1xuICAgICAgdmFyIG5iX2l0ZXJzID0gMDtcbiAgICAgIHZhciBjZW50cm9pZHMgPSBudWxsOyAvLyBnZXQgc2VlZCB2YWx1ZXNcblxuICAgICAgY2VudHJvaWRzID0gW107XG4gICAgICBjZW50cm9pZHMucHVzaChtaW4pO1xuXG4gICAgICBmb3IgKHZhciBpJDMgPSAxOyBpJDMgPCBudW07IGkkMysrKSB7XG4gICAgICAgIGNlbnRyb2lkcy5wdXNoKG1pbiArIGkkMyAvIG51bSAqIChtYXggLSBtaW4pKTtcbiAgICAgIH1cblxuICAgICAgY2VudHJvaWRzLnB1c2gobWF4KTtcblxuICAgICAgd2hpbGUgKHJlcGVhdCkge1xuICAgICAgICAvLyBhc3NpZ25tZW50IHN0ZXBcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBudW07IGorKykge1xuICAgICAgICAgIGNsdXN0ZXJTaXplc1tqXSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBpJDQgPSAwOyBpJDQgPCBuOyBpJDQrKykge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHZhbHVlc1tpJDRdO1xuICAgICAgICAgIHZhciBtaW5kaXN0ID0gTnVtYmVyLk1BWF9WQUxVRTtcbiAgICAgICAgICB2YXIgYmVzdCA9IHZvaWQgMDtcblxuICAgICAgICAgIGZvciAodmFyIGokMSA9IDA7IGokMSA8IG51bTsgaiQxKyspIHtcbiAgICAgICAgICAgIHZhciBkaXN0ID0gYWJzKGNlbnRyb2lkc1tqJDFdIC0gdmFsdWUpO1xuXG4gICAgICAgICAgICBpZiAoZGlzdCA8IG1pbmRpc3QpIHtcbiAgICAgICAgICAgICAgbWluZGlzdCA9IGRpc3Q7XG4gICAgICAgICAgICAgIGJlc3QgPSBqJDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNsdXN0ZXJTaXplc1tiZXN0XSsrO1xuICAgICAgICAgICAgYXNzaWdubWVudHNbaSQ0XSA9IGJlc3Q7XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIHVwZGF0ZSBjZW50cm9pZHMgc3RlcFxuXG5cbiAgICAgICAgdmFyIG5ld0NlbnRyb2lkcyA9IG5ldyBBcnJheShudW0pO1xuXG4gICAgICAgIGZvciAodmFyIGokMiA9IDA7IGokMiA8IG51bTsgaiQyKyspIHtcbiAgICAgICAgICBuZXdDZW50cm9pZHNbaiQyXSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBpJDUgPSAwOyBpJDUgPCBuOyBpJDUrKykge1xuICAgICAgICAgIGNsdXN0ZXIgPSBhc3NpZ25tZW50c1tpJDVdO1xuXG4gICAgICAgICAgaWYgKG5ld0NlbnRyb2lkc1tjbHVzdGVyXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgbmV3Q2VudHJvaWRzW2NsdXN0ZXJdID0gdmFsdWVzW2kkNV07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ld0NlbnRyb2lkc1tjbHVzdGVyXSArPSB2YWx1ZXNbaSQ1XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHZhciBqJDMgPSAwOyBqJDMgPCBudW07IGokMysrKSB7XG4gICAgICAgICAgbmV3Q2VudHJvaWRzW2okM10gKj0gMSAvIGNsdXN0ZXJTaXplc1tqJDNdO1xuICAgICAgICB9IC8vIGNoZWNrIGNvbnZlcmdlbmNlXG5cblxuICAgICAgICByZXBlYXQgPSBmYWxzZTtcblxuICAgICAgICBmb3IgKHZhciBqJDQgPSAwOyBqJDQgPCBudW07IGokNCsrKSB7XG4gICAgICAgICAgaWYgKG5ld0NlbnRyb2lkc1tqJDRdICE9PSBjZW50cm9pZHNbaiQ0XSkge1xuICAgICAgICAgICAgcmVwZWF0ID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNlbnRyb2lkcyA9IG5ld0NlbnRyb2lkcztcbiAgICAgICAgbmJfaXRlcnMrKztcblxuICAgICAgICBpZiAobmJfaXRlcnMgPiAyMDApIHtcbiAgICAgICAgICByZXBlYXQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSAvLyBmaW5pc2hlZCBrLW1lYW5zIGNsdXN0ZXJpbmdcbiAgICAgIC8vIHRoZSBuZXh0IHBhcnQgaXMgYm9ycm93ZWQgZnJvbSBnYWJyaWVsZmxvci5pdFxuXG5cbiAgICAgIHZhciBrQ2x1c3RlcnMgPSB7fTtcblxuICAgICAgZm9yICh2YXIgaiQ1ID0gMDsgaiQ1IDwgbnVtOyBqJDUrKykge1xuICAgICAgICBrQ2x1c3RlcnNbaiQ1XSA9IFtdO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBpJDYgPSAwOyBpJDYgPCBuOyBpJDYrKykge1xuICAgICAgICBjbHVzdGVyID0gYXNzaWdubWVudHNbaSQ2XTtcbiAgICAgICAga0NsdXN0ZXJzW2NsdXN0ZXJdLnB1c2godmFsdWVzW2kkNl0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgdG1wS01lYW5zQnJlYWtzID0gW107XG5cbiAgICAgIGZvciAodmFyIGokNiA9IDA7IGokNiA8IG51bTsgaiQ2KyspIHtcbiAgICAgICAgdG1wS01lYW5zQnJlYWtzLnB1c2goa0NsdXN0ZXJzW2okNl1bMF0pO1xuICAgICAgICB0bXBLTWVhbnNCcmVha3MucHVzaChrQ2x1c3RlcnNbaiQ2XVtrQ2x1c3RlcnNbaiQ2XS5sZW5ndGggLSAxXSk7XG4gICAgICB9XG5cbiAgICAgIHRtcEtNZWFuc0JyZWFrcyA9IHRtcEtNZWFuc0JyZWFrcy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhIC0gYjtcbiAgICAgIH0pO1xuICAgICAgbGltaXRzLnB1c2godG1wS01lYW5zQnJlYWtzWzBdKTtcblxuICAgICAgZm9yICh2YXIgaSQ3ID0gMTsgaSQ3IDwgdG1wS01lYW5zQnJlYWtzLmxlbmd0aDsgaSQ3ICs9IDIpIHtcbiAgICAgICAgdmFyIHYgPSB0bXBLTWVhbnNCcmVha3NbaSQ3XTtcblxuICAgICAgICBpZiAoIWlzTmFOKHYpICYmIGxpbWl0cy5pbmRleE9mKHYpID09PSAtMSkge1xuICAgICAgICAgIGxpbWl0cy5wdXNoKHYpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpbWl0cztcbiAgfTtcblxuICB2YXIgYW5hbHl6ZV8xID0ge1xuICAgIGFuYWx5emU6IGFuYWx5emUsXG4gICAgbGltaXRzOiBsaW1pdHNcbiAgfTtcblxuICB2YXIgY29udHJhc3QgPSBmdW5jdGlvbiBjb250cmFzdChhLCBiKSB7XG4gICAgLy8gV0NBRyBjb250cmFzdCByYXRpb1xuICAgIC8vIHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDA4L1JFQy1XQ0FHMjAtMjAwODEyMTEvI2NvbnRyYXN0LXJhdGlvZGVmXG4gICAgYSA9IG5ldyBDb2xvcl8xKGEpO1xuICAgIGIgPSBuZXcgQ29sb3JfMShiKTtcbiAgICB2YXIgbDEgPSBhLmx1bWluYW5jZSgpO1xuICAgIHZhciBsMiA9IGIubHVtaW5hbmNlKCk7XG4gICAgcmV0dXJuIGwxID4gbDIgPyAobDEgKyAwLjA1KSAvIChsMiArIDAuMDUpIDogKGwyICsgMC4wNSkgLyAobDEgKyAwLjA1KTtcbiAgfTtcblxuICB2YXIgc3FydCQ0ID0gTWF0aC5zcXJ0O1xuICB2YXIgYXRhbjIkMiA9IE1hdGguYXRhbjI7XG4gIHZhciBhYnMkMSA9IE1hdGguYWJzO1xuICB2YXIgY29zJDQgPSBNYXRoLmNvcztcbiAgdmFyIFBJJDIgPSBNYXRoLlBJO1xuXG4gIHZhciBkZWx0YUUgPSBmdW5jdGlvbiBkZWx0YUUoYSwgYiwgTCwgQykge1xuICAgIGlmIChMID09PSB2b2lkIDApIEwgPSAxO1xuICAgIGlmIChDID09PSB2b2lkIDApIEMgPSAxOyAvLyBEZWx0YSBFIChDTUMpXG4gICAgLy8gc2VlIGh0dHA6Ly93d3cuYnJ1Y2VsaW5kYmxvb20uY29tL2luZGV4Lmh0bWw/RXFuX0RlbHRhRV9DTUMuaHRtbFxuXG4gICAgYSA9IG5ldyBDb2xvcl8xKGEpO1xuICAgIGIgPSBuZXcgQ29sb3JfMShiKTtcbiAgICB2YXIgcmVmID0gQXJyYXkuZnJvbShhLmxhYigpKTtcbiAgICB2YXIgTDEgPSByZWZbMF07XG4gICAgdmFyIGExID0gcmVmWzFdO1xuICAgIHZhciBiMSA9IHJlZlsyXTtcbiAgICB2YXIgcmVmJDEgPSBBcnJheS5mcm9tKGIubGFiKCkpO1xuICAgIHZhciBMMiA9IHJlZiQxWzBdO1xuICAgIHZhciBhMiA9IHJlZiQxWzFdO1xuICAgIHZhciBiMiA9IHJlZiQxWzJdO1xuICAgIHZhciBjMSA9IHNxcnQkNChhMSAqIGExICsgYjEgKiBiMSk7XG4gICAgdmFyIGMyID0gc3FydCQ0KGEyICogYTIgKyBiMiAqIGIyKTtcbiAgICB2YXIgc2wgPSBMMSA8IDE2LjAgPyAwLjUxMSA6IDAuMDQwOTc1ICogTDEgLyAoMS4wICsgMC4wMTc2NSAqIEwxKTtcbiAgICB2YXIgc2MgPSAwLjA2MzggKiBjMSAvICgxLjAgKyAwLjAxMzEgKiBjMSkgKyAwLjYzODtcbiAgICB2YXIgaDEgPSBjMSA8IDAuMDAwMDAxID8gMC4wIDogYXRhbjIkMihiMSwgYTEpICogMTgwLjAgLyBQSSQyO1xuXG4gICAgd2hpbGUgKGgxIDwgMCkge1xuICAgICAgaDEgKz0gMzYwO1xuICAgIH1cblxuICAgIHdoaWxlIChoMSA+PSAzNjApIHtcbiAgICAgIGgxIC09IDM2MDtcbiAgICB9XG5cbiAgICB2YXIgdCA9IGgxID49IDE2NC4wICYmIGgxIDw9IDM0NS4wID8gMC41NiArIGFicyQxKDAuMiAqIGNvcyQ0KFBJJDIgKiAoaDEgKyAxNjguMCkgLyAxODAuMCkpIDogMC4zNiArIGFicyQxKDAuNCAqIGNvcyQ0KFBJJDIgKiAoaDEgKyAzNS4wKSAvIDE4MC4wKSk7XG4gICAgdmFyIGM0ID0gYzEgKiBjMSAqIGMxICogYzE7XG4gICAgdmFyIGYgPSBzcXJ0JDQoYzQgLyAoYzQgKyAxOTAwLjApKTtcbiAgICB2YXIgc2ggPSBzYyAqIChmICogdCArIDEuMCAtIGYpO1xuICAgIHZhciBkZWxMID0gTDEgLSBMMjtcbiAgICB2YXIgZGVsQyA9IGMxIC0gYzI7XG4gICAgdmFyIGRlbEEgPSBhMSAtIGEyO1xuICAgIHZhciBkZWxCID0gYjEgLSBiMjtcbiAgICB2YXIgZEgyID0gZGVsQSAqIGRlbEEgKyBkZWxCICogZGVsQiAtIGRlbEMgKiBkZWxDO1xuICAgIHZhciB2MSA9IGRlbEwgLyAoTCAqIHNsKTtcbiAgICB2YXIgdjIgPSBkZWxDIC8gKEMgKiBzYyk7XG4gICAgdmFyIHYzID0gc2g7XG4gICAgcmV0dXJuIHNxcnQkNCh2MSAqIHYxICsgdjIgKiB2MiArIGRIMiAvICh2MyAqIHYzKSk7XG4gIH07IC8vIHNpbXBsZSBFdWNsaWRlYW4gZGlzdGFuY2VcblxuXG4gIHZhciBkaXN0YW5jZSA9IGZ1bmN0aW9uIGRpc3RhbmNlKGEsIGIsIG1vZGUpIHtcbiAgICBpZiAobW9kZSA9PT0gdm9pZCAwKSBtb2RlID0gJ2xhYic7IC8vIERlbHRhIEUgKENJRSAxOTc2KVxuICAgIC8vIHNlZSBodHRwOi8vd3d3LmJydWNlbGluZGJsb29tLmNvbS9pbmRleC5odG1sP0VxdWF0aW9ucy5odG1sXG5cbiAgICBhID0gbmV3IENvbG9yXzEoYSk7XG4gICAgYiA9IG5ldyBDb2xvcl8xKGIpO1xuICAgIHZhciBsMSA9IGEuZ2V0KG1vZGUpO1xuICAgIHZhciBsMiA9IGIuZ2V0KG1vZGUpO1xuICAgIHZhciBzdW1fc3EgPSAwO1xuXG4gICAgZm9yICh2YXIgaSBpbiBsMSkge1xuICAgICAgdmFyIGQgPSAobDFbaV0gfHwgMCkgLSAobDJbaV0gfHwgMCk7XG4gICAgICBzdW1fc3EgKz0gZCAqIGQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIE1hdGguc3FydChzdW1fc3EpO1xuICB9O1xuXG4gIHZhciB2YWxpZCA9IGZ1bmN0aW9uIHZhbGlkKCkge1xuICAgIHZhciBhcmdzID0gW10sXG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgIGFyZ3NbbGVuXSA9IGFyZ3VtZW50c1tsZW5dO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBuZXcgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KENvbG9yXzEsIFtudWxsXS5jb25jYXQoYXJncykpKSgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTsgLy8gc29tZSBwcmUtZGVmaW5lZCBjb2xvciBzY2FsZXM6XG5cblxuICB2YXIgc2NhbGVzID0ge1xuICAgIGNvb2w6IGZ1bmN0aW9uIGNvb2woKSB7XG4gICAgICByZXR1cm4gc2NhbGUoW2Nocm9tYV8xLmhzbCgxODAsIDEsIC45KSwgY2hyb21hXzEuaHNsKDI1MCwgLjcsIC40KV0pO1xuICAgIH0sXG4gICAgaG90OiBmdW5jdGlvbiBob3QoKSB7XG4gICAgICByZXR1cm4gc2NhbGUoWycjMDAwJywgJyNmMDAnLCAnI2ZmMCcsICcjZmZmJ10sIFswLCAuMjUsIC43NSwgMV0pLm1vZGUoJ3JnYicpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAgICBDb2xvckJyZXdlciBjb2xvcnMgZm9yIGNocm9tYS5qc1xuICAgICAgIENvcHlyaWdodCAoYykgMjAwMiBDeW50aGlhIEJyZXdlciwgTWFyayBIYXJyb3dlciwgYW5kIFRoZVxuICAgICAgUGVubnN5bHZhbmlhIFN0YXRlIFVuaXZlcnNpdHkuXG4gICAgICAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAgICAgIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAgICAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gICAgICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZFxuICAgICAgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1JcbiAgICAgIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlXG4gICAgICBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICAqL1xuXG4gIHZhciBjb2xvcmJyZXdlciA9IHtcbiAgICAvLyBzZXF1ZW50aWFsXG4gICAgT3JSZDogWycjZmZmN2VjJywgJyNmZWU4YzgnLCAnI2ZkZDQ5ZScsICcjZmRiYjg0JywgJyNmYzhkNTknLCAnI2VmNjU0OCcsICcjZDczMDFmJywgJyNiMzAwMDAnLCAnIzdmMDAwMCddLFxuICAgIFB1QnU6IFsnI2ZmZjdmYicsICcjZWNlN2YyJywgJyNkMGQxZTYnLCAnI2E2YmRkYicsICcjNzRhOWNmJywgJyMzNjkwYzAnLCAnIzA1NzBiMCcsICcjMDQ1YThkJywgJyMwMjM4NTgnXSxcbiAgICBCdVB1OiBbJyNmN2ZjZmQnLCAnI2UwZWNmNCcsICcjYmZkM2U2JywgJyM5ZWJjZGEnLCAnIzhjOTZjNicsICcjOGM2YmIxJywgJyM4ODQxOWQnLCAnIzgxMGY3YycsICcjNGQwMDRiJ10sXG4gICAgT3JhbmdlczogWycjZmZmNWViJywgJyNmZWU2Y2UnLCAnI2ZkZDBhMicsICcjZmRhZTZiJywgJyNmZDhkM2MnLCAnI2YxNjkxMycsICcjZDk0ODAxJywgJyNhNjM2MDMnLCAnIzdmMjcwNCddLFxuICAgIEJ1R246IFsnI2Y3ZmNmZCcsICcjZTVmNWY5JywgJyNjY2VjZTYnLCAnIzk5ZDhjOScsICcjNjZjMmE0JywgJyM0MWFlNzYnLCAnIzIzOGI0NScsICcjMDA2ZDJjJywgJyMwMDQ0MWInXSxcbiAgICBZbE9yQnI6IFsnI2ZmZmZlNScsICcjZmZmN2JjJywgJyNmZWUzOTEnLCAnI2ZlYzQ0ZicsICcjZmU5OTI5JywgJyNlYzcwMTQnLCAnI2NjNGMwMicsICcjOTkzNDA0JywgJyM2NjI1MDYnXSxcbiAgICBZbEduOiBbJyNmZmZmZTUnLCAnI2Y3ZmNiOScsICcjZDlmMGEzJywgJyNhZGRkOGUnLCAnIzc4YzY3OScsICcjNDFhYjVkJywgJyMyMzg0NDMnLCAnIzAwNjgzNycsICcjMDA0NTI5J10sXG4gICAgUmVkczogWycjZmZmNWYwJywgJyNmZWUwZDInLCAnI2ZjYmJhMScsICcjZmM5MjcyJywgJyNmYjZhNGEnLCAnI2VmM2IyYycsICcjY2IxODFkJywgJyNhNTBmMTUnLCAnIzY3MDAwZCddLFxuICAgIFJkUHU6IFsnI2ZmZjdmMycsICcjZmRlMGRkJywgJyNmY2M1YzAnLCAnI2ZhOWZiNScsICcjZjc2OGExJywgJyNkZDM0OTcnLCAnI2FlMDE3ZScsICcjN2EwMTc3JywgJyM0OTAwNmEnXSxcbiAgICBHcmVlbnM6IFsnI2Y3ZmNmNScsICcjZTVmNWUwJywgJyNjN2U5YzAnLCAnI2ExZDk5YicsICcjNzRjNDc2JywgJyM0MWFiNWQnLCAnIzIzOGI0NScsICcjMDA2ZDJjJywgJyMwMDQ0MWInXSxcbiAgICBZbEduQnU6IFsnI2ZmZmZkOScsICcjZWRmOGIxJywgJyNjN2U5YjQnLCAnIzdmY2RiYicsICcjNDFiNmM0JywgJyMxZDkxYzAnLCAnIzIyNWVhOCcsICcjMjUzNDk0JywgJyMwODFkNTgnXSxcbiAgICBQdXJwbGVzOiBbJyNmY2ZiZmQnLCAnI2VmZWRmNScsICcjZGFkYWViJywgJyNiY2JkZGMnLCAnIzllOWFjOCcsICcjODA3ZGJhJywgJyM2YTUxYTMnLCAnIzU0Mjc4ZicsICcjM2YwMDdkJ10sXG4gICAgR25CdTogWycjZjdmY2YwJywgJyNlMGYzZGInLCAnI2NjZWJjNScsICcjYThkZGI1JywgJyM3YmNjYzQnLCAnIzRlYjNkMycsICcjMmI4Y2JlJywgJyMwODY4YWMnLCAnIzA4NDA4MSddLFxuICAgIEdyZXlzOiBbJyNmZmZmZmYnLCAnI2YwZjBmMCcsICcjZDlkOWQ5JywgJyNiZGJkYmQnLCAnIzk2OTY5NicsICcjNzM3MzczJywgJyM1MjUyNTInLCAnIzI1MjUyNScsICcjMDAwMDAwJ10sXG4gICAgWWxPclJkOiBbJyNmZmZmY2MnLCAnI2ZmZWRhMCcsICcjZmVkOTc2JywgJyNmZWIyNGMnLCAnI2ZkOGQzYycsICcjZmM0ZTJhJywgJyNlMzFhMWMnLCAnI2JkMDAyNicsICcjODAwMDI2J10sXG4gICAgUHVSZDogWycjZjdmNGY5JywgJyNlN2UxZWYnLCAnI2Q0YjlkYScsICcjYzk5NGM3JywgJyNkZjY1YjAnLCAnI2U3Mjk4YScsICcjY2UxMjU2JywgJyM5ODAwNDMnLCAnIzY3MDAxZiddLFxuICAgIEJsdWVzOiBbJyNmN2ZiZmYnLCAnI2RlZWJmNycsICcjYzZkYmVmJywgJyM5ZWNhZTEnLCAnIzZiYWVkNicsICcjNDI5MmM2JywgJyMyMTcxYjUnLCAnIzA4NTE5YycsICcjMDgzMDZiJ10sXG4gICAgUHVCdUduOiBbJyNmZmY3ZmInLCAnI2VjZTJmMCcsICcjZDBkMWU2JywgJyNhNmJkZGInLCAnIzY3YTljZicsICcjMzY5MGMwJywgJyMwMjgxOGEnLCAnIzAxNmM1OScsICcjMDE0NjM2J10sXG4gICAgVmlyaWRpczogWycjNDQwMTU0JywgJyM0ODI3NzcnLCAnIzNmNGE4YScsICcjMzE2NzhlJywgJyMyNjgzOGYnLCAnIzFmOWQ4YScsICcjNmNjZTVhJywgJyNiNmRlMmInLCAnI2ZlZTgyNSddLFxuICAgIC8vIGRpdmVyZ2luZ1xuICAgIFNwZWN0cmFsOiBbJyM5ZTAxNDInLCAnI2Q1M2U0ZicsICcjZjQ2ZDQzJywgJyNmZGFlNjEnLCAnI2ZlZTA4YicsICcjZmZmZmJmJywgJyNlNmY1OTgnLCAnI2FiZGRhNCcsICcjNjZjMmE1JywgJyMzMjg4YmQnLCAnIzVlNGZhMiddLFxuICAgIFJkWWxHbjogWycjYTUwMDI2JywgJyNkNzMwMjcnLCAnI2Y0NmQ0MycsICcjZmRhZTYxJywgJyNmZWUwOGInLCAnI2ZmZmZiZicsICcjZDllZjhiJywgJyNhNmQ5NmEnLCAnIzY2YmQ2MycsICcjMWE5ODUwJywgJyMwMDY4MzcnXSxcbiAgICBSZEJ1OiBbJyM2NzAwMWYnLCAnI2IyMTgyYicsICcjZDY2MDRkJywgJyNmNGE1ODInLCAnI2ZkZGJjNycsICcjZjdmN2Y3JywgJyNkMWU1ZjAnLCAnIzkyYzVkZScsICcjNDM5M2MzJywgJyMyMTY2YWMnLCAnIzA1MzA2MSddLFxuICAgIFBpWUc6IFsnIzhlMDE1MicsICcjYzUxYjdkJywgJyNkZTc3YWUnLCAnI2YxYjZkYScsICcjZmRlMGVmJywgJyNmN2Y3ZjcnLCAnI2U2ZjVkMCcsICcjYjhlMTg2JywgJyM3ZmJjNDEnLCAnIzRkOTIyMScsICcjMjc2NDE5J10sXG4gICAgUFJHbjogWycjNDAwMDRiJywgJyM3NjJhODMnLCAnIzk5NzBhYicsICcjYzJhNWNmJywgJyNlN2Q0ZTgnLCAnI2Y3ZjdmNycsICcjZDlmMGQzJywgJyNhNmRiYTAnLCAnIzVhYWU2MScsICcjMWI3ODM3JywgJyMwMDQ0MWInXSxcbiAgICBSZFlsQnU6IFsnI2E1MDAyNicsICcjZDczMDI3JywgJyNmNDZkNDMnLCAnI2ZkYWU2MScsICcjZmVlMDkwJywgJyNmZmZmYmYnLCAnI2UwZjNmOCcsICcjYWJkOWU5JywgJyM3NGFkZDEnLCAnIzQ1NzViNCcsICcjMzEzNjk1J10sXG4gICAgQnJCRzogWycjNTQzMDA1JywgJyM4YzUxMGEnLCAnI2JmODEyZCcsICcjZGZjMjdkJywgJyNmNmU4YzMnLCAnI2Y1ZjVmNScsICcjYzdlYWU1JywgJyM4MGNkYzEnLCAnIzM1OTc4ZicsICcjMDE2NjVlJywgJyMwMDNjMzAnXSxcbiAgICBSZEd5OiBbJyM2NzAwMWYnLCAnI2IyMTgyYicsICcjZDY2MDRkJywgJyNmNGE1ODInLCAnI2ZkZGJjNycsICcjZmZmZmZmJywgJyNlMGUwZTAnLCAnI2JhYmFiYScsICcjODc4Nzg3JywgJyM0ZDRkNGQnLCAnIzFhMWExYSddLFxuICAgIFB1T3I6IFsnIzdmM2IwOCcsICcjYjM1ODA2JywgJyNlMDgyMTQnLCAnI2ZkYjg2MycsICcjZmVlMGI2JywgJyNmN2Y3ZjcnLCAnI2Q4ZGFlYicsICcjYjJhYmQyJywgJyM4MDczYWMnLCAnIzU0Mjc4OCcsICcjMmQwMDRiJ10sXG4gICAgLy8gcXVhbGl0YXRpdmVcbiAgICBTZXQyOiBbJyM2NmMyYTUnLCAnI2ZjOGQ2MicsICcjOGRhMGNiJywgJyNlNzhhYzMnLCAnI2E2ZDg1NCcsICcjZmZkOTJmJywgJyNlNWM0OTQnLCAnI2IzYjNiMyddLFxuICAgIEFjY2VudDogWycjN2ZjOTdmJywgJyNiZWFlZDQnLCAnI2ZkYzA4NicsICcjZmZmZjk5JywgJyMzODZjYjAnLCAnI2YwMDI3ZicsICcjYmY1YjE3JywgJyM2NjY2NjYnXSxcbiAgICBTZXQxOiBbJyNlNDFhMWMnLCAnIzM3N2ViOCcsICcjNGRhZjRhJywgJyM5ODRlYTMnLCAnI2ZmN2YwMCcsICcjZmZmZjMzJywgJyNhNjU2MjgnLCAnI2Y3ODFiZicsICcjOTk5OTk5J10sXG4gICAgU2V0MzogWycjOGRkM2M3JywgJyNmZmZmYjMnLCAnI2JlYmFkYScsICcjZmI4MDcyJywgJyM4MGIxZDMnLCAnI2ZkYjQ2MicsICcjYjNkZTY5JywgJyNmY2NkZTUnLCAnI2Q5ZDlkOScsICcjYmM4MGJkJywgJyNjY2ViYzUnLCAnI2ZmZWQ2ZiddLFxuICAgIERhcmsyOiBbJyMxYjllNzcnLCAnI2Q5NWYwMicsICcjNzU3MGIzJywgJyNlNzI5OGEnLCAnIzY2YTYxZScsICcjZTZhYjAyJywgJyNhNjc2MWQnLCAnIzY2NjY2NiddLFxuICAgIFBhaXJlZDogWycjYTZjZWUzJywgJyMxZjc4YjQnLCAnI2IyZGY4YScsICcjMzNhMDJjJywgJyNmYjlhOTknLCAnI2UzMWExYycsICcjZmRiZjZmJywgJyNmZjdmMDAnLCAnI2NhYjJkNicsICcjNmEzZDlhJywgJyNmZmZmOTknLCAnI2IxNTkyOCddLFxuICAgIFBhc3RlbDI6IFsnI2IzZTJjZCcsICcjZmRjZGFjJywgJyNjYmQ1ZTgnLCAnI2Y0Y2FlNCcsICcjZTZmNWM5JywgJyNmZmYyYWUnLCAnI2YxZTJjYycsICcjY2NjY2NjJ10sXG4gICAgUGFzdGVsMTogWycjZmJiNGFlJywgJyNiM2NkZTMnLCAnI2NjZWJjNScsICcjZGVjYmU0JywgJyNmZWQ5YTYnLCAnI2ZmZmZjYycsICcjZTVkOGJkJywgJyNmZGRhZWMnLCAnI2YyZjJmMiddXG4gIH07IC8vIGFkZCBsb3dlcmNhc2UgYWxpYXNlcyBmb3IgY2FzZS1pbnNlbnNpdGl2ZSBtYXRjaGVzXG5cbiAgZm9yICh2YXIgaSQxID0gMCwgbGlzdCQxID0gT2JqZWN0LmtleXMoY29sb3JicmV3ZXIpOyBpJDEgPCBsaXN0JDEubGVuZ3RoOyBpJDEgKz0gMSkge1xuICAgIHZhciBrZXkgPSBsaXN0JDFbaSQxXTtcbiAgICBjb2xvcmJyZXdlcltrZXkudG9Mb3dlckNhc2UoKV0gPSBjb2xvcmJyZXdlcltrZXldO1xuICB9XG5cbiAgdmFyIGNvbG9yYnJld2VyXzEgPSBjb2xvcmJyZXdlcjsgLy8gZmVlbCBmcmVlIHRvIGNvbW1lbnQgb3V0IGFueXRoaW5nIHRvIHJvbGx1cFxuICAvLyBhIHNtYWxsZXIgY2hyb21hLmpzIGJ1aWx0XG4gIC8vIGlvIC0tPiBjb252ZXJ0IGNvbG9yc1xuICAvLyBvcGVyYXRvcnMgLS0+IG1vZGlmeSBleGlzdGluZyBDb2xvcnNcbiAgLy8gaW50ZXJwb2xhdG9yc1xuICAvLyBnZW5lcmF0b3JzIC0tID4gY3JlYXRlIG5ldyBjb2xvcnNcblxuICBjaHJvbWFfMS5hdmVyYWdlID0gYXZlcmFnZTtcbiAgY2hyb21hXzEuYmV6aWVyID0gYmV6aWVyXzE7XG4gIGNocm9tYV8xLmJsZW5kID0gYmxlbmRfMTtcbiAgY2hyb21hXzEuY3ViZWhlbGl4ID0gY3ViZWhlbGl4O1xuICBjaHJvbWFfMS5taXggPSBjaHJvbWFfMS5pbnRlcnBvbGF0ZSA9IG1peDtcbiAgY2hyb21hXzEucmFuZG9tID0gcmFuZG9tXzE7XG4gIGNocm9tYV8xLnNjYWxlID0gc2NhbGU7IC8vIG90aGVyIHV0aWxpdHkgbWV0aG9kc1xuXG4gIGNocm9tYV8xLmFuYWx5emUgPSBhbmFseXplXzEuYW5hbHl6ZTtcbiAgY2hyb21hXzEuY29udHJhc3QgPSBjb250cmFzdDtcbiAgY2hyb21hXzEuZGVsdGFFID0gZGVsdGFFO1xuICBjaHJvbWFfMS5kaXN0YW5jZSA9IGRpc3RhbmNlO1xuICBjaHJvbWFfMS5saW1pdHMgPSBhbmFseXplXzEubGltaXRzO1xuICBjaHJvbWFfMS52YWxpZCA9IHZhbGlkOyAvLyBzY2FsZVxuXG4gIGNocm9tYV8xLnNjYWxlcyA9IHNjYWxlczsgLy8gY29sb3JzXG5cbiAgY2hyb21hXzEuY29sb3JzID0gdzNjeDExXzE7XG4gIGNocm9tYV8xLmJyZXdlciA9IGNvbG9yYnJld2VyXzE7XG4gIHZhciBjaHJvbWFfanMgPSBjaHJvbWFfMTtcbiAgcmV0dXJuIGNocm9tYV9qcztcbn0pOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///3873\n")},2846:function(__unused_webpack_module,exports){eval("/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var nBits = -7;\n var i = isLE ? nBytes - 1 : 0;\n var d = isLE ? -1 : 1;\n var s = buffer[offset + i];\n i += d;\n e = s & (1 << -nBits) - 1;\n s >>= -nBits;\n nBits += eLen;\n\n for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & (1 << -nBits) - 1;\n e >>= -nBits;\n nBits += mLen;\n\n for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias;\n } else if (e === eMax) {\n return m ? NaN : (s ? -1 : 1) * Infinity;\n } else {\n m = m + Math.pow(2, mLen);\n e = e - eBias;\n }\n\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen);\n};\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c;\n var eLen = nBytes * 8 - mLen - 1;\n var eMax = (1 << eLen) - 1;\n var eBias = eMax >> 1;\n var rt = mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0;\n var i = isLE ? 0 : nBytes - 1;\n var d = isLE ? 1 : -1;\n var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;\n value = Math.abs(value);\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0;\n e = eMax;\n } else {\n e = Math.floor(Math.log(value) / Math.LN2);\n\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--;\n c *= 2;\n }\n\n if (e + eBias >= 1) {\n value += rt / c;\n } else {\n value += rt * Math.pow(2, 1 - eBias);\n }\n\n if (value * c >= 2) {\n e++;\n c /= 2;\n }\n\n if (e + eBias >= eMax) {\n m = 0;\n e = eMax;\n } else if (e + eBias >= 1) {\n m = (value * c - 1) * Math.pow(2, mLen);\n e = e + eBias;\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);\n e = 0;\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = e << mLen | m;\n eLen += mLen;\n\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzPzBiNzkiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBOztBQUVBLFFBQVEsV0FBVzs7QUFFbkI7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsUUFBUSxXQUFXOztBQUVuQjtBQUNBOztBQUVBLFFBQVEsVUFBVTs7QUFFbEI7QUFDQSIsImZpbGUiOiIyODQ2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohIGllZWU3NTQuIEJTRC0zLUNsYXVzZSBMaWNlbnNlLiBGZXJvc3MgQWJvdWtoYWRpamVoIDxodHRwczovL2Zlcm9zcy5vcmcvb3BlbnNvdXJjZT4gKi9cbmV4cG9ydHMucmVhZCA9IGZ1bmN0aW9uIChidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtO1xuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMTtcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDE7XG4gIHZhciBlQmlhcyA9IGVNYXggPj4gMTtcbiAgdmFyIG5CaXRzID0gLTc7XG4gIHZhciBpID0gaXNMRSA/IG5CeXRlcyAtIDEgOiAwO1xuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDE7XG4gIHZhciBzID0gYnVmZmVyW29mZnNldCArIGldO1xuICBpICs9IGQ7XG4gIGUgPSBzICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIHMgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gZUxlbjtcblxuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIG0gPSBlICYgKDEgPDwgLW5CaXRzKSAtIDE7XG4gIGUgPj49IC1uQml0cztcbiAgbkJpdHMgKz0gbUxlbjtcblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAocyA/IC0xIDogMSkgKiBJbmZpbml0eTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cblxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcbn07XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGM7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgcnQgPSBtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMDtcbiAgdmFyIGkgPSBpc0xFID8gMCA6IG5CeXRlcyAtIDE7XG4gIHZhciBkID0gaXNMRSA/IDEgOiAtMTtcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwO1xuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG5cbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuXG4gICAgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICB2YWx1ZSArPSBydCAvIGM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlICs9IHJ0ICogTWF0aC5wb3coMiwgMSAtIGVCaWFzKTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCkge31cblxuICBlID0gZSA8PCBtTGVuIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjg7XG59OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2846\n")},5978:function(module){eval("var fontWeights = {\n thin: 100,\n hairline: 100,\n 'ultra-light': 100,\n 'extra-light': 100,\n light: 200,\n book: 300,\n regular: 400,\n normal: 400,\n plain: 400,\n roman: 400,\n standard: 400,\n medium: 500,\n 'semi-bold': 600,\n 'demi-bold': 600,\n bold: 700,\n heavy: 800,\n black: 800,\n 'extra-bold': 800,\n 'ultra-black': 900,\n 'extra-black': 900,\n 'ultra-bold': 900,\n 'heavy-black': 900,\n fat: 900,\n poster: 900\n};\nvar sp = ' ';\nvar italicRE = /(italic|oblique)$/i;\nvar fontCache = {};\n\nmodule.exports = function (fonts, size, lineHeight) {\n var cssData = fontCache[fonts];\n\n if (!cssData) {\n if (!Array.isArray(fonts)) {\n fonts = [fonts];\n }\n\n var weight = 400;\n var style = 'normal';\n var fontFamilies = [];\n var haveWeight, haveStyle;\n\n for (var i = 0, ii = fonts.length; i < ii; ++i) {\n var font = fonts[i];\n var parts = font.split(' ');\n var maybeWeight = parts[parts.length - 1].toLowerCase();\n\n if (maybeWeight == 'normal' || maybeWeight == 'italic' || maybeWeight == 'oblique') {\n style = haveStyle ? style : maybeWeight;\n parts.pop();\n maybeWeight = parts[parts.length - 1].toLowerCase();\n } else if (italicRE.test(maybeWeight)) {\n maybeWeight = maybeWeight.replace(italicRE, '');\n style = haveStyle ? style : parts[parts.length - 1].replace(maybeWeight, '');\n }\n\n for (var w in fontWeights) {\n if (maybeWeight == w || maybeWeight == w.replace('-', '') || maybeWeight == w.replace('-', sp)) {\n weight = haveWeight ? weight : fontWeights[w];\n parts.pop();\n break;\n }\n }\n\n if (!haveWeight && typeof maybeWeight == 'number') {\n weight = maybeWeight;\n }\n\n var fontFamily = parts.join(sp).replace('Klokantech Noto Sans', 'Noto Sans');\n\n if (fontFamily.indexOf(sp) !== -1) {\n fontFamily = '\"' + fontFamily + '\"';\n }\n\n fontFamilies.push(fontFamily);\n } // CSS font property: font-style font-weight font-size/line-height font-family\n\n\n cssData = fontCache[fonts] = [style, weight, fontFamilies];\n }\n\n return cssData[0] + sp + cssData[1] + sp + size + 'px' + (lineHeight ? '/' + lineHeight : '') + sp + cssData[2];\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9tYXBib3gtdG8tY3NzLWZvbnQvaW5kZXguanM/M2VhNSJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0NBQXNDLFFBQVE7QUFDOUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQTs7QUFFQTtBQUNBIiwiZmlsZSI6IjU5NzguanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgZm9udFdlaWdodHMgPSB7XG4gIHRoaW46IDEwMCxcbiAgaGFpcmxpbmU6IDEwMCxcbiAgJ3VsdHJhLWxpZ2h0JzogMTAwLFxuICAnZXh0cmEtbGlnaHQnOiAxMDAsXG4gIGxpZ2h0OiAyMDAsXG4gIGJvb2s6IDMwMCxcbiAgcmVndWxhcjogNDAwLFxuICBub3JtYWw6IDQwMCxcbiAgcGxhaW46IDQwMCxcbiAgcm9tYW46IDQwMCxcbiAgc3RhbmRhcmQ6IDQwMCxcbiAgbWVkaXVtOiA1MDAsXG4gICdzZW1pLWJvbGQnOiA2MDAsXG4gICdkZW1pLWJvbGQnOiA2MDAsXG4gIGJvbGQ6IDcwMCxcbiAgaGVhdnk6IDgwMCxcbiAgYmxhY2s6IDgwMCxcbiAgJ2V4dHJhLWJvbGQnOiA4MDAsXG4gICd1bHRyYS1ibGFjayc6IDkwMCxcbiAgJ2V4dHJhLWJsYWNrJzogOTAwLFxuICAndWx0cmEtYm9sZCc6IDkwMCxcbiAgJ2hlYXZ5LWJsYWNrJzogOTAwLFxuICBmYXQ6IDkwMCxcbiAgcG9zdGVyOiA5MDBcbn07XG52YXIgc3AgPSAnICc7XG52YXIgaXRhbGljUkUgPSAvKGl0YWxpY3xvYmxpcXVlKSQvaTtcbnZhciBmb250Q2FjaGUgPSB7fTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZm9udHMsIHNpemUsIGxpbmVIZWlnaHQpIHtcbiAgdmFyIGNzc0RhdGEgPSBmb250Q2FjaGVbZm9udHNdO1xuXG4gIGlmICghY3NzRGF0YSkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShmb250cykpIHtcbiAgICAgIGZvbnRzID0gW2ZvbnRzXTtcbiAgICB9XG5cbiAgICB2YXIgd2VpZ2h0ID0gNDAwO1xuICAgIHZhciBzdHlsZSA9ICdub3JtYWwnO1xuICAgIHZhciBmb250RmFtaWxpZXMgPSBbXTtcbiAgICB2YXIgaGF2ZVdlaWdodCwgaGF2ZVN0eWxlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZm9udHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGZvbnQgPSBmb250c1tpXTtcbiAgICAgIHZhciBwYXJ0cyA9IGZvbnQuc3BsaXQoJyAnKTtcbiAgICAgIHZhciBtYXliZVdlaWdodCA9IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGlmIChtYXliZVdlaWdodCA9PSAnbm9ybWFsJyB8fCBtYXliZVdlaWdodCA9PSAnaXRhbGljJyB8fCBtYXliZVdlaWdodCA9PSAnb2JsaXF1ZScpIHtcbiAgICAgICAgc3R5bGUgPSBoYXZlU3R5bGUgPyBzdHlsZSA6IG1heWJlV2VpZ2h0O1xuICAgICAgICBwYXJ0cy5wb3AoKTtcbiAgICAgICAgbWF5YmVXZWlnaHQgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXS50b0xvd2VyQ2FzZSgpO1xuICAgICAgfSBlbHNlIGlmIChpdGFsaWNSRS50ZXN0KG1heWJlV2VpZ2h0KSkge1xuICAgICAgICBtYXliZVdlaWdodCA9IG1heWJlV2VpZ2h0LnJlcGxhY2UoaXRhbGljUkUsICcnKTtcbiAgICAgICAgc3R5bGUgPSBoYXZlU3R5bGUgPyBzdHlsZSA6IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdLnJlcGxhY2UobWF5YmVXZWlnaHQsICcnKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgdyBpbiBmb250V2VpZ2h0cykge1xuICAgICAgICBpZiAobWF5YmVXZWlnaHQgPT0gdyB8fCBtYXliZVdlaWdodCA9PSB3LnJlcGxhY2UoJy0nLCAnJykgfHwgbWF5YmVXZWlnaHQgPT0gdy5yZXBsYWNlKCctJywgc3ApKSB7XG4gICAgICAgICAgd2VpZ2h0ID0gaGF2ZVdlaWdodCA/IHdlaWdodCA6IGZvbnRXZWlnaHRzW3ddO1xuICAgICAgICAgIHBhcnRzLnBvcCgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghaGF2ZVdlaWdodCAmJiB0eXBlb2YgbWF5YmVXZWlnaHQgPT0gJ251bWJlcicpIHtcbiAgICAgICAgd2VpZ2h0ID0gbWF5YmVXZWlnaHQ7XG4gICAgICB9XG5cbiAgICAgIHZhciBmb250RmFtaWx5ID0gcGFydHMuam9pbihzcCkucmVwbGFjZSgnS2xva2FudGVjaCBOb3RvIFNhbnMnLCAnTm90byBTYW5zJyk7XG5cbiAgICAgIGlmIChmb250RmFtaWx5LmluZGV4T2Yoc3ApICE9PSAtMSkge1xuICAgICAgICBmb250RmFtaWx5ID0gJ1wiJyArIGZvbnRGYW1pbHkgKyAnXCInO1xuICAgICAgfVxuXG4gICAgICBmb250RmFtaWxpZXMucHVzaChmb250RmFtaWx5KTtcbiAgICB9IC8vIENTUyBmb250IHByb3BlcnR5OiBmb250LXN0eWxlIGZvbnQtd2VpZ2h0IGZvbnQtc2l6ZS9saW5lLWhlaWdodCBmb250LWZhbWlseVxuXG5cbiAgICBjc3NEYXRhID0gZm9udENhY2hlW2ZvbnRzXSA9IFtzdHlsZSwgd2VpZ2h0LCBmb250RmFtaWxpZXNdO1xuICB9XG5cbiAgcmV0dXJuIGNzc0RhdGFbMF0gKyBzcCArIGNzc0RhdGFbMV0gKyBzcCArIHNpemUgKyAncHgnICsgKGxpbmVIZWlnaHQgPyAnLycgKyBsaW5lSGVpZ2h0IDogJycpICsgc3AgKyBjc3NEYXRhWzJdO1xufTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5978\n")},4362:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = Pbf;\n\nvar ieee754 = __webpack_require__(2846);\n\nfunction Pbf(buf) {\n this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);\n this.pos = 0;\n this.type = 0;\n this.length = this.buf.length;\n}\n\nPbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum\n\nPbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64\n\nPbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields\n\nPbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32\n\nvar SHIFT_LEFT_32 = (1 << 16) * (1 << 16),\n SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32; // Threshold chosen based on both benchmarking and knowledge about browser string\n// data structures (which currently switch structure types at 12 bytes or more)\n\nvar TEXT_DECODER_MIN_LENGTH = 12;\nvar utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8');\nPbf.prototype = {\n destroy: function destroy() {\n this.buf = null;\n },\n // === READING =================================================================\n readFields: function readFields(readField, result, end) {\n end = end || this.length;\n\n while (this.pos < end) {\n var val = this.readVarint(),\n tag = val >> 3,\n startPos = this.pos;\n this.type = val & 0x7;\n readField(tag, result, this);\n if (this.pos === startPos) this.skip(val);\n }\n\n return result;\n },\n readMessage: function readMessage(readField, result) {\n return this.readFields(readField, result, this.readVarint() + this.pos);\n },\n readFixed32: function readFixed32() {\n var val = readUInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n readSFixed32: function readSFixed32() {\n var val = readInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)\n readFixed64: function readFixed64() {\n var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n readSFixed64: function readSFixed64() {\n var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n readFloat: function readFloat() {\n var val = ieee754.read(this.buf, this.pos, true, 23, 4);\n this.pos += 4;\n return val;\n },\n readDouble: function readDouble() {\n var val = ieee754.read(this.buf, this.pos, true, 52, 8);\n this.pos += 8;\n return val;\n },\n readVarint: function readVarint(isSigned) {\n var buf = this.buf,\n val,\n b;\n b = buf[this.pos++];\n val = b & 0x7f;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 7;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 14;\n if (b < 0x80) return val;\n b = buf[this.pos++];\n val |= (b & 0x7f) << 21;\n if (b < 0x80) return val;\n b = buf[this.pos];\n val |= (b & 0x0f) << 28;\n return readVarintRemainder(val, isSigned, this);\n },\n readVarint64: function readVarint64() {\n // for compatibility with v2.0.1\n return this.readVarint(true);\n },\n readSVarint: function readSVarint() {\n var num = this.readVarint();\n return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding\n },\n readBoolean: function readBoolean() {\n return Boolean(this.readVarint());\n },\n readString: function readString() {\n var end = this.readVarint() + this.pos;\n var pos = this.pos;\n this.pos = end;\n\n if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {\n // longer strings are fast with the built-in browser TextDecoder API\n return readUtf8TextDecoder(this.buf, pos, end);\n } // short strings are fast with our custom implementation\n\n\n return readUtf8(this.buf, pos, end);\n },\n readBytes: function readBytes() {\n var end = this.readVarint() + this.pos,\n buffer = this.buf.subarray(this.pos, end);\n this.pos = end;\n return buffer;\n },\n // verbose for performance reasons; doesn't affect gzipped size\n readPackedVarint: function readPackedVarint(arr, isSigned) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned));\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readVarint(isSigned));\n }\n\n return arr;\n },\n readPackedSVarint: function readPackedSVarint(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSVarint());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSVarint());\n }\n\n return arr;\n },\n readPackedBoolean: function readPackedBoolean(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readBoolean());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readBoolean());\n }\n\n return arr;\n },\n readPackedFloat: function readPackedFloat(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFloat());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFloat());\n }\n\n return arr;\n },\n readPackedDouble: function readPackedDouble(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readDouble());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readDouble());\n }\n\n return arr;\n },\n readPackedFixed32: function readPackedFixed32(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFixed32());\n }\n\n return arr;\n },\n readPackedSFixed32: function readPackedSFixed32(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSFixed32());\n }\n\n return arr;\n },\n readPackedFixed64: function readPackedFixed64(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readFixed64());\n }\n\n return arr;\n },\n readPackedSFixed64: function readPackedSFixed64(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n\n while (this.pos < end) {\n arr.push(this.readSFixed64());\n }\n\n return arr;\n },\n skip: function skip(val) {\n var type = val & 0x7;\n if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {} else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;else if (type === Pbf.Fixed32) this.pos += 4;else if (type === Pbf.Fixed64) this.pos += 8;else throw new Error('Unimplemented type: ' + type);\n },\n // === WRITING =================================================================\n writeTag: function writeTag(tag, type) {\n this.writeVarint(tag << 3 | type);\n },\n realloc: function realloc(min) {\n var length = this.length || 16;\n\n while (length < this.pos + min) {\n length *= 2;\n }\n\n if (length !== this.length) {\n var buf = new Uint8Array(length);\n buf.set(this.buf);\n this.buf = buf;\n this.length = length;\n }\n },\n finish: function finish() {\n this.length = this.pos;\n this.pos = 0;\n return this.buf.subarray(0, this.length);\n },\n writeFixed32: function writeFixed32(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n writeSFixed32: function writeSFixed32(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n writeFixed64: function writeFixed64(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n writeSFixed64: function writeSFixed64(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n writeVarint: function writeVarint(val) {\n val = +val || 0;\n\n if (val > 0xfffffff || val < 0) {\n writeBigVarint(val, this);\n return;\n }\n\n this.realloc(4);\n this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = (val >>>= 7) & 0x7f | (val > 0x7f ? 0x80 : 0);\n if (val <= 0x7f) return;\n this.buf[this.pos++] = val >>> 7 & 0x7f;\n },\n writeSVarint: function writeSVarint(val) {\n this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);\n },\n writeBoolean: function writeBoolean(val) {\n this.writeVarint(Boolean(val));\n },\n writeString: function writeString(str) {\n str = String(str);\n this.realloc(str.length * 4);\n this.pos++; // reserve 1 byte for short string length\n\n var startPos = this.pos; // write the string directly to the buffer and see how much was written\n\n this.pos = writeUtf8(this.buf, str, this.pos);\n var len = this.pos - startPos;\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position\n\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n writeFloat: function writeFloat(val) {\n this.realloc(4);\n ieee754.write(this.buf, val, this.pos, true, 23, 4);\n this.pos += 4;\n },\n writeDouble: function writeDouble(val) {\n this.realloc(8);\n ieee754.write(this.buf, val, this.pos, true, 52, 8);\n this.pos += 8;\n },\n writeBytes: function writeBytes(buffer) {\n var len = buffer.length;\n this.writeVarint(len);\n this.realloc(len);\n\n for (var i = 0; i < len; i++) {\n this.buf[this.pos++] = buffer[i];\n }\n },\n writeRawMessage: function writeRawMessage(fn, obj) {\n this.pos++; // reserve 1 byte for short message length\n // write the message directly to the buffer and see how much was written\n\n var startPos = this.pos;\n fn(obj, this);\n var len = this.pos - startPos;\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this); // finally, write the message length in the reserved place and restore the position\n\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n writeMessage: function writeMessage(tag, fn, obj) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeRawMessage(fn, obj);\n },\n writePackedVarint: function writePackedVarint(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedVarint, arr);\n },\n writePackedSVarint: function writePackedSVarint(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSVarint, arr);\n },\n writePackedBoolean: function writePackedBoolean(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedBoolean, arr);\n },\n writePackedFloat: function writePackedFloat(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFloat, arr);\n },\n writePackedDouble: function writePackedDouble(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedDouble, arr);\n },\n writePackedFixed32: function writePackedFixed32(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFixed, arr);\n },\n writePackedSFixed32: function writePackedSFixed32(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSFixed, arr);\n },\n writePackedFixed64: function writePackedFixed64(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedFixed2, arr);\n },\n writePackedSFixed64: function writePackedSFixed64(tag, arr) {\n if (arr.length) this.writeMessage(tag, _writePackedSFixed2, arr);\n },\n writeBytesField: function writeBytesField(tag, buffer) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeBytes(buffer);\n },\n writeFixed32Field: function writeFixed32Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFixed32(val);\n },\n writeSFixed32Field: function writeSFixed32Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeSFixed32(val);\n },\n writeFixed64Field: function writeFixed64Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeFixed64(val);\n },\n writeSFixed64Field: function writeSFixed64Field(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeSFixed64(val);\n },\n writeVarintField: function writeVarintField(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeVarint(val);\n },\n writeSVarintField: function writeSVarintField(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeSVarint(val);\n },\n writeStringField: function writeStringField(tag, str) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeString(str);\n },\n writeFloatField: function writeFloatField(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFloat(val);\n },\n writeDoubleField: function writeDoubleField(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeDouble(val);\n },\n writeBooleanField: function writeBooleanField(tag, val) {\n this.writeVarintField(tag, Boolean(val));\n }\n};\n\nfunction readVarintRemainder(l, s, p) {\n var buf = p.buf,\n h,\n b;\n b = buf[p.pos++];\n h = (b & 0x70) >> 4;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 3;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 10;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 17;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x7f) << 24;\n if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++];\n h |= (b & 0x01) << 31;\n if (b < 0x80) return toNum(l, h, s);\n throw new Error('Expected varint not more than 10 bytes');\n}\n\nfunction readPackedEnd(pbf) {\n return pbf.type === Pbf.Bytes ? pbf.readVarint() + pbf.pos : pbf.pos + 1;\n}\n\nfunction toNum(low, high, isSigned) {\n if (isSigned) {\n return high * 0x100000000 + (low >>> 0);\n }\n\n return (high >>> 0) * 0x100000000 + (low >>> 0);\n}\n\nfunction writeBigVarint(val, pbf) {\n var low, high;\n\n if (val >= 0) {\n low = val % 0x100000000 | 0;\n high = val / 0x100000000 | 0;\n } else {\n low = ~(-val % 0x100000000);\n high = ~(-val / 0x100000000);\n\n if (low ^ 0xffffffff) {\n low = low + 1 | 0;\n } else {\n low = 0;\n high = high + 1 | 0;\n }\n }\n\n if (val >= 0x10000000000000000 || val < -0x10000000000000000) {\n throw new Error('Given varint doesn\\'t fit into 10 bytes');\n }\n\n pbf.realloc(10);\n writeBigVarintLow(low, high, pbf);\n writeBigVarintHigh(high, pbf);\n}\n\nfunction writeBigVarintLow(low, high, pbf) {\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80;\n low >>>= 7;\n pbf.buf[pbf.pos] = low & 0x7f;\n}\n\nfunction writeBigVarintHigh(high, pbf) {\n var lsb = (high & 0x07) << 4;\n pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0);\n if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f;\n}\n\nfunction makeRoomForExtraLength(startPos, len, pbf) {\n var extraLen = len <= 0x3fff ? 1 : len <= 0x1fffff ? 2 : len <= 0xfffffff ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7)); // if 1 byte isn't enough for encoding message length, shift the data to the right\n\n pbf.realloc(extraLen);\n\n for (var i = pbf.pos - 1; i >= startPos; i--) {\n pbf.buf[i + extraLen] = pbf.buf[i];\n }\n}\n\nfunction _writePackedVarint(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeVarint(arr[i]);\n }\n}\n\nfunction _writePackedSVarint(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSVarint(arr[i]);\n }\n}\n\nfunction _writePackedFloat(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFloat(arr[i]);\n }\n}\n\nfunction _writePackedDouble(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeDouble(arr[i]);\n }\n}\n\nfunction _writePackedBoolean(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeBoolean(arr[i]);\n }\n}\n\nfunction _writePackedFixed(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFixed32(arr[i]);\n }\n}\n\nfunction _writePackedSFixed(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSFixed32(arr[i]);\n }\n}\n\nfunction _writePackedFixed2(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeFixed64(arr[i]);\n }\n}\n\nfunction _writePackedSFixed2(arr, pbf) {\n for (var i = 0; i < arr.length; i++) {\n pbf.writeSFixed64(arr[i]);\n }\n} // Buffer code below from https://github.com/feross/buffer, MIT-licensed\n\n\nfunction readUInt32(buf, pos) {\n return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + buf[pos + 3] * 0x1000000;\n}\n\nfunction writeInt32(buf, val, pos) {\n buf[pos] = val;\n buf[pos + 1] = val >>> 8;\n buf[pos + 2] = val >>> 16;\n buf[pos + 3] = val >>> 24;\n}\n\nfunction readInt32(buf, pos) {\n return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16) + (buf[pos + 3] << 24);\n}\n\nfunction readUtf8(buf, pos, end) {\n var str = '';\n var i = pos;\n\n while (i < end) {\n var b0 = buf[i];\n var c = null; // codepoint\n\n var bytesPerSequence = b0 > 0xEF ? 4 : b0 > 0xDF ? 3 : b0 > 0xBF ? 2 : 1;\n if (i + bytesPerSequence > end) break;\n var b1, b2, b3;\n\n if (bytesPerSequence === 1) {\n if (b0 < 0x80) {\n c = b0;\n }\n } else if (bytesPerSequence === 2) {\n b1 = buf[i + 1];\n\n if ((b1 & 0xC0) === 0x80) {\n c = (b0 & 0x1F) << 0x6 | b1 & 0x3F;\n\n if (c <= 0x7F) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 3) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | b2 & 0x3F;\n\n if (c <= 0x7FF || c >= 0xD800 && c <= 0xDFFF) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 4) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n b3 = buf[i + 3];\n\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | b3 & 0x3F;\n\n if (c <= 0xFFFF || c >= 0x110000) {\n c = null;\n }\n }\n }\n\n if (c === null) {\n c = 0xFFFD;\n bytesPerSequence = 1;\n } else if (c > 0xFFFF) {\n c -= 0x10000;\n str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);\n c = 0xDC00 | c & 0x3FF;\n }\n\n str += String.fromCharCode(c);\n i += bytesPerSequence;\n }\n\n return str;\n}\n\nfunction readUtf8TextDecoder(buf, pos, end) {\n return utf8TextDecoder.decode(buf.subarray(pos, end));\n}\n\nfunction writeUtf8(buf, str, pos) {\n for (var i = 0, c, lead; i < str.length; i++) {\n c = str.charCodeAt(i); // code point\n\n if (c > 0xD7FF && c < 0xE000) {\n if (lead) {\n if (c < 0xDC00) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = c;\n continue;\n } else {\n c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;\n lead = null;\n }\n } else {\n if (c > 0xDBFF || i + 1 === str.length) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n } else {\n lead = c;\n }\n\n continue;\n }\n } else if (lead) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = null;\n }\n\n if (c < 0x80) {\n buf[pos++] = c;\n } else {\n if (c < 0x800) {\n buf[pos++] = c >> 0x6 | 0xC0;\n } else {\n if (c < 0x10000) {\n buf[pos++] = c >> 0xC | 0xE0;\n } else {\n buf[pos++] = c >> 0x12 | 0xF0;\n buf[pos++] = c >> 0xC & 0x3F | 0x80;\n }\n\n buf[pos++] = c >> 0x6 & 0x3F | 0x80;\n }\n\n buf[pos++] = c & 0x3F | 0x80;\n }\n }\n\n return pos;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9wYmYvaW5kZXguanM/NmVmZCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjs7QUFFQSxjQUFjLG1CQUFPLENBQUMsSUFBUzs7QUFFL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGVBQWU7O0FBRWYsZ0JBQWdCOztBQUVoQixjQUFjOztBQUVkLGdCQUFnQjs7QUFFaEI7QUFDQSx1Q0FBdUM7QUFDdkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7O0FBR0w7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLG1FQUFtRSxzRUFBc0UsNkNBQTZDLDZDQUE2QztBQUNuTyxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxlQUFlOztBQUVmLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBLGlFQUFpRTs7QUFFakU7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxlQUFlO0FBQ2Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFOztBQUVqRTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2SEFBNkg7O0FBRTdIOztBQUVBLDJCQUEyQixlQUFlO0FBQzFDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixnQkFBZ0I7QUFDakM7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCLGdCQUFnQjtBQUNqQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQSxDQUFDOzs7QUFHRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBCQUEwQixnQkFBZ0I7QUFDMUMsMEJBQTBCOztBQUUxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSIsImZpbGUiOiI0MzYyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBiZjtcblxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0Jyk7XG5cbmZ1bmN0aW9uIFBiZihidWYpIHtcbiAgdGhpcy5idWYgPSBBcnJheUJ1ZmZlci5pc1ZpZXcgJiYgQXJyYXlCdWZmZXIuaXNWaWV3KGJ1ZikgPyBidWYgOiBuZXcgVWludDhBcnJheShidWYgfHwgMCk7XG4gIHRoaXMucG9zID0gMDtcbiAgdGhpcy50eXBlID0gMDtcbiAgdGhpcy5sZW5ndGggPSB0aGlzLmJ1Zi5sZW5ndGg7XG59XG5cblBiZi5WYXJpbnQgPSAwOyAvLyB2YXJpbnQ6IGludDMyLCBpbnQ2NCwgdWludDMyLCB1aW50NjQsIHNpbnQzMiwgc2ludDY0LCBib29sLCBlbnVtXG5cblBiZi5GaXhlZDY0ID0gMTsgLy8gNjQtYml0OiBkb3VibGUsIGZpeGVkNjQsIHNmaXhlZDY0XG5cblBiZi5CeXRlcyA9IDI7IC8vIGxlbmd0aC1kZWxpbWl0ZWQ6IHN0cmluZywgYnl0ZXMsIGVtYmVkZGVkIG1lc3NhZ2VzLCBwYWNrZWQgcmVwZWF0ZWQgZmllbGRzXG5cblBiZi5GaXhlZDMyID0gNTsgLy8gMzItYml0OiBmbG9hdCwgZml4ZWQzMiwgc2ZpeGVkMzJcblxudmFyIFNISUZUX0xFRlRfMzIgPSAoMSA8PCAxNikgKiAoMSA8PCAxNiksXG4gICAgU0hJRlRfUklHSFRfMzIgPSAxIC8gU0hJRlRfTEVGVF8zMjsgLy8gVGhyZXNob2xkIGNob3NlbiBiYXNlZCBvbiBib3RoIGJlbmNobWFya2luZyBhbmQga25vd2xlZGdlIGFib3V0IGJyb3dzZXIgc3RyaW5nXG4vLyBkYXRhIHN0cnVjdHVyZXMgKHdoaWNoIGN1cnJlbnRseSBzd2l0Y2ggc3RydWN0dXJlIHR5cGVzIGF0IDEyIGJ5dGVzIG9yIG1vcmUpXG5cbnZhciBURVhUX0RFQ09ERVJfTUlOX0xFTkdUSCA9IDEyO1xudmFyIHV0ZjhUZXh0RGVjb2RlciA9IHR5cGVvZiBUZXh0RGVjb2RlciA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogbmV3IFRleHREZWNvZGVyKCd1dGY4Jyk7XG5QYmYucHJvdG90eXBlID0ge1xuICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgIHRoaXMuYnVmID0gbnVsbDtcbiAgfSxcbiAgLy8gPT09IFJFQURJTkcgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgcmVhZEZpZWxkczogZnVuY3Rpb24gcmVhZEZpZWxkcyhyZWFkRmllbGQsIHJlc3VsdCwgZW5kKSB7XG4gICAgZW5kID0gZW5kIHx8IHRoaXMubGVuZ3RoO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICB2YXIgdmFsID0gdGhpcy5yZWFkVmFyaW50KCksXG4gICAgICAgICAgdGFnID0gdmFsID4+IDMsXG4gICAgICAgICAgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICAgIHRoaXMudHlwZSA9IHZhbCAmIDB4NztcbiAgICAgIHJlYWRGaWVsZCh0YWcsIHJlc3VsdCwgdGhpcyk7XG4gICAgICBpZiAodGhpcy5wb3MgPT09IHN0YXJ0UG9zKSB0aGlzLnNraXAodmFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuICByZWFkTWVzc2FnZTogZnVuY3Rpb24gcmVhZE1lc3NhZ2UocmVhZEZpZWxkLCByZXN1bHQpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFkRmllbGRzKHJlYWRGaWVsZCwgcmVzdWx0LCB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zKTtcbiAgfSxcbiAgcmVhZEZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRGaXhlZDMyKCkge1xuICAgIHZhciB2YWwgPSByZWFkVUludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICByZWFkU0ZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRTRml4ZWQzMigpIHtcbiAgICB2YXIgdmFsID0gcmVhZEludDMyKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICAvLyA2NC1iaXQgaW50IGhhbmRsaW5nIGlzIGJhc2VkIG9uIGdpdGh1Yi5jb20vZHB3L25vZGUtYnVmZmVyLW1vcmUtaW50cyAoTUlULWxpY2Vuc2VkKVxuICByZWFkRml4ZWQ2NDogZnVuY3Rpb24gcmVhZEZpeGVkNjQoKSB7XG4gICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zICsgNCkgKiBTSElGVF9MRUZUXzMyO1xuICAgIHRoaXMucG9zICs9IDg7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZFNGaXhlZDY0OiBmdW5jdGlvbiByZWFkU0ZpeGVkNjQoKSB7XG4gICAgdmFyIHZhbCA9IHJlYWRVSW50MzIodGhpcy5idWYsIHRoaXMucG9zKSArIHJlYWRJbnQzMih0aGlzLmJ1ZiwgdGhpcy5wb3MgKyA0KSAqIFNISUZUX0xFRlRfMzI7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgICByZXR1cm4gdmFsO1xuICB9LFxuICByZWFkRmxvYXQ6IGZ1bmN0aW9uIHJlYWRGbG9hdCgpIHtcbiAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgMjMsIDQpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZERvdWJsZTogZnVuY3Rpb24gcmVhZERvdWJsZSgpIHtcbiAgICB2YXIgdmFsID0gaWVlZTc1NC5yZWFkKHRoaXMuYnVmLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gICAgcmV0dXJuIHZhbDtcbiAgfSxcbiAgcmVhZFZhcmludDogZnVuY3Rpb24gcmVhZFZhcmludChpc1NpZ25lZCkge1xuICAgIHZhciBidWYgPSB0aGlzLmJ1ZixcbiAgICAgICAgdmFsLFxuICAgICAgICBiO1xuICAgIGIgPSBidWZbdGhpcy5wb3MrK107XG4gICAgdmFsID0gYiAmIDB4N2Y7XG4gICAgaWYgKGIgPCAweDgwKSByZXR1cm4gdmFsO1xuICAgIGIgPSBidWZbdGhpcy5wb3MrK107XG4gICAgdmFsIHw9IChiICYgMHg3ZikgPDwgNztcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTtcbiAgICB2YWwgfD0gKGIgJiAweDdmKSA8PCAxNDtcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvcysrXTtcbiAgICB2YWwgfD0gKGIgJiAweDdmKSA8PCAyMTtcbiAgICBpZiAoYiA8IDB4ODApIHJldHVybiB2YWw7XG4gICAgYiA9IGJ1Zlt0aGlzLnBvc107XG4gICAgdmFsIHw9IChiICYgMHgwZikgPDwgMjg7XG4gICAgcmV0dXJuIHJlYWRWYXJpbnRSZW1haW5kZXIodmFsLCBpc1NpZ25lZCwgdGhpcyk7XG4gIH0sXG4gIHJlYWRWYXJpbnQ2NDogZnVuY3Rpb24gcmVhZFZhcmludDY0KCkge1xuICAgIC8vIGZvciBjb21wYXRpYmlsaXR5IHdpdGggdjIuMC4xXG4gICAgcmV0dXJuIHRoaXMucmVhZFZhcmludCh0cnVlKTtcbiAgfSxcbiAgcmVhZFNWYXJpbnQ6IGZ1bmN0aW9uIHJlYWRTVmFyaW50KCkge1xuICAgIHZhciBudW0gPSB0aGlzLnJlYWRWYXJpbnQoKTtcbiAgICByZXR1cm4gbnVtICUgMiA9PT0gMSA/IChudW0gKyAxKSAvIC0yIDogbnVtIC8gMjsgLy8gemlnemFnIGVuY29kaW5nXG4gIH0sXG4gIHJlYWRCb29sZWFuOiBmdW5jdGlvbiByZWFkQm9vbGVhbigpIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnJlYWRWYXJpbnQoKSk7XG4gIH0sXG4gIHJlYWRTdHJpbmc6IGZ1bmN0aW9uIHJlYWRTdHJpbmcoKSB7XG4gICAgdmFyIGVuZCA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7XG4gICAgdmFyIHBvcyA9IHRoaXMucG9zO1xuICAgIHRoaXMucG9zID0gZW5kO1xuXG4gICAgaWYgKGVuZCAtIHBvcyA+PSBURVhUX0RFQ09ERVJfTUlOX0xFTkdUSCAmJiB1dGY4VGV4dERlY29kZXIpIHtcbiAgICAgIC8vIGxvbmdlciBzdHJpbmdzIGFyZSBmYXN0IHdpdGggdGhlIGJ1aWx0LWluIGJyb3dzZXIgVGV4dERlY29kZXIgQVBJXG4gICAgICByZXR1cm4gcmVhZFV0ZjhUZXh0RGVjb2Rlcih0aGlzLmJ1ZiwgcG9zLCBlbmQpO1xuICAgIH0gLy8gc2hvcnQgc3RyaW5ncyBhcmUgZmFzdCB3aXRoIG91ciBjdXN0b20gaW1wbGVtZW50YXRpb25cblxuXG4gICAgcmV0dXJuIHJlYWRVdGY4KHRoaXMuYnVmLCBwb3MsIGVuZCk7XG4gIH0sXG4gIHJlYWRCeXRlczogZnVuY3Rpb24gcmVhZEJ5dGVzKCkge1xuICAgIHZhciBlbmQgPSB0aGlzLnJlYWRWYXJpbnQoKSArIHRoaXMucG9zLFxuICAgICAgICBidWZmZXIgPSB0aGlzLmJ1Zi5zdWJhcnJheSh0aGlzLnBvcywgZW5kKTtcbiAgICB0aGlzLnBvcyA9IGVuZDtcbiAgICByZXR1cm4gYnVmZmVyO1xuICB9LFxuICAvLyB2ZXJib3NlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zOyBkb2Vzbid0IGFmZmVjdCBnemlwcGVkIHNpemVcbiAgcmVhZFBhY2tlZFZhcmludDogZnVuY3Rpb24gcmVhZFBhY2tlZFZhcmludChhcnIsIGlzU2lnbmVkKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gUGJmLkJ5dGVzKSByZXR1cm4gYXJyLnB1c2godGhpcy5yZWFkVmFyaW50KGlzU2lnbmVkKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRWYXJpbnQoaXNTaWduZWQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyO1xuICB9LFxuICByZWFkUGFja2VkU1ZhcmludDogZnVuY3Rpb24gcmVhZFBhY2tlZFNWYXJpbnQoYXJyKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gUGJmLkJ5dGVzKSByZXR1cm4gYXJyLnB1c2godGhpcy5yZWFkU1ZhcmludCgpKTtcbiAgICB2YXIgZW5kID0gcmVhZFBhY2tlZEVuZCh0aGlzKTtcbiAgICBhcnIgPSBhcnIgfHwgW107XG5cbiAgICB3aGlsZSAodGhpcy5wb3MgPCBlbmQpIHtcbiAgICAgIGFyci5wdXNoKHRoaXMucmVhZFNWYXJpbnQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEJvb2xlYW46IGZ1bmN0aW9uIHJlYWRQYWNrZWRCb29sZWFuKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEJvb2xlYW4oKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRCb29sZWFuKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRGbG9hdDogZnVuY3Rpb24gcmVhZFBhY2tlZEZsb2F0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZsb2F0KCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkRmxvYXQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZERvdWJsZTogZnVuY3Rpb24gcmVhZFBhY2tlZERvdWJsZShhcnIpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSBQYmYuQnl0ZXMpIHJldHVybiBhcnIucHVzaCh0aGlzLnJlYWREb3VibGUoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWREb3VibGUoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEZpeGVkMzI6IGZ1bmN0aW9uIHJlYWRQYWNrZWRGaXhlZDMyKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkMzIoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDMyKCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24gcmVhZFBhY2tlZFNGaXhlZDMyKGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDMyKCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkU0ZpeGVkMzIoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgcmVhZFBhY2tlZEZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRQYWNrZWRGaXhlZDY0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZEZpeGVkNjQoKSk7XG4gICAgdmFyIGVuZCA9IHJlYWRQYWNrZWRFbmQodGhpcyk7XG4gICAgYXJyID0gYXJyIHx8IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgZW5kKSB7XG4gICAgICBhcnIucHVzaCh0aGlzLnJlYWRGaXhlZDY0KCkpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnI7XG4gIH0sXG4gIHJlYWRQYWNrZWRTRml4ZWQ2NDogZnVuY3Rpb24gcmVhZFBhY2tlZFNGaXhlZDY0KGFycikge1xuICAgIGlmICh0aGlzLnR5cGUgIT09IFBiZi5CeXRlcykgcmV0dXJuIGFyci5wdXNoKHRoaXMucmVhZFNGaXhlZDY0KCkpO1xuICAgIHZhciBlbmQgPSByZWFkUGFja2VkRW5kKHRoaXMpO1xuICAgIGFyciA9IGFyciB8fCBbXTtcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IGVuZCkge1xuICAgICAgYXJyLnB1c2godGhpcy5yZWFkU0ZpeGVkNjQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycjtcbiAgfSxcbiAgc2tpcDogZnVuY3Rpb24gc2tpcCh2YWwpIHtcbiAgICB2YXIgdHlwZSA9IHZhbCAmIDB4NztcbiAgICBpZiAodHlwZSA9PT0gUGJmLlZhcmludCkgd2hpbGUgKHRoaXMuYnVmW3RoaXMucG9zKytdID4gMHg3Zikge30gZWxzZSBpZiAodHlwZSA9PT0gUGJmLkJ5dGVzKSB0aGlzLnBvcyA9IHRoaXMucmVhZFZhcmludCgpICsgdGhpcy5wb3M7ZWxzZSBpZiAodHlwZSA9PT0gUGJmLkZpeGVkMzIpIHRoaXMucG9zICs9IDQ7ZWxzZSBpZiAodHlwZSA9PT0gUGJmLkZpeGVkNjQpIHRoaXMucG9zICs9IDg7ZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgdHlwZTogJyArIHR5cGUpO1xuICB9LFxuICAvLyA9PT0gV1JJVElORyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB3cml0ZVRhZzogZnVuY3Rpb24gd3JpdGVUYWcodGFnLCB0eXBlKSB7XG4gICAgdGhpcy53cml0ZVZhcmludCh0YWcgPDwgMyB8IHR5cGUpO1xuICB9LFxuICByZWFsbG9jOiBmdW5jdGlvbiByZWFsbG9jKG1pbikge1xuICAgIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8fCAxNjtcblxuICAgIHdoaWxlIChsZW5ndGggPCB0aGlzLnBvcyArIG1pbikge1xuICAgICAgbGVuZ3RoICo9IDI7XG4gICAgfVxuXG4gICAgaWYgKGxlbmd0aCAhPT0gdGhpcy5sZW5ndGgpIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheShsZW5ndGgpO1xuICAgICAgYnVmLnNldCh0aGlzLmJ1Zik7XG4gICAgICB0aGlzLmJ1ZiA9IGJ1ZjtcbiAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuICAgIH1cbiAgfSxcbiAgZmluaXNoOiBmdW5jdGlvbiBmaW5pc2goKSB7XG4gICAgdGhpcy5sZW5ndGggPSB0aGlzLnBvcztcbiAgICB0aGlzLnBvcyA9IDA7XG4gICAgcmV0dXJuIHRoaXMuYnVmLnN1YmFycmF5KDAsIHRoaXMubGVuZ3RoKTtcbiAgfSxcbiAgd3JpdGVGaXhlZDMyOiBmdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkMzI6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkMzIodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDQpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCwgdGhpcy5wb3MpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlRml4ZWQ2NDogZnVuY3Rpb24gd3JpdGVGaXhlZDY0KHZhbCkge1xuICAgIHRoaXMucmVhbGxvYyg4KTtcbiAgICB3cml0ZUludDMyKHRoaXMuYnVmLCB2YWwgJiAtMSwgdGhpcy5wb3MpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIE1hdGguZmxvb3IodmFsICogU0hJRlRfUklHSFRfMzIpLCB0aGlzLnBvcyArIDQpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkNjQ6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkNjQodmFsKSB7XG4gICAgdGhpcy5yZWFsbG9jKDgpO1xuICAgIHdyaXRlSW50MzIodGhpcy5idWYsIHZhbCAmIC0xLCB0aGlzLnBvcyk7XG4gICAgd3JpdGVJbnQzMih0aGlzLmJ1ZiwgTWF0aC5mbG9vcih2YWwgKiBTSElGVF9SSUdIVF8zMiksIHRoaXMucG9zICsgNCk7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgfSxcbiAgd3JpdGVWYXJpbnQ6IGZ1bmN0aW9uIHdyaXRlVmFyaW50KHZhbCkge1xuICAgIHZhbCA9ICt2YWwgfHwgMDtcblxuICAgIGlmICh2YWwgPiAweGZmZmZmZmYgfHwgdmFsIDwgMCkge1xuICAgICAgd3JpdGVCaWdWYXJpbnQodmFsLCB0aGlzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSB2YWwgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAodmFsID4+Pj0gNykgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSAodmFsID4+Pj0gNykgJiAweDdmIHwgKHZhbCA+IDB4N2YgPyAweDgwIDogMCk7XG4gICAgaWYgKHZhbCA8PSAweDdmKSByZXR1cm47XG4gICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSB2YWwgPj4+IDcgJiAweDdmO1xuICB9LFxuICB3cml0ZVNWYXJpbnQ6IGZ1bmN0aW9uIHdyaXRlU1ZhcmludCh2YWwpIHtcbiAgICB0aGlzLndyaXRlVmFyaW50KHZhbCA8IDAgPyAtdmFsICogMiAtIDEgOiB2YWwgKiAyKTtcbiAgfSxcbiAgd3JpdGVCb29sZWFuOiBmdW5jdGlvbiB3cml0ZUJvb2xlYW4odmFsKSB7XG4gICAgdGhpcy53cml0ZVZhcmludChCb29sZWFuKHZhbCkpO1xuICB9LFxuICB3cml0ZVN0cmluZzogZnVuY3Rpb24gd3JpdGVTdHJpbmcoc3RyKSB7XG4gICAgc3RyID0gU3RyaW5nKHN0cik7XG4gICAgdGhpcy5yZWFsbG9jKHN0ci5sZW5ndGggKiA0KTtcbiAgICB0aGlzLnBvcysrOyAvLyByZXNlcnZlIDEgYnl0ZSBmb3Igc2hvcnQgc3RyaW5nIGxlbmd0aFxuXG4gICAgdmFyIHN0YXJ0UG9zID0gdGhpcy5wb3M7IC8vIHdyaXRlIHRoZSBzdHJpbmcgZGlyZWN0bHkgdG8gdGhlIGJ1ZmZlciBhbmQgc2VlIGhvdyBtdWNoIHdhcyB3cml0dGVuXG5cbiAgICB0aGlzLnBvcyA9IHdyaXRlVXRmOCh0aGlzLmJ1Ziwgc3RyLCB0aGlzLnBvcyk7XG4gICAgdmFyIGxlbiA9IHRoaXMucG9zIC0gc3RhcnRQb3M7XG4gICAgaWYgKGxlbiA+PSAweDgwKSBtYWtlUm9vbUZvckV4dHJhTGVuZ3RoKHN0YXJ0UG9zLCBsZW4sIHRoaXMpOyAvLyBmaW5hbGx5LCB3cml0ZSB0aGUgbWVzc2FnZSBsZW5ndGggaW4gdGhlIHJlc2VydmVkIHBsYWNlIGFuZCByZXN0b3JlIHRoZSBwb3NpdGlvblxuXG4gICAgdGhpcy5wb3MgPSBzdGFydFBvcyAtIDE7XG4gICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgIHRoaXMucG9zICs9IGxlbjtcbiAgfSxcbiAgd3JpdGVGbG9hdDogZnVuY3Rpb24gd3JpdGVGbG9hdCh2YWwpIHtcbiAgICB0aGlzLnJlYWxsb2MoNCk7XG4gICAgaWVlZTc1NC53cml0ZSh0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcywgdHJ1ZSwgMjMsIDQpO1xuICAgIHRoaXMucG9zICs9IDQ7XG4gIH0sXG4gIHdyaXRlRG91YmxlOiBmdW5jdGlvbiB3cml0ZURvdWJsZSh2YWwpIHtcbiAgICB0aGlzLnJlYWxsb2MoOCk7XG4gICAgaWVlZTc1NC53cml0ZSh0aGlzLmJ1ZiwgdmFsLCB0aGlzLnBvcywgdHJ1ZSwgNTIsIDgpO1xuICAgIHRoaXMucG9zICs9IDg7XG4gIH0sXG4gIHdyaXRlQnl0ZXM6IGZ1bmN0aW9uIHdyaXRlQnl0ZXMoYnVmZmVyKSB7XG4gICAgdmFyIGxlbiA9IGJ1ZmZlci5sZW5ndGg7XG4gICAgdGhpcy53cml0ZVZhcmludChsZW4pO1xuICAgIHRoaXMucmVhbGxvYyhsZW4pO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGhpcy5idWZbdGhpcy5wb3MrK10gPSBidWZmZXJbaV07XG4gICAgfVxuICB9LFxuICB3cml0ZVJhd01lc3NhZ2U6IGZ1bmN0aW9uIHdyaXRlUmF3TWVzc2FnZShmbiwgb2JqKSB7XG4gICAgdGhpcy5wb3MrKzsgLy8gcmVzZXJ2ZSAxIGJ5dGUgZm9yIHNob3J0IG1lc3NhZ2UgbGVuZ3RoXG4gICAgLy8gd3JpdGUgdGhlIG1lc3NhZ2UgZGlyZWN0bHkgdG8gdGhlIGJ1ZmZlciBhbmQgc2VlIGhvdyBtdWNoIHdhcyB3cml0dGVuXG5cbiAgICB2YXIgc3RhcnRQb3MgPSB0aGlzLnBvcztcbiAgICBmbihvYmosIHRoaXMpO1xuICAgIHZhciBsZW4gPSB0aGlzLnBvcyAtIHN0YXJ0UG9zO1xuICAgIGlmIChsZW4gPj0gMHg4MCkgbWFrZVJvb21Gb3JFeHRyYUxlbmd0aChzdGFydFBvcywgbGVuLCB0aGlzKTsgLy8gZmluYWxseSwgd3JpdGUgdGhlIG1lc3NhZ2UgbGVuZ3RoIGluIHRoZSByZXNlcnZlZCBwbGFjZSBhbmQgcmVzdG9yZSB0aGUgcG9zaXRpb25cblxuICAgIHRoaXMucG9zID0gc3RhcnRQb3MgLSAxO1xuICAgIHRoaXMud3JpdGVWYXJpbnQobGVuKTtcbiAgICB0aGlzLnBvcyArPSBsZW47XG4gIH0sXG4gIHdyaXRlTWVzc2FnZTogZnVuY3Rpb24gd3JpdGVNZXNzYWdlKHRhZywgZm4sIG9iaikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVSYXdNZXNzYWdlKGZuLCBvYmopO1xuICB9LFxuICB3cml0ZVBhY2tlZFZhcmludDogZnVuY3Rpb24gd3JpdGVQYWNrZWRWYXJpbnQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRWYXJpbnQsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkU1ZhcmludDogZnVuY3Rpb24gd3JpdGVQYWNrZWRTVmFyaW50KHRhZywgYXJyKSB7XG4gICAgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgX3dyaXRlUGFja2VkU1ZhcmludCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRCb29sZWFuOiBmdW5jdGlvbiB3cml0ZVBhY2tlZEJvb2xlYW4odGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRCb29sZWFuLCBhcnIpO1xuICB9LFxuICB3cml0ZVBhY2tlZEZsb2F0OiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZsb2F0KHRhZywgYXJyKSB7XG4gICAgaWYgKGFyci5sZW5ndGgpIHRoaXMud3JpdGVNZXNzYWdlKHRhZywgX3dyaXRlUGFja2VkRmxvYXQsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkRG91YmxlOiBmdW5jdGlvbiB3cml0ZVBhY2tlZERvdWJsZSh0YWcsIGFycikge1xuICAgIGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIF93cml0ZVBhY2tlZERvdWJsZSwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRGaXhlZDMyOiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkMzIodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRGaXhlZCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRTRml4ZWQzMjogZnVuY3Rpb24gd3JpdGVQYWNrZWRTRml4ZWQzMih0YWcsIGFycikge1xuICAgIGlmIChhcnIubGVuZ3RoKSB0aGlzLndyaXRlTWVzc2FnZSh0YWcsIF93cml0ZVBhY2tlZFNGaXhlZCwgYXJyKTtcbiAgfSxcbiAgd3JpdGVQYWNrZWRGaXhlZDY0OiBmdW5jdGlvbiB3cml0ZVBhY2tlZEZpeGVkNjQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRGaXhlZDIsIGFycik7XG4gIH0sXG4gIHdyaXRlUGFja2VkU0ZpeGVkNjQ6IGZ1bmN0aW9uIHdyaXRlUGFja2VkU0ZpeGVkNjQodGFnLCBhcnIpIHtcbiAgICBpZiAoYXJyLmxlbmd0aCkgdGhpcy53cml0ZU1lc3NhZ2UodGFnLCBfd3JpdGVQYWNrZWRTRml4ZWQyLCBhcnIpO1xuICB9LFxuICB3cml0ZUJ5dGVzRmllbGQ6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNGaWVsZCh0YWcsIGJ1ZmZlcikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVCeXRlcyhidWZmZXIpO1xuICB9LFxuICB3cml0ZUZpeGVkMzJGaWVsZDogZnVuY3Rpb24gd3JpdGVGaXhlZDMyRmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgIHRoaXMud3JpdGVGaXhlZDMyKHZhbCk7XG4gIH0sXG4gIHdyaXRlU0ZpeGVkMzJGaWVsZDogZnVuY3Rpb24gd3JpdGVTRml4ZWQzMkZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDMyKTtcbiAgICB0aGlzLndyaXRlU0ZpeGVkMzIodmFsKTtcbiAgfSxcbiAgd3JpdGVGaXhlZDY0RmllbGQ6IGZ1bmN0aW9uIHdyaXRlRml4ZWQ2NEZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICB0aGlzLndyaXRlRml4ZWQ2NCh2YWwpO1xuICB9LFxuICB3cml0ZVNGaXhlZDY0RmllbGQ6IGZ1bmN0aW9uIHdyaXRlU0ZpeGVkNjRGaWVsZCh0YWcsIHZhbCkge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuRml4ZWQ2NCk7XG4gICAgdGhpcy53cml0ZVNGaXhlZDY0KHZhbCk7XG4gIH0sXG4gIHdyaXRlVmFyaW50RmllbGQ6IGZ1bmN0aW9uIHdyaXRlVmFyaW50RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLlZhcmludCk7XG4gICAgdGhpcy53cml0ZVZhcmludCh2YWwpO1xuICB9LFxuICB3cml0ZVNWYXJpbnRGaWVsZDogZnVuY3Rpb24gd3JpdGVTVmFyaW50RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLlZhcmludCk7XG4gICAgdGhpcy53cml0ZVNWYXJpbnQodmFsKTtcbiAgfSxcbiAgd3JpdGVTdHJpbmdGaWVsZDogZnVuY3Rpb24gd3JpdGVTdHJpbmdGaWVsZCh0YWcsIHN0cikge1xuICAgIHRoaXMud3JpdGVUYWcodGFnLCBQYmYuQnl0ZXMpO1xuICAgIHRoaXMud3JpdGVTdHJpbmcoc3RyKTtcbiAgfSxcbiAgd3JpdGVGbG9hdEZpZWxkOiBmdW5jdGlvbiB3cml0ZUZsb2F0RmllbGQodGFnLCB2YWwpIHtcbiAgICB0aGlzLndyaXRlVGFnKHRhZywgUGJmLkZpeGVkMzIpO1xuICAgIHRoaXMud3JpdGVGbG9hdCh2YWwpO1xuICB9LFxuICB3cml0ZURvdWJsZUZpZWxkOiBmdW5jdGlvbiB3cml0ZURvdWJsZUZpZWxkKHRhZywgdmFsKSB7XG4gICAgdGhpcy53cml0ZVRhZyh0YWcsIFBiZi5GaXhlZDY0KTtcbiAgICB0aGlzLndyaXRlRG91YmxlKHZhbCk7XG4gIH0sXG4gIHdyaXRlQm9vbGVhbkZpZWxkOiBmdW5jdGlvbiB3cml0ZUJvb2xlYW5GaWVsZCh0YWcsIHZhbCkge1xuICAgIHRoaXMud3JpdGVWYXJpbnRGaWVsZCh0YWcsIEJvb2xlYW4odmFsKSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHJlYWRWYXJpbnRSZW1haW5kZXIobCwgcywgcCkge1xuICB2YXIgYnVmID0gcC5idWYsXG4gICAgICBoLFxuICAgICAgYjtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCA9IChiICYgMHg3MCkgPj4gNDtcbiAgaWYgKGIgPCAweDgwKSByZXR1cm4gdG9OdW0obCwgaCwgcyk7XG4gIGIgPSBidWZbcC5wb3MrK107XG4gIGggfD0gKGIgJiAweDdmKSA8PCAzO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDEwO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDE3O1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4N2YpIDw8IDI0O1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgYiA9IGJ1ZltwLnBvcysrXTtcbiAgaCB8PSAoYiAmIDB4MDEpIDw8IDMxO1xuICBpZiAoYiA8IDB4ODApIHJldHVybiB0b051bShsLCBoLCBzKTtcbiAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCB2YXJpbnQgbm90IG1vcmUgdGhhbiAxMCBieXRlcycpO1xufVxuXG5mdW5jdGlvbiByZWFkUGFja2VkRW5kKHBiZikge1xuICByZXR1cm4gcGJmLnR5cGUgPT09IFBiZi5CeXRlcyA/IHBiZi5yZWFkVmFyaW50KCkgKyBwYmYucG9zIDogcGJmLnBvcyArIDE7XG59XG5cbmZ1bmN0aW9uIHRvTnVtKGxvdywgaGlnaCwgaXNTaWduZWQpIHtcbiAgaWYgKGlzU2lnbmVkKSB7XG4gICAgcmV0dXJuIGhpZ2ggKiAweDEwMDAwMDAwMCArIChsb3cgPj4+IDApO1xuICB9XG5cbiAgcmV0dXJuIChoaWdoID4+PiAwKSAqIDB4MTAwMDAwMDAwICsgKGxvdyA+Pj4gMCk7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50KHZhbCwgcGJmKSB7XG4gIHZhciBsb3csIGhpZ2g7XG5cbiAgaWYgKHZhbCA+PSAwKSB7XG4gICAgbG93ID0gdmFsICUgMHgxMDAwMDAwMDAgfCAwO1xuICAgIGhpZ2ggPSB2YWwgLyAweDEwMDAwMDAwMCB8IDA7XG4gIH0gZWxzZSB7XG4gICAgbG93ID0gfigtdmFsICUgMHgxMDAwMDAwMDApO1xuICAgIGhpZ2ggPSB+KC12YWwgLyAweDEwMDAwMDAwMCk7XG5cbiAgICBpZiAobG93IF4gMHhmZmZmZmZmZikge1xuICAgICAgbG93ID0gbG93ICsgMSB8IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gaGlnaCArIDEgfCAwO1xuICAgIH1cbiAgfVxuXG4gIGlmICh2YWwgPj0gMHgxMDAwMDAwMDAwMDAwMDAwMCB8fCB2YWwgPCAtMHgxMDAwMDAwMDAwMDAwMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignR2l2ZW4gdmFyaW50IGRvZXNuXFwndCBmaXQgaW50byAxMCBieXRlcycpO1xuICB9XG5cbiAgcGJmLnJlYWxsb2MoMTApO1xuICB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZik7XG4gIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpO1xufVxuXG5mdW5jdGlvbiB3cml0ZUJpZ1ZhcmludExvdyhsb3csIGhpZ2gsIHBiZikge1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBsb3cgJiAweDdmIHwgMHg4MDtcbiAgbG93ID4+Pj0gNztcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gbG93ICYgMHg3ZiB8IDB4ODA7XG4gIGxvdyA+Pj49IDc7XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGxvdyAmIDB4N2YgfCAweDgwO1xuICBsb3cgPj4+PSA3O1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBsb3cgJiAweDdmIHwgMHg4MDtcbiAgbG93ID4+Pj0gNztcbiAgcGJmLmJ1ZltwYmYucG9zXSA9IGxvdyAmIDB4N2Y7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmlnVmFyaW50SGlnaChoaWdoLCBwYmYpIHtcbiAgdmFyIGxzYiA9IChoaWdoICYgMHgwNykgPDwgNDtcbiAgcGJmLmJ1ZltwYmYucG9zKytdIHw9IGxzYiB8ICgoaGlnaCA+Pj49IDMpID8gMHg4MCA6IDApO1xuICBpZiAoIWhpZ2gpIHJldHVybjtcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTtcbiAgaWYgKCFoaWdoKSByZXR1cm47XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGhpZ2ggJiAweDdmIHwgKChoaWdoID4+Pj0gNykgPyAweDgwIDogMCk7XG4gIGlmICghaGlnaCkgcmV0dXJuO1xuICBwYmYuYnVmW3BiZi5wb3MrK10gPSBoaWdoICYgMHg3ZiB8ICgoaGlnaCA+Pj49IDcpID8gMHg4MCA6IDApO1xuICBpZiAoIWhpZ2gpIHJldHVybjtcbiAgcGJmLmJ1ZltwYmYucG9zKytdID0gaGlnaCAmIDB4N2YgfCAoKGhpZ2ggPj4+PSA3KSA/IDB4ODAgOiAwKTtcbiAgaWYgKCFoaWdoKSByZXR1cm47XG4gIHBiZi5idWZbcGJmLnBvcysrXSA9IGhpZ2ggJiAweDdmO1xufVxuXG5mdW5jdGlvbiBtYWtlUm9vbUZvckV4dHJhTGVuZ3RoKHN0YXJ0UG9zLCBsZW4sIHBiZikge1xuICB2YXIgZXh0cmFMZW4gPSBsZW4gPD0gMHgzZmZmID8gMSA6IGxlbiA8PSAweDFmZmZmZiA/IDIgOiBsZW4gPD0gMHhmZmZmZmZmID8gMyA6IE1hdGguZmxvb3IoTWF0aC5sb2cobGVuKSAvIChNYXRoLkxOMiAqIDcpKTsgLy8gaWYgMSBieXRlIGlzbid0IGVub3VnaCBmb3IgZW5jb2RpbmcgbWVzc2FnZSBsZW5ndGgsIHNoaWZ0IHRoZSBkYXRhIHRvIHRoZSByaWdodFxuXG4gIHBiZi5yZWFsbG9jKGV4dHJhTGVuKTtcblxuICBmb3IgKHZhciBpID0gcGJmLnBvcyAtIDE7IGkgPj0gc3RhcnRQb3M7IGktLSkge1xuICAgIHBiZi5idWZbaSArIGV4dHJhTGVuXSA9IHBiZi5idWZbaV07XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkVmFyaW50KGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlVmFyaW50KGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkU1ZhcmludChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZVNWYXJpbnQoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRGbG9hdChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZsb2F0KGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkRG91YmxlKGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlRG91YmxlKGFycltpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3dyaXRlUGFja2VkQm9vbGVhbihhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUJvb2xlYW4oYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRGaXhlZChhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZpeGVkMzIoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRTRml4ZWQoYXJyLCBwYmYpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBwYmYud3JpdGVTRml4ZWQzMihhcnJbaV0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIF93cml0ZVBhY2tlZEZpeGVkMihhcnIsIHBiZikge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIHBiZi53cml0ZUZpeGVkNjQoYXJyW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfd3JpdGVQYWNrZWRTRml4ZWQyKGFyciwgcGJmKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgcGJmLndyaXRlU0ZpeGVkNjQoYXJyW2ldKTtcbiAgfVxufSAvLyBCdWZmZXIgY29kZSBiZWxvdyBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9mZXJvc3MvYnVmZmVyLCBNSVQtbGljZW5zZWRcblxuXG5mdW5jdGlvbiByZWFkVUludDMyKGJ1ZiwgcG9zKSB7XG4gIHJldHVybiAoYnVmW3Bvc10gfCBidWZbcG9zICsgMV0gPDwgOCB8IGJ1Zltwb3MgKyAyXSA8PCAxNikgKyBidWZbcG9zICsgM10gKiAweDEwMDAwMDA7XG59XG5cbmZ1bmN0aW9uIHdyaXRlSW50MzIoYnVmLCB2YWwsIHBvcykge1xuICBidWZbcG9zXSA9IHZhbDtcbiAgYnVmW3BvcyArIDFdID0gdmFsID4+PiA4O1xuICBidWZbcG9zICsgMl0gPSB2YWwgPj4+IDE2O1xuICBidWZbcG9zICsgM10gPSB2YWwgPj4+IDI0O1xufVxuXG5mdW5jdGlvbiByZWFkSW50MzIoYnVmLCBwb3MpIHtcbiAgcmV0dXJuIChidWZbcG9zXSB8IGJ1Zltwb3MgKyAxXSA8PCA4IHwgYnVmW3BvcyArIDJdIDw8IDE2KSArIChidWZbcG9zICsgM10gPDwgMjQpO1xufVxuXG5mdW5jdGlvbiByZWFkVXRmOChidWYsIHBvcywgZW5kKSB7XG4gIHZhciBzdHIgPSAnJztcbiAgdmFyIGkgPSBwb3M7XG5cbiAgd2hpbGUgKGkgPCBlbmQpIHtcbiAgICB2YXIgYjAgPSBidWZbaV07XG4gICAgdmFyIGMgPSBudWxsOyAvLyBjb2RlcG9pbnRcblxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gYjAgPiAweEVGID8gNCA6IGIwID4gMHhERiA/IDMgOiBiMCA+IDB4QkYgPyAyIDogMTtcbiAgICBpZiAoaSArIGJ5dGVzUGVyU2VxdWVuY2UgPiBlbmQpIGJyZWFrO1xuICAgIHZhciBiMSwgYjIsIGIzO1xuXG4gICAgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDEpIHtcbiAgICAgIGlmIChiMCA8IDB4ODApIHtcbiAgICAgICAgYyA9IGIwO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYnl0ZXNQZXJTZXF1ZW5jZSA9PT0gMikge1xuICAgICAgYjEgPSBidWZbaSArIDFdO1xuXG4gICAgICBpZiAoKGIxICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgYyA9IChiMCAmIDB4MUYpIDw8IDB4NiB8IGIxICYgMHgzRjtcblxuICAgICAgICBpZiAoYyA8PSAweDdGKSB7XG4gICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJ5dGVzUGVyU2VxdWVuY2UgPT09IDMpIHtcbiAgICAgIGIxID0gYnVmW2kgKyAxXTtcbiAgICAgIGIyID0gYnVmW2kgKyAyXTtcblxuICAgICAgaWYgKChiMSAmIDB4QzApID09PSAweDgwICYmIChiMiAmIDB4QzApID09PSAweDgwKSB7XG4gICAgICAgIGMgPSAoYjAgJiAweEYpIDw8IDB4QyB8IChiMSAmIDB4M0YpIDw8IDB4NiB8IGIyICYgMHgzRjtcblxuICAgICAgICBpZiAoYyA8PSAweDdGRiB8fCBjID49IDB4RDgwMCAmJiBjIDw9IDB4REZGRikge1xuICAgICAgICAgIGMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChieXRlc1BlclNlcXVlbmNlID09PSA0KSB7XG4gICAgICBiMSA9IGJ1ZltpICsgMV07XG4gICAgICBiMiA9IGJ1ZltpICsgMl07XG4gICAgICBiMyA9IGJ1ZltpICsgM107XG5cbiAgICAgIGlmICgoYjEgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjIgJiAweEMwKSA9PT0gMHg4MCAmJiAoYjMgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICBjID0gKGIwICYgMHhGKSA8PCAweDEyIHwgKGIxICYgMHgzRikgPDwgMHhDIHwgKGIyICYgMHgzRikgPDwgMHg2IHwgYjMgJiAweDNGO1xuXG4gICAgICAgIGlmIChjIDw9IDB4RkZGRiB8fCBjID49IDB4MTEwMDAwKSB7XG4gICAgICAgICAgYyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAgYyA9IDB4RkZGRDtcbiAgICAgIGJ5dGVzUGVyU2VxdWVuY2UgPSAxO1xuICAgIH0gZWxzZSBpZiAoYyA+IDB4RkZGRikge1xuICAgICAgYyAtPSAweDEwMDAwO1xuICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG4gICAgICBjID0gMHhEQzAwIHwgYyAmIDB4M0ZGO1xuICAgIH1cblxuICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZTtcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59XG5cbmZ1bmN0aW9uIHJlYWRVdGY4VGV4dERlY29kZXIoYnVmLCBwb3MsIGVuZCkge1xuICByZXR1cm4gdXRmOFRleHREZWNvZGVyLmRlY29kZShidWYuc3ViYXJyYXkocG9zLCBlbmQpKTtcbn1cblxuZnVuY3Rpb24gd3JpdGVVdGY4KGJ1Ziwgc3RyLCBwb3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGMsIGxlYWQ7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSk7IC8vIGNvZGUgcG9pbnRcblxuICAgIGlmIChjID4gMHhEN0ZGICYmIGMgPCAweEUwMDApIHtcbiAgICAgIGlmIChsZWFkKSB7XG4gICAgICAgIGlmIChjIDwgMHhEQzAwKSB7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4RUY7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkY7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IDB4QkQ7XG4gICAgICAgICAgbGVhZCA9IGM7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYyA9IGxlYWQgLSAweEQ4MDAgPDwgMTAgfCBjIC0gMHhEQzAwIHwgMHgxMDAwMDtcbiAgICAgICAgICBsZWFkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGMgPiAweERCRkYgfHwgaSArIDEgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhFRjtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhCRjtcbiAgICAgICAgICBidWZbcG9zKytdID0gMHhCRDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZWFkID0gYztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobGVhZCkge1xuICAgICAgYnVmW3BvcysrXSA9IDB4RUY7XG4gICAgICBidWZbcG9zKytdID0gMHhCRjtcbiAgICAgIGJ1Zltwb3MrK10gPSAweEJEO1xuICAgICAgbGVhZCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGMgPCAweDgwKSB7XG4gICAgICBidWZbcG9zKytdID0gYztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGMgPCAweDgwMCkge1xuICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDYgfCAweEMwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGMgPCAweDEwMDAwKSB7XG4gICAgICAgICAgYnVmW3BvcysrXSA9IGMgPj4gMHhDIHwgMHhFMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweDEyIHwgMHhGMDtcbiAgICAgICAgICBidWZbcG9zKytdID0gYyA+PiAweEMgJiAweDNGIHwgMHg4MDtcbiAgICAgICAgfVxuXG4gICAgICAgIGJ1Zltwb3MrK10gPSBjID4+IDB4NiAmIDB4M0YgfCAweDgwO1xuICAgICAgfVxuXG4gICAgICBidWZbcG9zKytdID0gYyAmIDB4M0YgfCAweDgwO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwb3M7XG59Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4362\n")},5792:function(module){eval('!function (t, i) {\n true ? module.exports = i() : 0;\n}(this, function () {\n "use strict";\n\n function t(t, r, e, a, h) {\n !function t(n, r, e, a, h) {\n for (; a > e;) {\n if (a - e > 600) {\n var o = a - e + 1,\n s = r - e + 1,\n l = Math.log(o),\n f = .5 * Math.exp(2 * l / 3),\n u = .5 * Math.sqrt(l * f * (o - f) / o) * (s - o / 2 < 0 ? -1 : 1),\n m = Math.max(e, Math.floor(r - s * f / o + u)),\n c = Math.min(a, Math.floor(r + (o - s) * f / o + u));\n t(n, r, m, c, h);\n }\n\n var p = n[r],\n d = e,\n x = a;\n\n for (i(n, e, r), h(n[a], p) > 0 && i(n, e, a); d < x;) {\n for (i(n, d, x), d++, x--; h(n[d], p) < 0;) {\n d++;\n }\n\n for (; h(n[x], p) > 0;) {\n x--;\n }\n }\n\n 0 === h(n[e], p) ? i(n, e, x) : i(n, ++x, a), x <= r && (e = x + 1), r <= x && (a = x - 1);\n }\n }(t, r, e || 0, a || t.length - 1, h || n);\n }\n\n function i(t, i, n) {\n var r = t[i];\n t[i] = t[n], t[n] = r;\n }\n\n function n(t, i) {\n return t < i ? -1 : t > i ? 1 : 0;\n }\n\n var r = function r(t) {\n void 0 === t && (t = 9), this._maxEntries = Math.max(4, t), this._minEntries = Math.max(2, Math.ceil(.4 * this._maxEntries)), this.clear();\n };\n\n function e(t, i, n) {\n if (!n) return i.indexOf(t);\n\n for (var r = 0; r < i.length; r++) {\n if (n(t, i[r])) return r;\n }\n\n return -1;\n }\n\n function a(t, i) {\n h(t, 0, t.children.length, i, t);\n }\n\n function h(t, i, n, r, e) {\n e || (e = p(null)), e.minX = 1 / 0, e.minY = 1 / 0, e.maxX = -1 / 0, e.maxY = -1 / 0;\n\n for (var a = i; a < n; a++) {\n var h = t.children[a];\n o(e, t.leaf ? r(h) : h);\n }\n\n return e;\n }\n\n function o(t, i) {\n return t.minX = Math.min(t.minX, i.minX), t.minY = Math.min(t.minY, i.minY), t.maxX = Math.max(t.maxX, i.maxX), t.maxY = Math.max(t.maxY, i.maxY), t;\n }\n\n function s(t, i) {\n return t.minX - i.minX;\n }\n\n function l(t, i) {\n return t.minY - i.minY;\n }\n\n function f(t) {\n return (t.maxX - t.minX) * (t.maxY - t.minY);\n }\n\n function u(t) {\n return t.maxX - t.minX + (t.maxY - t.minY);\n }\n\n function m(t, i) {\n return t.minX <= i.minX && t.minY <= i.minY && i.maxX <= t.maxX && i.maxY <= t.maxY;\n }\n\n function c(t, i) {\n return i.minX <= t.maxX && i.minY <= t.maxY && i.maxX >= t.minX && i.maxY >= t.minY;\n }\n\n function p(t) {\n return {\n children: t,\n height: 1,\n leaf: !0,\n minX: 1 / 0,\n minY: 1 / 0,\n maxX: -1 / 0,\n maxY: -1 / 0\n };\n }\n\n function d(i, n, r, e, a) {\n for (var h = [n, r]; h.length;) {\n if (!((r = h.pop()) - (n = h.pop()) <= e)) {\n var o = n + Math.ceil((r - n) / e / 2) * e;\n t(i, o, n, r, a), h.push(n, o, o, r);\n }\n }\n }\n\n return r.prototype.all = function () {\n return this._all(this.data, []);\n }, r.prototype.search = function (t) {\n var i = this.data,\n n = [];\n if (!c(t, i)) return n;\n\n for (var r = this.toBBox, e = []; i;) {\n for (var a = 0; a < i.children.length; a++) {\n var h = i.children[a],\n o = i.leaf ? r(h) : h;\n c(t, o) && (i.leaf ? n.push(h) : m(t, o) ? this._all(h, n) : e.push(h));\n }\n\n i = e.pop();\n }\n\n return n;\n }, r.prototype.collides = function (t) {\n var i = this.data;\n if (!c(t, i)) return !1;\n\n for (var n = []; i;) {\n for (var r = 0; r < i.children.length; r++) {\n var e = i.children[r],\n a = i.leaf ? this.toBBox(e) : e;\n\n if (c(t, a)) {\n if (i.leaf || m(t, a)) return !0;\n n.push(e);\n }\n }\n\n i = n.pop();\n }\n\n return !1;\n }, r.prototype.load = function (t) {\n if (!t || !t.length) return this;\n\n if (t.length < this._minEntries) {\n for (var i = 0; i < t.length; i++) {\n this.insert(t[i]);\n }\n\n return this;\n }\n\n var n = this._build(t.slice(), 0, t.length - 1, 0);\n\n if (this.data.children.length) {\n if (this.data.height === n.height) this._splitRoot(this.data, n);else {\n if (this.data.height < n.height) {\n var r = this.data;\n this.data = n, n = r;\n }\n\n this._insert(n, this.data.height - n.height - 1, !0);\n }\n } else this.data = n;\n return this;\n }, r.prototype.insert = function (t) {\n return t && this._insert(t, this.data.height - 1), this;\n }, r.prototype.clear = function () {\n return this.data = p([]), this;\n }, r.prototype.remove = function (t, i) {\n if (!t) return this;\n\n for (var n, r, a, h = this.data, o = this.toBBox(t), s = [], l = []; h || s.length;) {\n if (h || (h = s.pop(), r = s[s.length - 1], n = l.pop(), a = !0), h.leaf) {\n var f = e(t, h.children, i);\n if (-1 !== f) return h.children.splice(f, 1), s.push(h), this._condense(s), this;\n }\n\n a || h.leaf || !m(h, o) ? r ? (n++, h = r.children[n], a = !1) : h = null : (s.push(h), l.push(n), n = 0, r = h, h = h.children[0]);\n }\n\n return this;\n }, r.prototype.toBBox = function (t) {\n return t;\n }, r.prototype.compareMinX = function (t, i) {\n return t.minX - i.minX;\n }, r.prototype.compareMinY = function (t, i) {\n return t.minY - i.minY;\n }, r.prototype.toJSON = function () {\n return this.data;\n }, r.prototype.fromJSON = function (t) {\n return this.data = t, this;\n }, r.prototype._all = function (t, i) {\n for (var n = []; t;) {\n t.leaf ? i.push.apply(i, t.children) : n.push.apply(n, t.children), t = n.pop();\n }\n\n return i;\n }, r.prototype._build = function (t, i, n, r) {\n var e,\n h = n - i + 1,\n o = this._maxEntries;\n if (h <= o) return a(e = p(t.slice(i, n + 1)), this.toBBox), e;\n r || (r = Math.ceil(Math.log(h) / Math.log(o)), o = Math.ceil(h / Math.pow(o, r - 1))), (e = p([])).leaf = !1, e.height = r;\n var s = Math.ceil(h / o),\n l = s * Math.ceil(Math.sqrt(o));\n d(t, i, n, l, this.compareMinX);\n\n for (var f = i; f <= n; f += l) {\n var u = Math.min(f + l - 1, n);\n d(t, f, u, s, this.compareMinY);\n\n for (var m = f; m <= u; m += s) {\n var c = Math.min(m + s - 1, u);\n e.children.push(this._build(t, m, c, r - 1));\n }\n }\n\n return a(e, this.toBBox), e;\n }, r.prototype._chooseSubtree = function (t, i, n, r) {\n for (; r.push(i), !i.leaf && r.length - 1 !== n;) {\n for (var e = 1 / 0, a = 1 / 0, h = void 0, o = 0; o < i.children.length; o++) {\n var s = i.children[o],\n l = f(s),\n u = (m = t, c = s, (Math.max(c.maxX, m.maxX) - Math.min(c.minX, m.minX)) * (Math.max(c.maxY, m.maxY) - Math.min(c.minY, m.minY)) - l);\n u < a ? (a = u, e = l < e ? l : e, h = s) : u === a && l < e && (e = l, h = s);\n }\n\n i = h || i.children[0];\n }\n\n var m, c;\n return i;\n }, r.prototype._insert = function (t, i, n) {\n var r = n ? t : this.toBBox(t),\n e = [],\n a = this._chooseSubtree(r, this.data, i, e);\n\n for (a.children.push(t), o(a, r); i >= 0 && e[i].children.length > this._maxEntries;) {\n this._split(e, i), i--;\n }\n\n this._adjustParentBBoxes(r, e, i);\n }, r.prototype._split = function (t, i) {\n var n = t[i],\n r = n.children.length,\n e = this._minEntries;\n\n this._chooseSplitAxis(n, e, r);\n\n var h = this._chooseSplitIndex(n, e, r),\n o = p(n.children.splice(h, n.children.length - h));\n\n o.height = n.height, o.leaf = n.leaf, a(n, this.toBBox), a(o, this.toBBox), i ? t[i - 1].children.push(o) : this._splitRoot(n, o);\n }, r.prototype._splitRoot = function (t, i) {\n this.data = p([t, i]), this.data.height = t.height + 1, this.data.leaf = !1, a(this.data, this.toBBox);\n }, r.prototype._chooseSplitIndex = function (t, i, n) {\n for (var r, e, a, o, s, l, u, m = 1 / 0, c = 1 / 0, p = i; p <= n - i; p++) {\n var d = h(t, 0, p, this.toBBox),\n x = h(t, p, n, this.toBBox),\n v = (e = d, a = x, o = void 0, s = void 0, l = void 0, u = void 0, o = Math.max(e.minX, a.minX), s = Math.max(e.minY, a.minY), l = Math.min(e.maxX, a.maxX), u = Math.min(e.maxY, a.maxY), Math.max(0, l - o) * Math.max(0, u - s)),\n M = f(d) + f(x);\n v < m ? (m = v, r = p, c = M < c ? M : c) : v === m && M < c && (c = M, r = p);\n }\n\n return r || n - i;\n }, r.prototype._chooseSplitAxis = function (t, i, n) {\n var r = t.leaf ? this.compareMinX : s,\n e = t.leaf ? this.compareMinY : l;\n this._allDistMargin(t, i, n, r) < this._allDistMargin(t, i, n, e) && t.children.sort(r);\n }, r.prototype._allDistMargin = function (t, i, n, r) {\n t.children.sort(r);\n\n for (var e = this.toBBox, a = h(t, 0, i, e), s = h(t, n - i, n, e), l = u(a) + u(s), f = i; f < n - i; f++) {\n var m = t.children[f];\n o(a, t.leaf ? e(m) : m), l += u(a);\n }\n\n for (var c = n - i - 1; c >= i; c--) {\n var p = t.children[c];\n o(s, t.leaf ? e(p) : p), l += u(s);\n }\n\n return l;\n }, r.prototype._adjustParentBBoxes = function (t, i, n) {\n for (var r = n; r >= 0; r--) {\n o(i[r], t);\n }\n }, r.prototype._condense = function (t) {\n for (var i = t.length - 1, n = void 0; i >= 0; i--) {\n 0 === t[i].children.length ? i > 0 ? (n = t[i - 1].children).splice(n.indexOf(t[i]), 1) : this.clear() : a(t[i], this.toBBox);\n }\n }, r;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9yYnVzaC9yYnVzaC5taW4uanM/NzliYyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBLEVBQUUsS0FBMEQsMEJBQTBCLENBQW1GO0FBQ3pLLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxzREFBc0QsT0FBTztBQUM3RCxvQ0FBb0MsZ0JBQWdCO0FBQ3BEO0FBQ0E7O0FBRUEsZ0JBQWdCLGdCQUFnQjtBQUNoQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsbUJBQW1CLGNBQWM7QUFDakM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1CQUFtQixPQUFPO0FBQzFCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0JBQXdCLFVBQVU7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxHQUFHO0FBQ3hDLHFCQUFxQix1QkFBdUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLG9CQUFvQixHQUFHO0FBQ3ZCLHFCQUFxQix1QkFBdUI7QUFDNUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQSxxQkFBcUIsY0FBYztBQUNuQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSx1RUFBdUU7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDs7QUFFQSx3RUFBd0UsZUFBZTtBQUN2RjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNILG9CQUFvQixHQUFHO0FBQ3ZCO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsUUFBUTtBQUMzQjtBQUNBOztBQUVBLHFCQUFxQixRQUFRO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNILFVBQVUsMENBQTBDO0FBQ3BELHVEQUF1RCx1QkFBdUI7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBLHFDQUFxQyxtREFBbUQ7QUFDeEY7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSCw4REFBOEQsWUFBWTtBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBLCtGQUErRixXQUFXO0FBQzFHO0FBQ0E7QUFDQTs7QUFFQSwyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0gsbUJBQW1CLFFBQVE7QUFDM0I7QUFDQTtBQUNBLEdBQUc7QUFDSCwwQ0FBMEMsUUFBUTtBQUNsRDtBQUNBO0FBQ0EsR0FBRztBQUNILENBQUMiLCJmaWxlIjoiNTc5Mi5qcyIsInNvdXJjZXNDb250ZW50IjpbIiFmdW5jdGlvbiAodCwgaSkge1xuICBcIm9iamVjdFwiID09IHR5cGVvZiBleHBvcnRzICYmIFwidW5kZWZpbmVkXCIgIT0gdHlwZW9mIG1vZHVsZSA/IG1vZHVsZS5leHBvcnRzID0gaSgpIDogXCJmdW5jdGlvblwiID09IHR5cGVvZiBkZWZpbmUgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShpKSA6ICh0ID0gdCB8fCBzZWxmKS5SQnVzaCA9IGkoKTtcbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiB0KHQsIHIsIGUsIGEsIGgpIHtcbiAgICAhZnVuY3Rpb24gdChuLCByLCBlLCBhLCBoKSB7XG4gICAgICBmb3IgKDsgYSA+IGU7KSB7XG4gICAgICAgIGlmIChhIC0gZSA+IDYwMCkge1xuICAgICAgICAgIHZhciBvID0gYSAtIGUgKyAxLFxuICAgICAgICAgICAgICBzID0gciAtIGUgKyAxLFxuICAgICAgICAgICAgICBsID0gTWF0aC5sb2cobyksXG4gICAgICAgICAgICAgIGYgPSAuNSAqIE1hdGguZXhwKDIgKiBsIC8gMyksXG4gICAgICAgICAgICAgIHUgPSAuNSAqIE1hdGguc3FydChsICogZiAqIChvIC0gZikgLyBvKSAqIChzIC0gbyAvIDIgPCAwID8gLTEgOiAxKSxcbiAgICAgICAgICAgICAgbSA9IE1hdGgubWF4KGUsIE1hdGguZmxvb3IociAtIHMgKiBmIC8gbyArIHUpKSxcbiAgICAgICAgICAgICAgYyA9IE1hdGgubWluKGEsIE1hdGguZmxvb3IociArIChvIC0gcykgKiBmIC8gbyArIHUpKTtcbiAgICAgICAgICB0KG4sIHIsIG0sIGMsIGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHAgPSBuW3JdLFxuICAgICAgICAgICAgZCA9IGUsXG4gICAgICAgICAgICB4ID0gYTtcblxuICAgICAgICBmb3IgKGkobiwgZSwgciksIGgoblthXSwgcCkgPiAwICYmIGkobiwgZSwgYSk7IGQgPCB4Oykge1xuICAgICAgICAgIGZvciAoaShuLCBkLCB4KSwgZCsrLCB4LS07IGgobltkXSwgcCkgPCAwOykge1xuICAgICAgICAgICAgZCsrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAoOyBoKG5beF0sIHApID4gMDspIHtcbiAgICAgICAgICAgIHgtLTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAwID09PSBoKG5bZV0sIHApID8gaShuLCBlLCB4KSA6IGkobiwgKyt4LCBhKSwgeCA8PSByICYmIChlID0geCArIDEpLCByIDw9IHggJiYgKGEgPSB4IC0gMSk7XG4gICAgICB9XG4gICAgfSh0LCByLCBlIHx8IDAsIGEgfHwgdC5sZW5ndGggLSAxLCBoIHx8IG4pO1xuICB9XG5cbiAgZnVuY3Rpb24gaSh0LCBpLCBuKSB7XG4gICAgdmFyIHIgPSB0W2ldO1xuICAgIHRbaV0gPSB0W25dLCB0W25dID0gcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIG4odCwgaSkge1xuICAgIHJldHVybiB0IDwgaSA/IC0xIDogdCA+IGkgPyAxIDogMDtcbiAgfVxuXG4gIHZhciByID0gZnVuY3Rpb24gcih0KSB7XG4gICAgdm9pZCAwID09PSB0ICYmICh0ID0gOSksIHRoaXMuX21heEVudHJpZXMgPSBNYXRoLm1heCg0LCB0KSwgdGhpcy5fbWluRW50cmllcyA9IE1hdGgubWF4KDIsIE1hdGguY2VpbCguNCAqIHRoaXMuX21heEVudHJpZXMpKSwgdGhpcy5jbGVhcigpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGUodCwgaSwgbikge1xuICAgIGlmICghbikgcmV0dXJuIGkuaW5kZXhPZih0KTtcblxuICAgIGZvciAodmFyIHIgPSAwOyByIDwgaS5sZW5ndGg7IHIrKykge1xuICAgICAgaWYgKG4odCwgaVtyXSkpIHJldHVybiByO1xuICAgIH1cblxuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGEodCwgaSkge1xuICAgIGgodCwgMCwgdC5jaGlsZHJlbi5sZW5ndGgsIGksIHQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaCh0LCBpLCBuLCByLCBlKSB7XG4gICAgZSB8fCAoZSA9IHAobnVsbCkpLCBlLm1pblggPSAxIC8gMCwgZS5taW5ZID0gMSAvIDAsIGUubWF4WCA9IC0xIC8gMCwgZS5tYXhZID0gLTEgLyAwO1xuXG4gICAgZm9yICh2YXIgYSA9IGk7IGEgPCBuOyBhKyspIHtcbiAgICAgIHZhciBoID0gdC5jaGlsZHJlblthXTtcbiAgICAgIG8oZSwgdC5sZWFmID8gcihoKSA6IGgpO1xuICAgIH1cblxuICAgIHJldHVybiBlO1xuICB9XG5cbiAgZnVuY3Rpb24gbyh0LCBpKSB7XG4gICAgcmV0dXJuIHQubWluWCA9IE1hdGgubWluKHQubWluWCwgaS5taW5YKSwgdC5taW5ZID0gTWF0aC5taW4odC5taW5ZLCBpLm1pblkpLCB0Lm1heFggPSBNYXRoLm1heCh0Lm1heFgsIGkubWF4WCksIHQubWF4WSA9IE1hdGgubWF4KHQubWF4WSwgaS5tYXhZKSwgdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHModCwgaSkge1xuICAgIHJldHVybiB0Lm1pblggLSBpLm1pblg7XG4gIH1cblxuICBmdW5jdGlvbiBsKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5ZIC0gaS5taW5ZO1xuICB9XG5cbiAgZnVuY3Rpb24gZih0KSB7XG4gICAgcmV0dXJuICh0Lm1heFggLSB0Lm1pblgpICogKHQubWF4WSAtIHQubWluWSk7XG4gIH1cblxuICBmdW5jdGlvbiB1KHQpIHtcbiAgICByZXR1cm4gdC5tYXhYIC0gdC5taW5YICsgKHQubWF4WSAtIHQubWluWSk7XG4gIH1cblxuICBmdW5jdGlvbiBtKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5YIDw9IGkubWluWCAmJiB0Lm1pblkgPD0gaS5taW5ZICYmIGkubWF4WCA8PSB0Lm1heFggJiYgaS5tYXhZIDw9IHQubWF4WTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGModCwgaSkge1xuICAgIHJldHVybiBpLm1pblggPD0gdC5tYXhYICYmIGkubWluWSA8PSB0Lm1heFkgJiYgaS5tYXhYID49IHQubWluWCAmJiBpLm1heFkgPj0gdC5taW5ZO1xuICB9XG5cbiAgZnVuY3Rpb24gcCh0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNoaWxkcmVuOiB0LFxuICAgICAgaGVpZ2h0OiAxLFxuICAgICAgbGVhZjogITAsXG4gICAgICBtaW5YOiAxIC8gMCxcbiAgICAgIG1pblk6IDEgLyAwLFxuICAgICAgbWF4WDogLTEgLyAwLFxuICAgICAgbWF4WTogLTEgLyAwXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGQoaSwgbiwgciwgZSwgYSkge1xuICAgIGZvciAodmFyIGggPSBbbiwgcl07IGgubGVuZ3RoOykge1xuICAgICAgaWYgKCEoKHIgPSBoLnBvcCgpKSAtIChuID0gaC5wb3AoKSkgPD0gZSkpIHtcbiAgICAgICAgdmFyIG8gPSBuICsgTWF0aC5jZWlsKChyIC0gbikgLyBlIC8gMikgKiBlO1xuICAgICAgICB0KGksIG8sIG4sIHIsIGEpLCBoLnB1c2gobiwgbywgbywgcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHIucHJvdG90eXBlLmFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsKHRoaXMuZGF0YSwgW10pO1xuICB9LCByLnByb3RvdHlwZS5zZWFyY2ggPSBmdW5jdGlvbiAodCkge1xuICAgIHZhciBpID0gdGhpcy5kYXRhLFxuICAgICAgICBuID0gW107XG4gICAgaWYgKCFjKHQsIGkpKSByZXR1cm4gbjtcblxuICAgIGZvciAodmFyIHIgPSB0aGlzLnRvQkJveCwgZSA9IFtdOyBpOykge1xuICAgICAgZm9yICh2YXIgYSA9IDA7IGEgPCBpLmNoaWxkcmVuLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgIHZhciBoID0gaS5jaGlsZHJlblthXSxcbiAgICAgICAgICAgIG8gPSBpLmxlYWYgPyByKGgpIDogaDtcbiAgICAgICAgYyh0LCBvKSAmJiAoaS5sZWFmID8gbi5wdXNoKGgpIDogbSh0LCBvKSA/IHRoaXMuX2FsbChoLCBuKSA6IGUucHVzaChoKSk7XG4gICAgICB9XG5cbiAgICAgIGkgPSBlLnBvcCgpO1xuICAgIH1cblxuICAgIHJldHVybiBuO1xuICB9LCByLnByb3RvdHlwZS5jb2xsaWRlcyA9IGZ1bmN0aW9uICh0KSB7XG4gICAgdmFyIGkgPSB0aGlzLmRhdGE7XG4gICAgaWYgKCFjKHQsIGkpKSByZXR1cm4gITE7XG5cbiAgICBmb3IgKHZhciBuID0gW107IGk7KSB7XG4gICAgICBmb3IgKHZhciByID0gMDsgciA8IGkuY2hpbGRyZW4ubGVuZ3RoOyByKyspIHtcbiAgICAgICAgdmFyIGUgPSBpLmNoaWxkcmVuW3JdLFxuICAgICAgICAgICAgYSA9IGkubGVhZiA/IHRoaXMudG9CQm94KGUpIDogZTtcblxuICAgICAgICBpZiAoYyh0LCBhKSkge1xuICAgICAgICAgIGlmIChpLmxlYWYgfHwgbSh0LCBhKSkgcmV0dXJuICEwO1xuICAgICAgICAgIG4ucHVzaChlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpID0gbi5wb3AoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gITE7XG4gIH0sIHIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAodCkge1xuICAgIGlmICghdCB8fCAhdC5sZW5ndGgpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKHQubGVuZ3RoIDwgdGhpcy5fbWluRW50cmllcykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0KHRbaV0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgbiA9IHRoaXMuX2J1aWxkKHQuc2xpY2UoKSwgMCwgdC5sZW5ndGggLSAxLCAwKTtcblxuICAgIGlmICh0aGlzLmRhdGEuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy5kYXRhLmhlaWdodCA9PT0gbi5oZWlnaHQpIHRoaXMuX3NwbGl0Um9vdCh0aGlzLmRhdGEsIG4pO2Vsc2Uge1xuICAgICAgICBpZiAodGhpcy5kYXRhLmhlaWdodCA8IG4uaGVpZ2h0KSB7XG4gICAgICAgICAgdmFyIHIgPSB0aGlzLmRhdGE7XG4gICAgICAgICAgdGhpcy5kYXRhID0gbiwgbiA9IHI7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9pbnNlcnQobiwgdGhpcy5kYXRhLmhlaWdodCAtIG4uaGVpZ2h0IC0gMSwgITApO1xuICAgICAgfVxuICAgIH0gZWxzZSB0aGlzLmRhdGEgPSBuO1xuICAgIHJldHVybiB0aGlzO1xuICB9LCByLnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbiAodCkge1xuICAgIHJldHVybiB0ICYmIHRoaXMuX2luc2VydCh0LCB0aGlzLmRhdGEuaGVpZ2h0IC0gMSksIHRoaXM7XG4gIH0sIHIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEgPSBwKFtdKSwgdGhpcztcbiAgfSwgci5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICBpZiAoIXQpIHJldHVybiB0aGlzO1xuXG4gICAgZm9yICh2YXIgbiwgciwgYSwgaCA9IHRoaXMuZGF0YSwgbyA9IHRoaXMudG9CQm94KHQpLCBzID0gW10sIGwgPSBbXTsgaCB8fCBzLmxlbmd0aDspIHtcbiAgICAgIGlmIChoIHx8IChoID0gcy5wb3AoKSwgciA9IHNbcy5sZW5ndGggLSAxXSwgbiA9IGwucG9wKCksIGEgPSAhMCksIGgubGVhZikge1xuICAgICAgICB2YXIgZiA9IGUodCwgaC5jaGlsZHJlbiwgaSk7XG4gICAgICAgIGlmICgtMSAhPT0gZikgcmV0dXJuIGguY2hpbGRyZW4uc3BsaWNlKGYsIDEpLCBzLnB1c2goaCksIHRoaXMuX2NvbmRlbnNlKHMpLCB0aGlzO1xuICAgICAgfVxuXG4gICAgICBhIHx8IGgubGVhZiB8fCAhbShoLCBvKSA/IHIgPyAobisrLCBoID0gci5jaGlsZHJlbltuXSwgYSA9ICExKSA6IGggPSBudWxsIDogKHMucHVzaChoKSwgbC5wdXNoKG4pLCBuID0gMCwgciA9IGgsIGggPSBoLmNoaWxkcmVuWzBdKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSwgci5wcm90b3R5cGUudG9CQm94ID0gZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gdDtcbiAgfSwgci5wcm90b3R5cGUuY29tcGFyZU1pblggPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHJldHVybiB0Lm1pblggLSBpLm1pblg7XG4gIH0sIHIucHJvdG90eXBlLmNvbXBhcmVNaW5ZID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICByZXR1cm4gdC5taW5ZIC0gaS5taW5ZO1xuICB9LCByLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgfSwgci5wcm90b3R5cGUuZnJvbUpTT04gPSBmdW5jdGlvbiAodCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEgPSB0LCB0aGlzO1xuICB9LCByLnByb3RvdHlwZS5fYWxsID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICBmb3IgKHZhciBuID0gW107IHQ7KSB7XG4gICAgICB0LmxlYWYgPyBpLnB1c2guYXBwbHkoaSwgdC5jaGlsZHJlbikgOiBuLnB1c2guYXBwbHkobiwgdC5jaGlsZHJlbiksIHQgPSBuLnBvcCgpO1xuICAgIH1cblxuICAgIHJldHVybiBpO1xuICB9LCByLnByb3RvdHlwZS5fYnVpbGQgPSBmdW5jdGlvbiAodCwgaSwgbiwgcikge1xuICAgIHZhciBlLFxuICAgICAgICBoID0gbiAtIGkgKyAxLFxuICAgICAgICBvID0gdGhpcy5fbWF4RW50cmllcztcbiAgICBpZiAoaCA8PSBvKSByZXR1cm4gYShlID0gcCh0LnNsaWNlKGksIG4gKyAxKSksIHRoaXMudG9CQm94KSwgZTtcbiAgICByIHx8IChyID0gTWF0aC5jZWlsKE1hdGgubG9nKGgpIC8gTWF0aC5sb2cobykpLCBvID0gTWF0aC5jZWlsKGggLyBNYXRoLnBvdyhvLCByIC0gMSkpKSwgKGUgPSBwKFtdKSkubGVhZiA9ICExLCBlLmhlaWdodCA9IHI7XG4gICAgdmFyIHMgPSBNYXRoLmNlaWwoaCAvIG8pLFxuICAgICAgICBsID0gcyAqIE1hdGguY2VpbChNYXRoLnNxcnQobykpO1xuICAgIGQodCwgaSwgbiwgbCwgdGhpcy5jb21wYXJlTWluWCk7XG5cbiAgICBmb3IgKHZhciBmID0gaTsgZiA8PSBuOyBmICs9IGwpIHtcbiAgICAgIHZhciB1ID0gTWF0aC5taW4oZiArIGwgLSAxLCBuKTtcbiAgICAgIGQodCwgZiwgdSwgcywgdGhpcy5jb21wYXJlTWluWSk7XG5cbiAgICAgIGZvciAodmFyIG0gPSBmOyBtIDw9IHU7IG0gKz0gcykge1xuICAgICAgICB2YXIgYyA9IE1hdGgubWluKG0gKyBzIC0gMSwgdSk7XG4gICAgICAgIGUuY2hpbGRyZW4ucHVzaCh0aGlzLl9idWlsZCh0LCBtLCBjLCByIC0gMSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBhKGUsIHRoaXMudG9CQm94KSwgZTtcbiAgfSwgci5wcm90b3R5cGUuX2Nob29zZVN1YnRyZWUgPSBmdW5jdGlvbiAodCwgaSwgbiwgcikge1xuICAgIGZvciAoOyByLnB1c2goaSksICFpLmxlYWYgJiYgci5sZW5ndGggLSAxICE9PSBuOykge1xuICAgICAgZm9yICh2YXIgZSA9IDEgLyAwLCBhID0gMSAvIDAsIGggPSB2b2lkIDAsIG8gPSAwOyBvIDwgaS5jaGlsZHJlbi5sZW5ndGg7IG8rKykge1xuICAgICAgICB2YXIgcyA9IGkuY2hpbGRyZW5bb10sXG4gICAgICAgICAgICBsID0gZihzKSxcbiAgICAgICAgICAgIHUgPSAobSA9IHQsIGMgPSBzLCAoTWF0aC5tYXgoYy5tYXhYLCBtLm1heFgpIC0gTWF0aC5taW4oYy5taW5YLCBtLm1pblgpKSAqIChNYXRoLm1heChjLm1heFksIG0ubWF4WSkgLSBNYXRoLm1pbihjLm1pblksIG0ubWluWSkpIC0gbCk7XG4gICAgICAgIHUgPCBhID8gKGEgPSB1LCBlID0gbCA8IGUgPyBsIDogZSwgaCA9IHMpIDogdSA9PT0gYSAmJiBsIDwgZSAmJiAoZSA9IGwsIGggPSBzKTtcbiAgICAgIH1cblxuICAgICAgaSA9IGggfHwgaS5jaGlsZHJlblswXTtcbiAgICB9XG5cbiAgICB2YXIgbSwgYztcbiAgICByZXR1cm4gaTtcbiAgfSwgci5wcm90b3R5cGUuX2luc2VydCA9IGZ1bmN0aW9uICh0LCBpLCBuKSB7XG4gICAgdmFyIHIgPSBuID8gdCA6IHRoaXMudG9CQm94KHQpLFxuICAgICAgICBlID0gW10sXG4gICAgICAgIGEgPSB0aGlzLl9jaG9vc2VTdWJ0cmVlKHIsIHRoaXMuZGF0YSwgaSwgZSk7XG5cbiAgICBmb3IgKGEuY2hpbGRyZW4ucHVzaCh0KSwgbyhhLCByKTsgaSA+PSAwICYmIGVbaV0uY2hpbGRyZW4ubGVuZ3RoID4gdGhpcy5fbWF4RW50cmllczspIHtcbiAgICAgIHRoaXMuX3NwbGl0KGUsIGkpLCBpLS07XG4gICAgfVxuXG4gICAgdGhpcy5fYWRqdXN0UGFyZW50QkJveGVzKHIsIGUsIGkpO1xuICB9LCByLnByb3RvdHlwZS5fc3BsaXQgPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHZhciBuID0gdFtpXSxcbiAgICAgICAgciA9IG4uY2hpbGRyZW4ubGVuZ3RoLFxuICAgICAgICBlID0gdGhpcy5fbWluRW50cmllcztcblxuICAgIHRoaXMuX2Nob29zZVNwbGl0QXhpcyhuLCBlLCByKTtcblxuICAgIHZhciBoID0gdGhpcy5fY2hvb3NlU3BsaXRJbmRleChuLCBlLCByKSxcbiAgICAgICAgbyA9IHAobi5jaGlsZHJlbi5zcGxpY2UoaCwgbi5jaGlsZHJlbi5sZW5ndGggLSBoKSk7XG5cbiAgICBvLmhlaWdodCA9IG4uaGVpZ2h0LCBvLmxlYWYgPSBuLmxlYWYsIGEobiwgdGhpcy50b0JCb3gpLCBhKG8sIHRoaXMudG9CQm94KSwgaSA/IHRbaSAtIDFdLmNoaWxkcmVuLnB1c2gobykgOiB0aGlzLl9zcGxpdFJvb3Qobiwgbyk7XG4gIH0sIHIucHJvdG90eXBlLl9zcGxpdFJvb3QgPSBmdW5jdGlvbiAodCwgaSkge1xuICAgIHRoaXMuZGF0YSA9IHAoW3QsIGldKSwgdGhpcy5kYXRhLmhlaWdodCA9IHQuaGVpZ2h0ICsgMSwgdGhpcy5kYXRhLmxlYWYgPSAhMSwgYSh0aGlzLmRhdGEsIHRoaXMudG9CQm94KTtcbiAgfSwgci5wcm90b3R5cGUuX2Nob29zZVNwbGl0SW5kZXggPSBmdW5jdGlvbiAodCwgaSwgbikge1xuICAgIGZvciAodmFyIHIsIGUsIGEsIG8sIHMsIGwsIHUsIG0gPSAxIC8gMCwgYyA9IDEgLyAwLCBwID0gaTsgcCA8PSBuIC0gaTsgcCsrKSB7XG4gICAgICB2YXIgZCA9IGgodCwgMCwgcCwgdGhpcy50b0JCb3gpLFxuICAgICAgICAgIHggPSBoKHQsIHAsIG4sIHRoaXMudG9CQm94KSxcbiAgICAgICAgICB2ID0gKGUgPSBkLCBhID0geCwgbyA9IHZvaWQgMCwgcyA9IHZvaWQgMCwgbCA9IHZvaWQgMCwgdSA9IHZvaWQgMCwgbyA9IE1hdGgubWF4KGUubWluWCwgYS5taW5YKSwgcyA9IE1hdGgubWF4KGUubWluWSwgYS5taW5ZKSwgbCA9IE1hdGgubWluKGUubWF4WCwgYS5tYXhYKSwgdSA9IE1hdGgubWluKGUubWF4WSwgYS5tYXhZKSwgTWF0aC5tYXgoMCwgbCAtIG8pICogTWF0aC5tYXgoMCwgdSAtIHMpKSxcbiAgICAgICAgICBNID0gZihkKSArIGYoeCk7XG4gICAgICB2IDwgbSA/IChtID0gdiwgciA9IHAsIGMgPSBNIDwgYyA/IE0gOiBjKSA6IHYgPT09IG0gJiYgTSA8IGMgJiYgKGMgPSBNLCByID0gcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHIgfHwgbiAtIGk7XG4gIH0sIHIucHJvdG90eXBlLl9jaG9vc2VTcGxpdEF4aXMgPSBmdW5jdGlvbiAodCwgaSwgbikge1xuICAgIHZhciByID0gdC5sZWFmID8gdGhpcy5jb21wYXJlTWluWCA6IHMsXG4gICAgICAgIGUgPSB0LmxlYWYgPyB0aGlzLmNvbXBhcmVNaW5ZIDogbDtcbiAgICB0aGlzLl9hbGxEaXN0TWFyZ2luKHQsIGksIG4sIHIpIDwgdGhpcy5fYWxsRGlzdE1hcmdpbih0LCBpLCBuLCBlKSAmJiB0LmNoaWxkcmVuLnNvcnQocik7XG4gIH0sIHIucHJvdG90eXBlLl9hbGxEaXN0TWFyZ2luID0gZnVuY3Rpb24gKHQsIGksIG4sIHIpIHtcbiAgICB0LmNoaWxkcmVuLnNvcnQocik7XG5cbiAgICBmb3IgKHZhciBlID0gdGhpcy50b0JCb3gsIGEgPSBoKHQsIDAsIGksIGUpLCBzID0gaCh0LCBuIC0gaSwgbiwgZSksIGwgPSB1KGEpICsgdShzKSwgZiA9IGk7IGYgPCBuIC0gaTsgZisrKSB7XG4gICAgICB2YXIgbSA9IHQuY2hpbGRyZW5bZl07XG4gICAgICBvKGEsIHQubGVhZiA/IGUobSkgOiBtKSwgbCArPSB1KGEpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGMgPSBuIC0gaSAtIDE7IGMgPj0gaTsgYy0tKSB7XG4gICAgICB2YXIgcCA9IHQuY2hpbGRyZW5bY107XG4gICAgICBvKHMsIHQubGVhZiA/IGUocCkgOiBwKSwgbCArPSB1KHMpO1xuICAgIH1cblxuICAgIHJldHVybiBsO1xuICB9LCByLnByb3RvdHlwZS5fYWRqdXN0UGFyZW50QkJveGVzID0gZnVuY3Rpb24gKHQsIGksIG4pIHtcbiAgICBmb3IgKHZhciByID0gbjsgciA+PSAwOyByLS0pIHtcbiAgICAgIG8oaVtyXSwgdCk7XG4gICAgfVxuICB9LCByLnByb3RvdHlwZS5fY29uZGVuc2UgPSBmdW5jdGlvbiAodCkge1xuICAgIGZvciAodmFyIGkgPSB0Lmxlbmd0aCAtIDEsIG4gPSB2b2lkIDA7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAwID09PSB0W2ldLmNoaWxkcmVuLmxlbmd0aCA/IGkgPiAwID8gKG4gPSB0W2kgLSAxXS5jaGlsZHJlbikuc3BsaWNlKG4uaW5kZXhPZih0W2ldKSwgMSkgOiB0aGlzLmNsZWFyKCkgOiBhKHRbaV0sIHRoaXMudG9CQm94KTtcbiAgICB9XG4gIH0sIHI7XG59KTsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5792\n')},4239:function(module){eval('// Generated by CoffeeScript 1.10.0\n(function () {\n var families;\n module.exports = {\n icon: \'icons/google.svg\',\n name: \'google\',\n title: \'Google Fonts\',\n link: \'google.com/fonts\',\n getNames: function getNames() {\n return families;\n },\n getLink: function getLink(name) {\n return "https://fonts.google.com/specimen/" + name.replace(/( )/g, \'+\');\n },\n normalizeName: function normalizeName(name) {\n return name;\n }\n };\n families = ["ABeeZee", "Abel", "Abril Fatface", "Aclonica", "Acme", "Actor", "Adamina", "Advent Pro", "Aguafina Script", "Akronim", "Aladin", "Aldrich", "Alef", "Alegreya", "Alegreya SC", "Alegreya Sans", "Alegreya Sans SC", "Alex Brush", "Alfa Slab One", "Alice", "Alike", "Alike Angular", "Allan", "Allerta", "Allerta Stencil", "Allura", "Almendra", "Almendra Display", "Almendra SC", "Amarante", "Amaranth", "Amatic SC", "Amethysta", "Amiri", "Amita", "Anaheim", "Andada", "Andika", "Angkor", "Annie Use Your Telescope", "Anonymous Pro", "Antic", "Antic Didone", "Antic Slab", "Anton", "Arapey", "Arbutus", "Arbutus Slab", "Architects Daughter", "Archivo Black", "Archivo Narrow", "Arimo", "Arizonia", "Armata", "Artifika", "Arvo", "Arya", "Asap", "Asar", "Asset", "Astloch", "Asul", "Atomic Age", "Aubrey", "Audiowide", "Autour One", "Average", "Average Sans", "Averia Gruesa Libre", "Averia Libre", "Averia Sans Libre", "Averia Serif Libre", "Bad Script", "Balthazar", "Bangers", "Basic", "Battambang", "Baumans", "Bayon", "Belgrano", "Belleza", "BenchNine", "Bentham", "Berkshire Swash", "Bevan", "Bigelow Rules", "Bigshot One", "Bilbo", "Bilbo Swash Caps", "Biryani", "Bitter", "Black Ops One", "Bokor", "Bonbon", "Boogaloo", "Bowlby One", "Bowlby One SC", "Brawler", "Bree Serif", "Bubblegum Sans", "Bubbler One", "Buda", "Buenard", "Butcherman", "Butterfly Kids", "Cabin", "Cabin Condensed", "Cabin Sketch", "Caesar Dressing", "Cagliostro", "Calligraffitti", "Cambay", "Cambo", "Candal", "Cantarell", "Cantata One", "Cantora One", "Capriola", "Cardo", "Carme", "Carrois Gothic", "Carrois Gothic SC", "Carter One", "Catamaran", "Caudex", "Caveat", "Caveat Brush", "Cedarville Cursive", "Ceviche One", "Changa One", "Chango", "Chau Philomene One", "Chela One", "Chelsea Market", "Chenla", "Cherry Cream Soda", "Cherry Swash", "Chewy", "Chicle", "Chivo", "Chonburi", "Cinzel", "Cinzel Decorative", "Clicker Script", "Coda", "Coda Caption", "Codystar", "Combo", "Comfortaa", "Coming Soon", "Concert One", "Condiment", "Content", "Contrail One", "Convergence", "Cookie", "Copse", "Corben", "Courgette", "Cousine", "Coustard", "Covered By Your Grace", "Crafty Girls", "Creepster", "Crete Round", "Crimson Text", "Croissant One", "Crushed", "Cuprum", "Cutive", "Cutive Mono", "Damion", "Dancing Script", "Dangrek", "Dawning of a New Day", "Days One", "Dekko", "Delius", "Delius Swash Caps", "Delius Unicase", "Della Respira", "Denk One", "Devonshire", "Dhurjati", "Didact Gothic", "Diplomata", "Diplomata SC", "Domine", "Donegal One", "Doppio One", "Dorsa", "Dosis", "Dr Sugiyama", "Droid Sans", "Droid Sans Mono", "Droid Serif", "Duru Sans", "Dynalight", "EB Garamond", "Eagle Lake", "Eater", "Economica", "Eczar", "Ek Mukta", "Electrolize", "Elsie", "Elsie Swash Caps", "Emblema One", "Emilys Candy", "Engagement", "Englebert", "Enriqueta", "Erica One", "Esteban", "Euphoria Script", "Ewert", "Exo", "Exo 2", "Expletus Sans", "Fanwood Text", "Fascinate", "Fascinate Inline", "Faster One", "Fasthand", "Fauna One", "Federant", "Federo", "Felipa", "Fenix", "Finger Paint", "Fira Mono", "Fira Sans", "Fjalla One", "Fjord One", "Flamenco", "Flavors", "Fondamento", "Fontdiner Swanky", "Forum", "Francois One", "Freckle Face", "Fredericka the Great", "Fredoka One", "Freehand", "Fresca", "Frijole", "Fruktur", "Fugaz One", "GFS Didot", "GFS Neohellenic", "Gabriela", "Gafata", "Galdeano", "Galindo", "Gentium Basic", "Gentium Book Basic", "Geo", "Geostar", "Geostar Fill", "Germania One", "Gidugu", "Gilda Display", "Give You Glory", "Glass Antiqua", "Glegoo", "Gloria Hallelujah", "Goblin One", "Gochi Hand", "Gorditas", "Goudy Bookletter 1911", "Graduate", "Grand Hotel", "Gravitas One", "Great Vibes", "Griffy", "Gruppo", "Gudea", "Gurajada", "Habibi", "Halant", "Hammersmith One", "Hanalei", "Hanalei Fill", "Handlee", "Hanuman", "Happy Monkey", "Headland One", "Henny Penny", "Herr Von Muellerhoff", "Hind", "Hind Siliguri", "Hind Vadodara", "Holtwood One SC", "Homemade Apple", "Homenaje", "IM Fell DW Pica", "IM Fell DW Pica SC", "IM Fell Double Pica", "IM Fell Double Pica SC", "IM Fell English", "IM Fell English SC", "IM Fell French Canon", "IM Fell French Canon SC", "IM Fell Great Primer", "IM Fell Great Primer SC", "Iceberg", "Iceland", "Imprima", "Inconsolata", "Inder", "Indie Flower", "Inika", "Inknut Antiqua", "Irish Grover", "Istok Web", "Italiana", "Italianno", "Itim", "Jacques Francois", "Jacques Francois Shadow", "Jaldi", "Jim Nightshade", "Jockey One", "Jolly Lodger", "Josefin Sans", "Josefin Slab", "Joti One", "Judson", "Julee", "Julius Sans One", "Junge", "Jura", "Just Another Hand", "Just Me Again Down Here", "Kadwa", "Kalam", "Kameron", "Kantumruy", "Karla", "Karma", "Kaushan Script", "Kavoon", "Kdam Thmor", "Keania One", "Kelly Slab", "Kenia", "Khand", "Khmer", "Khula", "Kite One", "Knewave", "Kotta One", "Koulen", "Kranky", "Kreon", "Kristi", "Krona One", "Kurale", "La Belle Aurore", "Laila", "Lakki Reddy", "Lancelot", "Lateef", "Lato", "League Script", "Leckerli One", "Ledger", "Lekton", "Lemon", "Libre Baskerville", "Life Savers", "Lilita One", "Lily Script One", "Limelight", "Linden Hill", "Lobster", "Lobster Two", "Londrina Outline", "Londrina Shadow", "Londrina Sketch", "Londrina Solid", "Lora", "Love Ya Like A Sister", "Loved by the King", "Lovers Quarrel", "Luckiest Guy", "Lusitana", "Lustria", "Macondo", "Macondo Swash Caps", "Magra", "Maiden Orange", "Mako", "Mallanna", "Mandali", "Marcellus", "Marcellus SC", "Marck Script", "Margarine", "Marko One", "Marmelad", "Martel", "Martel Sans", "Marvel", "Mate", "Mate SC", "Maven Pro", "McLaren", "Meddon", "MedievalSharp", "Medula One", "Megrim", "Meie Script", "Merienda", "Merienda One", "Merriweather", "Merriweather Sans", "Metal", "Metal Mania", "Metamorphous", "Metrophobic", "Michroma", "Milonga", "Miltonian", "Miltonian Tattoo", "Miniver", "Miss Fajardose", "Modak", "Modern Antiqua", "Molengo", "Molle", "Monda", "Monofett", "Monoton", "Monsieur La Doulaise", "Montaga", "Montez", "Montserrat", "Montserrat Alternates", "Montserrat Subrayada", "Moul", "Moulpali", "Mountains of Christmas", "Mouse Memoirs", "Mr Bedfort", "Mr Dafoe", "Mr De Haviland", "Mrs Saint Delafield", "Mrs Sheppards", "Muli", "Mystery Quest", "NTR", "Neucha", "Neuton", "New Rocker", "News Cycle", "Niconne", "Nixie One", "Nobile", "Nokora", "Norican", "Nosifer", "Nothing You Could Do", "Noticia Text", "Noto Sans", "Noto Serif", "Nova Cut", "Nova Flat", "Nova Mono", "Nova Oval", "Nova Round", "Nova Script", "Nova Slim", "Nova Square", "Numans", "Nunito", "Odor Mean Chey", "Offside", "Old Standard TT", "Oldenburg", "Oleo Script", "Oleo Script Swash Caps", "Open Sans", "Open Sans Condensed", "Oranienbaum", "Orbitron", "Oregano", "Orienta", "Original Surfer", "Oswald", "Over the Rainbow", "Overlock", "Overlock SC", "Ovo", "Oxygen", "Oxygen Mono", "PT Mono", "PT Sans", "PT Sans Caption", "PT Sans Narrow", "PT Serif", "PT Serif Caption", "Pacifico", "Palanquin", "Palanquin Dark", "Paprika", "Parisienne", "Passero One", "Passion One", "Pathway Gothic One", "Patrick Hand", "Patrick Hand SC", "Patua One", "Paytone One", "Peddana", "Peralta", "Permanent Marker", "Petit Formal Script", "Petrona", "Philosopher", "Piedra", "Pinyon Script", "Pirata One", "Plaster", "Play", "Playball", "Playfair Display", "Playfair Display SC", "Podkova", "Poiret One", "Poller One", "Poly", "Pompiere", "Pontano Sans", "Poppins", "Port Lligat Sans", "Port Lligat Slab", "Pragati Narrow", "Prata", "Preahvihear", "Press Start 2P", "Princess Sofia", "Prociono", "Prosto One", "Puritan", "Purple Purse", "Quando", "Quantico", "Quattrocento", "Quattrocento Sans", "Questrial", "Quicksand", "Quintessential", "Qwigley", "Racing Sans One", "Radley", "Rajdhani", "Raleway", "Raleway Dots", "Ramabhadra", "Ramaraja", "Rambla", "Rammetto One", "Ranchers", "Rancho", "Ranga", "Rationale", "Ravi Prakash", "Redressed", "Reenie Beanie", "Revalia", "Rhodium Libre", "Ribeye", "Ribeye Marrow", "Righteous", "Risque", "Roboto", "Roboto Condensed", "Roboto Mono", "Roboto Slab", "Rochester", "Rock Salt", "Rokkitt", "Romanesco", "Ropa Sans", "Rosario", "Rosarivo", "Rouge Script", "Rozha One", "Rubik", "Rubik Mono One", "Rubik One", "Ruda", "Rufina", "Ruge Boogie", "Ruluko", "Rum Raisin", "Ruslan Display", "Russo One", "Ruthie", "Rye", "Sacramento", "Sahitya", "Sail", "Salsa", "Sanchez", "Sancreek", "Sansita One", "Sarala", "Sarina", "Sarpanch", "Satisfy", "Scada", "Scheherazade", "Schoolbell", "Seaweed Script", "Sevillana", "Seymour One", "Shadows Into Light", "Shadows Into Light Two", "Shanti", "Share", "Share Tech", "Share Tech Mono", "Shojumaru", "Short Stack", "Siemreap", "Sigmar One", "Signika", "Signika Negative", "Simonetta", "Sintony", "Sirin Stencil", "Six Caps", "Skranji", "Slabo 13px", "Slabo 27px", "Slackey", "Smokum", "Smythe", "Sniglet", "Snippet", "Snowburst One", "Sofadi One", "Sofia", "Sonsie One", "Sorts Mill Goudy", "Source Code Pro", "Source Sans Pro", "Source Serif Pro", "Special Elite", "Spicy Rice", "Spinnaker", "Spirax", "Squada One", "Sree Krushnadevaraya", "Stalemate", "Stalinist One", "Stardos Stencil", "Stint Ultra Condensed", "Stint Ultra Expanded", "Stoke", "Strait", "Sue Ellen Francisco", "Sumana", "Sunshiney", "Supermercado One", "Sura", "Suranna", "Suravaram", "Suwannaphum", "Swanky and Moo Moo", "Syncopate", "Tangerine", "Taprom", "Tauri", "Teko", "Telex", "Tenali Ramakrishna", "Tenor Sans", "Text Me One", "The Girl Next Door", "Tienne", "Tillana", "Timmana", "Tinos", "Titan One", "Titillium Web", "Trade Winds", "Trocchi", "Trochut", "Trykker", "Tulpen One", "Ubuntu", "Ubuntu Condensed", "Ubuntu Mono", "Ultra", "Uncial Antiqua", "Underdog", "Unica One", "UnifrakturCook", "UnifrakturMaguntia", "Unkempt", "Unlock", "Unna", "VT323", "Vampiro One", "Varela", "Varela Round", "Vast Shadow", "Vesper Libre", "Vibur", "Vidaloka", "Viga", "Voces", "Volkhov", "Vollkorn", "Voltaire", "Waiting for the Sunrise", "Wallpoet", "Walter Turncoat", "Warnes", "Wellfleet", "Wendy One", "Wire One", "Work Sans", "Yanone Kaffeesatz", "Yantramanav", "Yellowtail", "Yeseva One", "Yesteryear", "Zeyada"];\n}).call(this);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy93ZWJmb250LW1hdGNoZXIvbGliL2ZvbnRzL2dvb2dsZS5qcz9lYjdhIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMiLCJmaWxlIjoiNDIzOS5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMC4wXG4oZnVuY3Rpb24gKCkge1xuICB2YXIgZmFtaWxpZXM7XG4gIG1vZHVsZS5leHBvcnRzID0ge1xuICAgIGljb246ICdpY29ucy9nb29nbGUuc3ZnJyxcbiAgICBuYW1lOiAnZ29vZ2xlJyxcbiAgICB0aXRsZTogJ0dvb2dsZSBGb250cycsXG4gICAgbGluazogJ2dvb2dsZS5jb20vZm9udHMnLFxuICAgIGdldE5hbWVzOiBmdW5jdGlvbiBnZXROYW1lcygpIHtcbiAgICAgIHJldHVybiBmYW1pbGllcztcbiAgICB9LFxuICAgIGdldExpbms6IGZ1bmN0aW9uIGdldExpbmsobmFtZSkge1xuICAgICAgcmV0dXJuIFwiaHR0cHM6Ly9mb250cy5nb29nbGUuY29tL3NwZWNpbWVuL1wiICsgbmFtZS5yZXBsYWNlKC8oICkvZywgJysnKTtcbiAgICB9LFxuICAgIG5vcm1hbGl6ZU5hbWU6IGZ1bmN0aW9uIG5vcm1hbGl6ZU5hbWUobmFtZSkge1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICB9O1xuICBmYW1pbGllcyA9IFtcIkFCZWVaZWVcIiwgXCJBYmVsXCIsIFwiQWJyaWwgRmF0ZmFjZVwiLCBcIkFjbG9uaWNhXCIsIFwiQWNtZVwiLCBcIkFjdG9yXCIsIFwiQWRhbWluYVwiLCBcIkFkdmVudCBQcm9cIiwgXCJBZ3VhZmluYSBTY3JpcHRcIiwgXCJBa3JvbmltXCIsIFwiQWxhZGluXCIsIFwiQWxkcmljaFwiLCBcIkFsZWZcIiwgXCJBbGVncmV5YVwiLCBcIkFsZWdyZXlhIFNDXCIsIFwiQWxlZ3JleWEgU2Fuc1wiLCBcIkFsZWdyZXlhIFNhbnMgU0NcIiwgXCJBbGV4IEJydXNoXCIsIFwiQWxmYSBTbGFiIE9uZVwiLCBcIkFsaWNlXCIsIFwiQWxpa2VcIiwgXCJBbGlrZSBBbmd1bGFyXCIsIFwiQWxsYW5cIiwgXCJBbGxlcnRhXCIsIFwiQWxsZXJ0YSBTdGVuY2lsXCIsIFwiQWxsdXJhXCIsIFwiQWxtZW5kcmFcIiwgXCJBbG1lbmRyYSBEaXNwbGF5XCIsIFwiQWxtZW5kcmEgU0NcIiwgXCJBbWFyYW50ZVwiLCBcIkFtYXJhbnRoXCIsIFwiQW1hdGljIFNDXCIsIFwiQW1ldGh5c3RhXCIsIFwiQW1pcmlcIiwgXCJBbWl0YVwiLCBcIkFuYWhlaW1cIiwgXCJBbmRhZGFcIiwgXCJBbmRpa2FcIiwgXCJBbmdrb3JcIiwgXCJBbm5pZSBVc2UgWW91ciBUZWxlc2NvcGVcIiwgXCJBbm9ueW1vdXMgUHJvXCIsIFwiQW50aWNcIiwgXCJBbnRpYyBEaWRvbmVcIiwgXCJBbnRpYyBTbGFiXCIsIFwiQW50b25cIiwgXCJBcmFwZXlcIiwgXCJBcmJ1dHVzXCIsIFwiQXJidXR1cyBTbGFiXCIsIFwiQXJjaGl0ZWN0cyBEYXVnaHRlclwiLCBcIkFyY2hpdm8gQmxhY2tcIiwgXCJBcmNoaXZvIE5hcnJvd1wiLCBcIkFyaW1vXCIsIFwiQXJpem9uaWFcIiwgXCJBcm1hdGFcIiwgXCJBcnRpZmlrYVwiLCBcIkFydm9cIiwgXCJBcnlhXCIsIFwiQXNhcFwiLCBcIkFzYXJcIiwgXCJBc3NldFwiLCBcIkFzdGxvY2hcIiwgXCJBc3VsXCIsIFwiQXRvbWljIEFnZVwiLCBcIkF1YnJleVwiLCBcIkF1ZGlvd2lkZVwiLCBcIkF1dG91ciBPbmVcIiwgXCJBdmVyYWdlXCIsIFwiQXZlcmFnZSBTYW5zXCIsIFwiQXZlcmlhIEdydWVzYSBMaWJyZVwiLCBcIkF2ZXJpYSBMaWJyZVwiLCBcIkF2ZXJpYSBTYW5zIExpYnJlXCIsIFwiQXZlcmlhIFNlcmlmIExpYnJlXCIsIFwiQmFkIFNjcmlwdFwiLCBcIkJhbHRoYXphclwiLCBcIkJhbmdlcnNcIiwgXCJCYXNpY1wiLCBcIkJhdHRhbWJhbmdcIiwgXCJCYXVtYW5zXCIsIFwiQmF5b25cIiwgXCJCZWxncmFub1wiLCBcIkJlbGxlemFcIiwgXCJCZW5jaE5pbmVcIiwgXCJCZW50aGFtXCIsIFwiQmVya3NoaXJlIFN3YXNoXCIsIFwiQmV2YW5cIiwgXCJCaWdlbG93IFJ1bGVzXCIsIFwiQmlnc2hvdCBPbmVcIiwgXCJCaWxib1wiLCBcIkJpbGJvIFN3YXNoIENhcHNcIiwgXCJCaXJ5YW5pXCIsIFwiQml0dGVyXCIsIFwiQmxhY2sgT3BzIE9uZVwiLCBcIkJva29yXCIsIFwiQm9uYm9uXCIsIFwiQm9vZ2Fsb29cIiwgXCJCb3dsYnkgT25lXCIsIFwiQm93bGJ5IE9uZSBTQ1wiLCBcIkJyYXdsZXJcIiwgXCJCcmVlIFNlcmlmXCIsIFwiQnViYmxlZ3VtIFNhbnNcIiwgXCJCdWJibGVyIE9uZVwiLCBcIkJ1ZGFcIiwgXCJCdWVuYXJkXCIsIFwiQnV0Y2hlcm1hblwiLCBcIkJ1dHRlcmZseSBLaWRzXCIsIFwiQ2FiaW5cIiwgXCJDYWJpbiBDb25kZW5zZWRcIiwgXCJDYWJpbiBTa2V0Y2hcIiwgXCJDYWVzYXIgRHJlc3NpbmdcIiwgXCJDYWdsaW9zdHJvXCIsIFwiQ2FsbGlncmFmZml0dGlcIiwgXCJDYW1iYXlcIiwgXCJDYW1ib1wiLCBcIkNhbmRhbFwiLCBcIkNhbnRhcmVsbFwiLCBcIkNhbnRhdGEgT25lXCIsIFwiQ2FudG9yYSBPbmVcIiwgXCJDYXByaW9sYVwiLCBcIkNhcmRvXCIsIFwiQ2FybWVcIiwgXCJDYXJyb2lzIEdvdGhpY1wiLCBcIkNhcnJvaXMgR290aGljIFNDXCIsIFwiQ2FydGVyIE9uZVwiLCBcIkNhdGFtYXJhblwiLCBcIkNhdWRleFwiLCBcIkNhdmVhdFwiLCBcIkNhdmVhdCBCcnVzaFwiLCBcIkNlZGFydmlsbGUgQ3Vyc2l2ZVwiLCBcIkNldmljaGUgT25lXCIsIFwiQ2hhbmdhIE9uZVwiLCBcIkNoYW5nb1wiLCBcIkNoYXUgUGhpbG9tZW5lIE9uZVwiLCBcIkNoZWxhIE9uZVwiLCBcIkNoZWxzZWEgTWFya2V0XCIsIFwiQ2hlbmxhXCIsIFwiQ2hlcnJ5IENyZWFtIFNvZGFcIiwgXCJDaGVycnkgU3dhc2hcIiwgXCJDaGV3eVwiLCBcIkNoaWNsZVwiLCBcIkNoaXZvXCIsIFwiQ2hvbmJ1cmlcIiwgXCJDaW56ZWxcIiwgXCJDaW56ZWwgRGVjb3JhdGl2ZVwiLCBcIkNsaWNrZXIgU2NyaXB0XCIsIFwiQ29kYVwiLCBcIkNvZGEgQ2FwdGlvblwiLCBcIkNvZHlzdGFyXCIsIFwiQ29tYm9cIiwgXCJDb21mb3J0YWFcIiwgXCJDb21pbmcgU29vblwiLCBcIkNvbmNlcnQgT25lXCIsIFwiQ29uZGltZW50XCIsIFwiQ29udGVudFwiLCBcIkNvbnRyYWlsIE9uZVwiLCBcIkNvbnZlcmdlbmNlXCIsIFwiQ29va2llXCIsIFwiQ29wc2VcIiwgXCJDb3JiZW5cIiwgXCJDb3VyZ2V0dGVcIiwgXCJDb3VzaW5lXCIsIFwiQ291c3RhcmRcIiwgXCJDb3ZlcmVkIEJ5IFlvdXIgR3JhY2VcIiwgXCJDcmFmdHkgR2lybHNcIiwgXCJDcmVlcHN0ZXJcIiwgXCJDcmV0ZSBSb3VuZFwiLCBcIkNyaW1zb24gVGV4dFwiLCBcIkNyb2lzc2FudCBPbmVcIiwgXCJDcnVzaGVkXCIsIFwiQ3VwcnVtXCIsIFwiQ3V0aXZlXCIsIFwiQ3V0aXZlIE1vbm9cIiwgXCJEYW1pb25cIiwgXCJEYW5jaW5nIFNjcmlwdFwiLCBcIkRhbmdyZWtcIiwgXCJEYXduaW5nIG9mIGEgTmV3IERheVwiLCBcIkRheXMgT25lXCIsIFwiRGVra29cIiwgXCJEZWxpdXNcIiwgXCJEZWxpdXMgU3dhc2ggQ2Fwc1wiLCBcIkRlbGl1cyBVbmljYXNlXCIsIFwiRGVsbGEgUmVzcGlyYVwiLCBcIkRlbmsgT25lXCIsIFwiRGV2b25zaGlyZVwiLCBcIkRodXJqYXRpXCIsIFwiRGlkYWN0IEdvdGhpY1wiLCBcIkRpcGxvbWF0YVwiLCBcIkRpcGxvbWF0YSBTQ1wiLCBcIkRvbWluZVwiLCBcIkRvbmVnYWwgT25lXCIsIFwiRG9wcGlvIE9uZVwiLCBcIkRvcnNhXCIsIFwiRG9zaXNcIiwgXCJEciBTdWdpeWFtYVwiLCBcIkRyb2lkIFNhbnNcIiwgXCJEcm9pZCBTYW5zIE1vbm9cIiwgXCJEcm9pZCBTZXJpZlwiLCBcIkR1cnUgU2Fuc1wiLCBcIkR5bmFsaWdodFwiLCBcIkVCIEdhcmFtb25kXCIsIFwiRWFnbGUgTGFrZVwiLCBcIkVhdGVyXCIsIFwiRWNvbm9taWNhXCIsIFwiRWN6YXJcIiwgXCJFayBNdWt0YVwiLCBcIkVsZWN0cm9saXplXCIsIFwiRWxzaWVcIiwgXCJFbHNpZSBTd2FzaCBDYXBzXCIsIFwiRW1ibGVtYSBPbmVcIiwgXCJFbWlseXMgQ2FuZHlcIiwgXCJFbmdhZ2VtZW50XCIsIFwiRW5nbGViZXJ0XCIsIFwiRW5yaXF1ZXRhXCIsIFwiRXJpY2EgT25lXCIsIFwiRXN0ZWJhblwiLCBcIkV1cGhvcmlhIFNjcmlwdFwiLCBcIkV3ZXJ0XCIsIFwiRXhvXCIsIFwiRXhvIDJcIiwgXCJFeHBsZXR1cyBTYW5zXCIsIFwiRmFud29vZCBUZXh0XCIsIFwiRmFzY2luYXRlXCIsIFwiRmFzY2luYXRlIElubGluZVwiLCBcIkZhc3RlciBPbmVcIiwgXCJGYXN0aGFuZFwiLCBcIkZhdW5hIE9uZVwiLCBcIkZlZGVyYW50XCIsIFwiRmVkZXJvXCIsIFwiRmVsaXBhXCIsIFwiRmVuaXhcIiwgXCJGaW5nZXIgUGFpbnRcIiwgXCJGaXJhIE1vbm9cIiwgXCJGaXJhIFNhbnNcIiwgXCJGamFsbGEgT25lXCIsIFwiRmpvcmQgT25lXCIsIFwiRmxhbWVuY29cIiwgXCJGbGF2b3JzXCIsIFwiRm9uZGFtZW50b1wiLCBcIkZvbnRkaW5lciBTd2Fua3lcIiwgXCJGb3J1bVwiLCBcIkZyYW5jb2lzIE9uZVwiLCBcIkZyZWNrbGUgRmFjZVwiLCBcIkZyZWRlcmlja2EgdGhlIEdyZWF0XCIsIFwiRnJlZG9rYSBPbmVcIiwgXCJGcmVlaGFuZFwiLCBcIkZyZXNjYVwiLCBcIkZyaWpvbGVcIiwgXCJGcnVrdHVyXCIsIFwiRnVnYXogT25lXCIsIFwiR0ZTIERpZG90XCIsIFwiR0ZTIE5lb2hlbGxlbmljXCIsIFwiR2FicmllbGFcIiwgXCJHYWZhdGFcIiwgXCJHYWxkZWFub1wiLCBcIkdhbGluZG9cIiwgXCJHZW50aXVtIEJhc2ljXCIsIFwiR2VudGl1bSBCb29rIEJhc2ljXCIsIFwiR2VvXCIsIFwiR2Vvc3RhclwiLCBcIkdlb3N0YXIgRmlsbFwiLCBcIkdlcm1hbmlhIE9uZVwiLCBcIkdpZHVndVwiLCBcIkdpbGRhIERpc3BsYXlcIiwgXCJHaXZlIFlvdSBHbG9yeVwiLCBcIkdsYXNzIEFudGlxdWFcIiwgXCJHbGVnb29cIiwgXCJHbG9yaWEgSGFsbGVsdWphaFwiLCBcIkdvYmxpbiBPbmVcIiwgXCJHb2NoaSBIYW5kXCIsIFwiR29yZGl0YXNcIiwgXCJHb3VkeSBCb29rbGV0dGVyIDE5MTFcIiwgXCJHcmFkdWF0ZVwiLCBcIkdyYW5kIEhvdGVsXCIsIFwiR3Jhdml0YXMgT25lXCIsIFwiR3JlYXQgVmliZXNcIiwgXCJHcmlmZnlcIiwgXCJHcnVwcG9cIiwgXCJHdWRlYVwiLCBcIkd1cmFqYWRhXCIsIFwiSGFiaWJpXCIsIFwiSGFsYW50XCIsIFwiSGFtbWVyc21pdGggT25lXCIsIFwiSGFuYWxlaVwiLCBcIkhhbmFsZWkgRmlsbFwiLCBcIkhhbmRsZWVcIiwgXCJIYW51bWFuXCIsIFwiSGFwcHkgTW9ua2V5XCIsIFwiSGVhZGxhbmQgT25lXCIsIFwiSGVubnkgUGVubnlcIiwgXCJIZXJyIFZvbiBNdWVsbGVyaG9mZlwiLCBcIkhpbmRcIiwgXCJIaW5kIFNpbGlndXJpXCIsIFwiSGluZCBWYWRvZGFyYVwiLCBcIkhvbHR3b29kIE9uZSBTQ1wiLCBcIkhvbWVtYWRlIEFwcGxlXCIsIFwiSG9tZW5hamVcIiwgXCJJTSBGZWxsIERXIFBpY2FcIiwgXCJJTSBGZWxsIERXIFBpY2EgU0NcIiwgXCJJTSBGZWxsIERvdWJsZSBQaWNhXCIsIFwiSU0gRmVsbCBEb3VibGUgUGljYSBTQ1wiLCBcIklNIEZlbGwgRW5nbGlzaFwiLCBcIklNIEZlbGwgRW5nbGlzaCBTQ1wiLCBcIklNIEZlbGwgRnJlbmNoIENhbm9uXCIsIFwiSU0gRmVsbCBGcmVuY2ggQ2Fub24gU0NcIiwgXCJJTSBGZWxsIEdyZWF0IFByaW1lclwiLCBcIklNIEZlbGwgR3JlYXQgUHJpbWVyIFNDXCIsIFwiSWNlYmVyZ1wiLCBcIkljZWxhbmRcIiwgXCJJbXByaW1hXCIsIFwiSW5jb25zb2xhdGFcIiwgXCJJbmRlclwiLCBcIkluZGllIEZsb3dlclwiLCBcIkluaWthXCIsIFwiSW5rbnV0IEFudGlxdWFcIiwgXCJJcmlzaCBHcm92ZXJcIiwgXCJJc3RvayBXZWJcIiwgXCJJdGFsaWFuYVwiLCBcIkl0YWxpYW5ub1wiLCBcIkl0aW1cIiwgXCJKYWNxdWVzIEZyYW5jb2lzXCIsIFwiSmFjcXVlcyBGcmFuY29pcyBTaGFkb3dcIiwgXCJKYWxkaVwiLCBcIkppbSBOaWdodHNoYWRlXCIsIFwiSm9ja2V5IE9uZVwiLCBcIkpvbGx5IExvZGdlclwiLCBcIkpvc2VmaW4gU2Fuc1wiLCBcIkpvc2VmaW4gU2xhYlwiLCBcIkpvdGkgT25lXCIsIFwiSnVkc29uXCIsIFwiSnVsZWVcIiwgXCJKdWxpdXMgU2FucyBPbmVcIiwgXCJKdW5nZVwiLCBcIkp1cmFcIiwgXCJKdXN0IEFub3RoZXIgSGFuZFwiLCBcIkp1c3QgTWUgQWdhaW4gRG93biBIZXJlXCIsIFwiS2Fkd2FcIiwgXCJLYWxhbVwiLCBcIkthbWVyb25cIiwgXCJLYW50dW1ydXlcIiwgXCJLYXJsYVwiLCBcIkthcm1hXCIsIFwiS2F1c2hhbiBTY3JpcHRcIiwgXCJLYXZvb25cIiwgXCJLZGFtIFRobW9yXCIsIFwiS2VhbmlhIE9uZVwiLCBcIktlbGx5IFNsYWJcIiwgXCJLZW5pYVwiLCBcIktoYW5kXCIsIFwiS2htZXJcIiwgXCJLaHVsYVwiLCBcIktpdGUgT25lXCIsIFwiS25ld2F2ZVwiLCBcIktvdHRhIE9uZVwiLCBcIktvdWxlblwiLCBcIktyYW5reVwiLCBcIktyZW9uXCIsIFwiS3Jpc3RpXCIsIFwiS3JvbmEgT25lXCIsIFwiS3VyYWxlXCIsIFwiTGEgQmVsbGUgQXVyb3JlXCIsIFwiTGFpbGFcIiwgXCJMYWtraSBSZWRkeVwiLCBcIkxhbmNlbG90XCIsIFwiTGF0ZWVmXCIsIFwiTGF0b1wiLCBcIkxlYWd1ZSBTY3JpcHRcIiwgXCJMZWNrZXJsaSBPbmVcIiwgXCJMZWRnZXJcIiwgXCJMZWt0b25cIiwgXCJMZW1vblwiLCBcIkxpYnJlIEJhc2tlcnZpbGxlXCIsIFwiTGlmZSBTYXZlcnNcIiwgXCJMaWxpdGEgT25lXCIsIFwiTGlseSBTY3JpcHQgT25lXCIsIFwiTGltZWxpZ2h0XCIsIFwiTGluZGVuIEhpbGxcIiwgXCJMb2JzdGVyXCIsIFwiTG9ic3RlciBUd29cIiwgXCJMb25kcmluYSBPdXRsaW5lXCIsIFwiTG9uZHJpbmEgU2hhZG93XCIsIFwiTG9uZHJpbmEgU2tldGNoXCIsIFwiTG9uZHJpbmEgU29saWRcIiwgXCJMb3JhXCIsIFwiTG92ZSBZYSBMaWtlIEEgU2lzdGVyXCIsIFwiTG92ZWQgYnkgdGhlIEtpbmdcIiwgXCJMb3ZlcnMgUXVhcnJlbFwiLCBcIkx1Y2tpZXN0IEd1eVwiLCBcIkx1c2l0YW5hXCIsIFwiTHVzdHJpYVwiLCBcIk1hY29uZG9cIiwgXCJNYWNvbmRvIFN3YXNoIENhcHNcIiwgXCJNYWdyYVwiLCBcIk1haWRlbiBPcmFuZ2VcIiwgXCJNYWtvXCIsIFwiTWFsbGFubmFcIiwgXCJNYW5kYWxpXCIsIFwiTWFyY2VsbHVzXCIsIFwiTWFyY2VsbHVzIFNDXCIsIFwiTWFyY2sgU2NyaXB0XCIsIFwiTWFyZ2FyaW5lXCIsIFwiTWFya28gT25lXCIsIFwiTWFybWVsYWRcIiwgXCJNYXJ0ZWxcIiwgXCJNYXJ0ZWwgU2Fuc1wiLCBcIk1hcnZlbFwiLCBcIk1hdGVcIiwgXCJNYXRlIFNDXCIsIFwiTWF2ZW4gUHJvXCIsIFwiTWNMYXJlblwiLCBcIk1lZGRvblwiLCBcIk1lZGlldmFsU2hhcnBcIiwgXCJNZWR1bGEgT25lXCIsIFwiTWVncmltXCIsIFwiTWVpZSBTY3JpcHRcIiwgXCJNZXJpZW5kYVwiLCBcIk1lcmllbmRhIE9uZVwiLCBcIk1lcnJpd2VhdGhlclwiLCBcIk1lcnJpd2VhdGhlciBTYW5zXCIsIFwiTWV0YWxcIiwgXCJNZXRhbCBNYW5pYVwiLCBcIk1ldGFtb3JwaG91c1wiLCBcIk1ldHJvcGhvYmljXCIsIFwiTWljaHJvbWFcIiwgXCJNaWxvbmdhXCIsIFwiTWlsdG9uaWFuXCIsIFwiTWlsdG9uaWFuIFRhdHRvb1wiLCBcIk1pbml2ZXJcIiwgXCJNaXNzIEZhamFyZG9zZVwiLCBcIk1vZGFrXCIsIFwiTW9kZXJuIEFudGlxdWFcIiwgXCJNb2xlbmdvXCIsIFwiTW9sbGVcIiwgXCJNb25kYVwiLCBcIk1vbm9mZXR0XCIsIFwiTW9ub3RvblwiLCBcIk1vbnNpZXVyIExhIERvdWxhaXNlXCIsIFwiTW9udGFnYVwiLCBcIk1vbnRlelwiLCBcIk1vbnRzZXJyYXRcIiwgXCJNb250c2VycmF0IEFsdGVybmF0ZXNcIiwgXCJNb250c2VycmF0IFN1YnJheWFkYVwiLCBcIk1vdWxcIiwgXCJNb3VscGFsaVwiLCBcIk1vdW50YWlucyBvZiBDaHJpc3RtYXNcIiwgXCJNb3VzZSBNZW1vaXJzXCIsIFwiTXIgQmVkZm9ydFwiLCBcIk1yIERhZm9lXCIsIFwiTXIgRGUgSGF2aWxhbmRcIiwgXCJNcnMgU2FpbnQgRGVsYWZpZWxkXCIsIFwiTXJzIFNoZXBwYXJkc1wiLCBcIk11bGlcIiwgXCJNeXN0ZXJ5IFF1ZXN0XCIsIFwiTlRSXCIsIFwiTmV1Y2hhXCIsIFwiTmV1dG9uXCIsIFwiTmV3IFJvY2tlclwiLCBcIk5ld3MgQ3ljbGVcIiwgXCJOaWNvbm5lXCIsIFwiTml4aWUgT25lXCIsIFwiTm9iaWxlXCIsIFwiTm9rb3JhXCIsIFwiTm9yaWNhblwiLCBcIk5vc2lmZXJcIiwgXCJOb3RoaW5nIFlvdSBDb3VsZCBEb1wiLCBcIk5vdGljaWEgVGV4dFwiLCBcIk5vdG8gU2Fuc1wiLCBcIk5vdG8gU2VyaWZcIiwgXCJOb3ZhIEN1dFwiLCBcIk5vdmEgRmxhdFwiLCBcIk5vdmEgTW9ub1wiLCBcIk5vdmEgT3ZhbFwiLCBcIk5vdmEgUm91bmRcIiwgXCJOb3ZhIFNjcmlwdFwiLCBcIk5vdmEgU2xpbVwiLCBcIk5vdmEgU3F1YXJlXCIsIFwiTnVtYW5zXCIsIFwiTnVuaXRvXCIsIFwiT2RvciBNZWFuIENoZXlcIiwgXCJPZmZzaWRlXCIsIFwiT2xkIFN0YW5kYXJkIFRUXCIsIFwiT2xkZW5idXJnXCIsIFwiT2xlbyBTY3JpcHRcIiwgXCJPbGVvIFNjcmlwdCBTd2FzaCBDYXBzXCIsIFwiT3BlbiBTYW5zXCIsIFwiT3BlbiBTYW5zIENvbmRlbnNlZFwiLCBcIk9yYW5pZW5iYXVtXCIsIFwiT3JiaXRyb25cIiwgXCJPcmVnYW5vXCIsIFwiT3JpZW50YVwiLCBcIk9yaWdpbmFsIFN1cmZlclwiLCBcIk9zd2FsZFwiLCBcIk92ZXIgdGhlIFJhaW5ib3dcIiwgXCJPdmVybG9ja1wiLCBcIk92ZXJsb2NrIFNDXCIsIFwiT3ZvXCIsIFwiT3h5Z2VuXCIsIFwiT3h5Z2VuIE1vbm9cIiwgXCJQVCBNb25vXCIsIFwiUFQgU2Fuc1wiLCBcIlBUIFNhbnMgQ2FwdGlvblwiLCBcIlBUIFNhbnMgTmFycm93XCIsIFwiUFQgU2VyaWZcIiwgXCJQVCBTZXJpZiBDYXB0aW9uXCIsIFwiUGFjaWZpY29cIiwgXCJQYWxhbnF1aW5cIiwgXCJQYWxhbnF1aW4gRGFya1wiLCBcIlBhcHJpa2FcIiwgXCJQYXJpc2llbm5lXCIsIFwiUGFzc2VybyBPbmVcIiwgXCJQYXNzaW9uIE9uZVwiLCBcIlBhdGh3YXkgR290aGljIE9uZVwiLCBcIlBhdHJpY2sgSGFuZFwiLCBcIlBhdHJpY2sgSGFuZCBTQ1wiLCBcIlBhdHVhIE9uZVwiLCBcIlBheXRvbmUgT25lXCIsIFwiUGVkZGFuYVwiLCBcIlBlcmFsdGFcIiwgXCJQZXJtYW5lbnQgTWFya2VyXCIsIFwiUGV0aXQgRm9ybWFsIFNjcmlwdFwiLCBcIlBldHJvbmFcIiwgXCJQaGlsb3NvcGhlclwiLCBcIlBpZWRyYVwiLCBcIlBpbnlvbiBTY3JpcHRcIiwgXCJQaXJhdGEgT25lXCIsIFwiUGxhc3RlclwiLCBcIlBsYXlcIiwgXCJQbGF5YmFsbFwiLCBcIlBsYXlmYWlyIERpc3BsYXlcIiwgXCJQbGF5ZmFpciBEaXNwbGF5IFNDXCIsIFwiUG9ka292YVwiLCBcIlBvaXJldCBPbmVcIiwgXCJQb2xsZXIgT25lXCIsIFwiUG9seVwiLCBcIlBvbXBpZXJlXCIsIFwiUG9udGFubyBTYW5zXCIsIFwiUG9wcGluc1wiLCBcIlBvcnQgTGxpZ2F0IFNhbnNcIiwgXCJQb3J0IExsaWdhdCBTbGFiXCIsIFwiUHJhZ2F0aSBOYXJyb3dcIiwgXCJQcmF0YVwiLCBcIlByZWFodmloZWFyXCIsIFwiUHJlc3MgU3RhcnQgMlBcIiwgXCJQcmluY2VzcyBTb2ZpYVwiLCBcIlByb2Npb25vXCIsIFwiUHJvc3RvIE9uZVwiLCBcIlB1cml0YW5cIiwgXCJQdXJwbGUgUHVyc2VcIiwgXCJRdWFuZG9cIiwgXCJRdWFudGljb1wiLCBcIlF1YXR0cm9jZW50b1wiLCBcIlF1YXR0cm9jZW50byBTYW5zXCIsIFwiUXVlc3RyaWFsXCIsIFwiUXVpY2tzYW5kXCIsIFwiUXVpbnRlc3NlbnRpYWxcIiwgXCJRd2lnbGV5XCIsIFwiUmFjaW5nIFNhbnMgT25lXCIsIFwiUmFkbGV5XCIsIFwiUmFqZGhhbmlcIiwgXCJSYWxld2F5XCIsIFwiUmFsZXdheSBEb3RzXCIsIFwiUmFtYWJoYWRyYVwiLCBcIlJhbWFyYWphXCIsIFwiUmFtYmxhXCIsIFwiUmFtbWV0dG8gT25lXCIsIFwiUmFuY2hlcnNcIiwgXCJSYW5jaG9cIiwgXCJSYW5nYVwiLCBcIlJhdGlvbmFsZVwiLCBcIlJhdmkgUHJha2FzaFwiLCBcIlJlZHJlc3NlZFwiLCBcIlJlZW5pZSBCZWFuaWVcIiwgXCJSZXZhbGlhXCIsIFwiUmhvZGl1bSBMaWJyZVwiLCBcIlJpYmV5ZVwiLCBcIlJpYmV5ZSBNYXJyb3dcIiwgXCJSaWdodGVvdXNcIiwgXCJSaXNxdWVcIiwgXCJSb2JvdG9cIiwgXCJSb2JvdG8gQ29uZGVuc2VkXCIsIFwiUm9ib3RvIE1vbm9cIiwgXCJSb2JvdG8gU2xhYlwiLCBcIlJvY2hlc3RlclwiLCBcIlJvY2sgU2FsdFwiLCBcIlJva2tpdHRcIiwgXCJSb21hbmVzY29cIiwgXCJSb3BhIFNhbnNcIiwgXCJSb3NhcmlvXCIsIFwiUm9zYXJpdm9cIiwgXCJSb3VnZSBTY3JpcHRcIiwgXCJSb3poYSBPbmVcIiwgXCJSdWJpa1wiLCBcIlJ1YmlrIE1vbm8gT25lXCIsIFwiUnViaWsgT25lXCIsIFwiUnVkYVwiLCBcIlJ1ZmluYVwiLCBcIlJ1Z2UgQm9vZ2llXCIsIFwiUnVsdWtvXCIsIFwiUnVtIFJhaXNpblwiLCBcIlJ1c2xhbiBEaXNwbGF5XCIsIFwiUnVzc28gT25lXCIsIFwiUnV0aGllXCIsIFwiUnllXCIsIFwiU2FjcmFtZW50b1wiLCBcIlNhaGl0eWFcIiwgXCJTYWlsXCIsIFwiU2Fsc2FcIiwgXCJTYW5jaGV6XCIsIFwiU2FuY3JlZWtcIiwgXCJTYW5zaXRhIE9uZVwiLCBcIlNhcmFsYVwiLCBcIlNhcmluYVwiLCBcIlNhcnBhbmNoXCIsIFwiU2F0aXNmeVwiLCBcIlNjYWRhXCIsIFwiU2NoZWhlcmF6YWRlXCIsIFwiU2Nob29sYmVsbFwiLCBcIlNlYXdlZWQgU2NyaXB0XCIsIFwiU2V2aWxsYW5hXCIsIFwiU2V5bW91ciBPbmVcIiwgXCJTaGFkb3dzIEludG8gTGlnaHRcIiwgXCJTaGFkb3dzIEludG8gTGlnaHQgVHdvXCIsIFwiU2hhbnRpXCIsIFwiU2hhcmVcIiwgXCJTaGFyZSBUZWNoXCIsIFwiU2hhcmUgVGVjaCBNb25vXCIsIFwiU2hvanVtYXJ1XCIsIFwiU2hvcnQgU3RhY2tcIiwgXCJTaWVtcmVhcFwiLCBcIlNpZ21hciBPbmVcIiwgXCJTaWduaWthXCIsIFwiU2lnbmlrYSBOZWdhdGl2ZVwiLCBcIlNpbW9uZXR0YVwiLCBcIlNpbnRvbnlcIiwgXCJTaXJpbiBTdGVuY2lsXCIsIFwiU2l4IENhcHNcIiwgXCJTa3JhbmppXCIsIFwiU2xhYm8gMTNweFwiLCBcIlNsYWJvIDI3cHhcIiwgXCJTbGFja2V5XCIsIFwiU21va3VtXCIsIFwiU215dGhlXCIsIFwiU25pZ2xldFwiLCBcIlNuaXBwZXRcIiwgXCJTbm93YnVyc3QgT25lXCIsIFwiU29mYWRpIE9uZVwiLCBcIlNvZmlhXCIsIFwiU29uc2llIE9uZVwiLCBcIlNvcnRzIE1pbGwgR291ZHlcIiwgXCJTb3VyY2UgQ29kZSBQcm9cIiwgXCJTb3VyY2UgU2FucyBQcm9cIiwgXCJTb3VyY2UgU2VyaWYgUHJvXCIsIFwiU3BlY2lhbCBFbGl0ZVwiLCBcIlNwaWN5IFJpY2VcIiwgXCJTcGlubmFrZXJcIiwgXCJTcGlyYXhcIiwgXCJTcXVhZGEgT25lXCIsIFwiU3JlZSBLcnVzaG5hZGV2YXJheWFcIiwgXCJTdGFsZW1hdGVcIiwgXCJTdGFsaW5pc3QgT25lXCIsIFwiU3RhcmRvcyBTdGVuY2lsXCIsIFwiU3RpbnQgVWx0cmEgQ29uZGVuc2VkXCIsIFwiU3RpbnQgVWx0cmEgRXhwYW5kZWRcIiwgXCJTdG9rZVwiLCBcIlN0cmFpdFwiLCBcIlN1ZSBFbGxlbiBGcmFuY2lzY29cIiwgXCJTdW1hbmFcIiwgXCJTdW5zaGluZXlcIiwgXCJTdXBlcm1lcmNhZG8gT25lXCIsIFwiU3VyYVwiLCBcIlN1cmFubmFcIiwgXCJTdXJhdmFyYW1cIiwgXCJTdXdhbm5hcGh1bVwiLCBcIlN3YW5reSBhbmQgTW9vIE1vb1wiLCBcIlN5bmNvcGF0ZVwiLCBcIlRhbmdlcmluZVwiLCBcIlRhcHJvbVwiLCBcIlRhdXJpXCIsIFwiVGVrb1wiLCBcIlRlbGV4XCIsIFwiVGVuYWxpIFJhbWFrcmlzaG5hXCIsIFwiVGVub3IgU2Fuc1wiLCBcIlRleHQgTWUgT25lXCIsIFwiVGhlIEdpcmwgTmV4dCBEb29yXCIsIFwiVGllbm5lXCIsIFwiVGlsbGFuYVwiLCBcIlRpbW1hbmFcIiwgXCJUaW5vc1wiLCBcIlRpdGFuIE9uZVwiLCBcIlRpdGlsbGl1bSBXZWJcIiwgXCJUcmFkZSBXaW5kc1wiLCBcIlRyb2NjaGlcIiwgXCJUcm9jaHV0XCIsIFwiVHJ5a2tlclwiLCBcIlR1bHBlbiBPbmVcIiwgXCJVYnVudHVcIiwgXCJVYnVudHUgQ29uZGVuc2VkXCIsIFwiVWJ1bnR1IE1vbm9cIiwgXCJVbHRyYVwiLCBcIlVuY2lhbCBBbnRpcXVhXCIsIFwiVW5kZXJkb2dcIiwgXCJVbmljYSBPbmVcIiwgXCJVbmlmcmFrdHVyQ29va1wiLCBcIlVuaWZyYWt0dXJNYWd1bnRpYVwiLCBcIlVua2VtcHRcIiwgXCJVbmxvY2tcIiwgXCJVbm5hXCIsIFwiVlQzMjNcIiwgXCJWYW1waXJvIE9uZVwiLCBcIlZhcmVsYVwiLCBcIlZhcmVsYSBSb3VuZFwiLCBcIlZhc3QgU2hhZG93XCIsIFwiVmVzcGVyIExpYnJlXCIsIFwiVmlidXJcIiwgXCJWaWRhbG9rYVwiLCBcIlZpZ2FcIiwgXCJWb2Nlc1wiLCBcIlZvbGtob3ZcIiwgXCJWb2xsa29yblwiLCBcIlZvbHRhaXJlXCIsIFwiV2FpdGluZyBmb3IgdGhlIFN1bnJpc2VcIiwgXCJXYWxscG9ldFwiLCBcIldhbHRlciBUdXJuY29hdFwiLCBcIldhcm5lc1wiLCBcIldlbGxmbGVldFwiLCBcIldlbmR5IE9uZVwiLCBcIldpcmUgT25lXCIsIFwiV29yayBTYW5zXCIsIFwiWWFub25lIEthZmZlZXNhdHpcIiwgXCJZYW50cmFtYW5hdlwiLCBcIlllbGxvd3RhaWxcIiwgXCJZZXNldmEgT25lXCIsIFwiWWVzdGVyeWVhclwiLCBcIlpleWFkYVwiXTtcbn0pLmNhbGwodGhpcyk7Il0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4239\n')},5417:function(module,__unused_webpack_exports,__webpack_require__){eval("var isObject = __webpack_require__(111);\nvar isArray = __webpack_require__(3157);\nvar wellKnownSymbol = __webpack_require__(5112);\n\nvar SPECIES = wellKnownSymbol('species');\n\n// `ArraySpeciesCreate` abstract operation\n// https://tc39.es/ecma262/#sec-arrayspeciescreate\nmodule.exports = function (originalArray, length) {\n var C;\n if (isArray(originalArray)) {\n C = originalArray.constructor;\n // cross-realm fallback\n if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;\n else if (isObject(C)) {\n C = C[SPECIES];\n if (C === null) C = undefined;\n }\n } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcz82NWYwIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGVBQWUsbUJBQU8sQ0FBQyxHQUF3QjtBQUMvQyxjQUFjLG1CQUFPLENBQUMsSUFBdUI7QUFDN0Msc0JBQXNCLG1CQUFPLENBQUMsSUFBZ0M7O0FBRTlEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCIsImZpbGUiOiI1NDE3LmpzIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2lzLW9iamVjdCcpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvaXMtYXJyYXknKTtcbnZhciB3ZWxsS25vd25TeW1ib2wgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvd2VsbC1rbm93bi1zeW1ib2wnKTtcblxudmFyIFNQRUNJRVMgPSB3ZWxsS25vd25TeW1ib2woJ3NwZWNpZXMnKTtcblxuLy8gYEFycmF5U3BlY2llc0NyZWF0ZWAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWFycmF5c3BlY2llc2NyZWF0ZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWxBcnJheSwgbGVuZ3RoKSB7XG4gIHZhciBDO1xuICBpZiAoaXNBcnJheShvcmlnaW5hbEFycmF5KSkge1xuICAgIEMgPSBvcmlnaW5hbEFycmF5LmNvbnN0cnVjdG9yO1xuICAgIC8vIGNyb3NzLXJlYWxtIGZhbGxiYWNrXG4gICAgaWYgKHR5cGVvZiBDID09ICdmdW5jdGlvbicgJiYgKEMgPT09IEFycmF5IHx8IGlzQXJyYXkoQy5wcm90b3R5cGUpKSkgQyA9IHVuZGVmaW5lZDtcbiAgICBlbHNlIGlmIChpc09iamVjdChDKSkge1xuICAgICAgQyA9IENbU1BFQ0lFU107XG4gICAgICBpZiAoQyA9PT0gbnVsbCkgQyA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gcmV0dXJuIG5ldyAoQyA9PT0gdW5kZWZpbmVkID8gQXJyYXkgOiBDKShsZW5ndGggPT09IDAgPyAwIDogbGVuZ3RoKTtcbn07XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5417\n")},6790:function(module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\nvar isArray = __webpack_require__(3157);\nvar toLength = __webpack_require__(7466);\nvar bind = __webpack_require__(9974);\n\n// `FlattenIntoArray` abstract operation\n// https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray\nvar flattenIntoArray = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {\n var targetIndex = start;\n var sourceIndex = 0;\n var mapFn = mapper ? bind(mapper, thisArg, 3) : false;\n var element;\n\n while (sourceIndex < sourceLen) {\n if (sourceIndex in source) {\n element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];\n\n if (depth > 0 && isArray(element)) {\n targetIndex = flattenIntoArray(target, original, element, toLength(element.length), targetIndex, depth - 1) - 1;\n } else {\n if (targetIndex >= 0x1FFFFFFFFFFFFF) throw TypeError('Exceed the acceptable array length');\n target[targetIndex] = element;\n }\n\n targetIndex++;\n }\n sourceIndex++;\n }\n return targetIndex;\n};\n\nmodule.exports = flattenIntoArray;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mbGF0dGVuLWludG8tYXJyYXkuanM/YTJiZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBYTtBQUNiLGNBQWMsbUJBQU8sQ0FBQyxJQUF1QjtBQUM3QyxlQUFlLG1CQUFPLENBQUMsSUFBd0I7QUFDL0MsV0FBVyxtQkFBTyxDQUFDLElBQW9DOztBQUV2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBIiwiZmlsZSI6IjY3OTAuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9pcy1hcnJheScpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL3RvLWxlbmd0aCcpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZnVuY3Rpb24tYmluZC1jb250ZXh0Jyk7XG5cbi8vIGBGbGF0dGVuSW50b0FycmF5YCBhYnN0cmFjdCBvcGVyYXRpb25cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vcHJvcG9zYWwtZmxhdE1hcC8jc2VjLUZsYXR0ZW5JbnRvQXJyYXlcbnZhciBmbGF0dGVuSW50b0FycmF5ID0gZnVuY3Rpb24gKHRhcmdldCwgb3JpZ2luYWwsIHNvdXJjZSwgc291cmNlTGVuLCBzdGFydCwgZGVwdGgsIG1hcHBlciwgdGhpc0FyZykge1xuICB2YXIgdGFyZ2V0SW5kZXggPSBzdGFydDtcbiAgdmFyIHNvdXJjZUluZGV4ID0gMDtcbiAgdmFyIG1hcEZuID0gbWFwcGVyID8gYmluZChtYXBwZXIsIHRoaXNBcmcsIDMpIDogZmFsc2U7XG4gIHZhciBlbGVtZW50O1xuXG4gIHdoaWxlIChzb3VyY2VJbmRleCA8IHNvdXJjZUxlbikge1xuICAgIGlmIChzb3VyY2VJbmRleCBpbiBzb3VyY2UpIHtcbiAgICAgIGVsZW1lbnQgPSBtYXBGbiA/IG1hcEZuKHNvdXJjZVtzb3VyY2VJbmRleF0sIHNvdXJjZUluZGV4LCBvcmlnaW5hbCkgOiBzb3VyY2Vbc291cmNlSW5kZXhdO1xuXG4gICAgICBpZiAoZGVwdGggPiAwICYmIGlzQXJyYXkoZWxlbWVudCkpIHtcbiAgICAgICAgdGFyZ2V0SW5kZXggPSBmbGF0dGVuSW50b0FycmF5KHRhcmdldCwgb3JpZ2luYWwsIGVsZW1lbnQsIHRvTGVuZ3RoKGVsZW1lbnQubGVuZ3RoKSwgdGFyZ2V0SW5kZXgsIGRlcHRoIC0gMSkgLSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRhcmdldEluZGV4ID49IDB4MUZGRkZGRkZGRkZGRkYpIHRocm93IFR5cGVFcnJvcignRXhjZWVkIHRoZSBhY2NlcHRhYmxlIGFycmF5IGxlbmd0aCcpO1xuICAgICAgICB0YXJnZXRbdGFyZ2V0SW5kZXhdID0gZWxlbWVudDtcbiAgICAgIH1cblxuICAgICAgdGFyZ2V0SW5kZXgrKztcbiAgICB9XG4gICAgc291cmNlSW5kZXgrKztcbiAgfVxuICByZXR1cm4gdGFyZ2V0SW5kZXg7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZsYXR0ZW5JbnRvQXJyYXk7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///6790\n")},9974:function(module,__unused_webpack_exports,__webpack_require__){eval("var aFunction = __webpack_require__(3099);\n\n// optional / simple context binding\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 0: return function () {\n return fn.call(that);\n };\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9mdW5jdGlvbi1iaW5kLWNvbnRleHQuanM/MDM2NiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxnQkFBZ0IsbUJBQU8sQ0FBQyxJQUF5Qjs7QUFFakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiOTk3NC5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvYS1mdW5jdGlvbicpO1xuXG4vLyBvcHRpb25hbCAvIHNpbXBsZSBjb250ZXh0IGJpbmRpbmdcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCB0aGF0LCBsZW5ndGgpIHtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYgKHRoYXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZuO1xuICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQpO1xuICAgIH07XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24gKGEpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xuICAgIH07XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIpO1xuICAgIH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24gKGEsIGIsIGMpIHtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEsIGIsIGMpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uICgvKiAuLi5hcmdzICovKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3VtZW50cyk7XG4gIH07XG59O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///9974\n")},3157:function(module,__unused_webpack_exports,__webpack_require__){eval("var classof = __webpack_require__(4326);\n\n// `IsArray` abstract operation\n// https://tc39.es/ecma262/#sec-isarray\n// eslint-disable-next-line es/no-array-isarray -- safe\nmodule.exports = Array.isArray || function isArray(arg) {\n return classof(arg) == 'Array';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ludGVybmFscy9pcy1hcnJheS5qcz9lOGI1Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsbUJBQU8sQ0FBQyxJQUEwQjs7QUFFaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjMxNTcuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9jbGFzc29mLXJhdycpO1xuXG4vLyBgSXNBcnJheWAgYWJzdHJhY3Qgb3BlcmF0aW9uXG4vLyBodHRwczovL3RjMzkuZXMvZWNtYTI2Mi8jc2VjLWlzYXJyYXlcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcy9uby1hcnJheS1pc2FycmF5IC0tIHNhZmVcbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICByZXR1cm4gY2xhc3NvZihhcmcpID09ICdBcnJheSc7XG59O1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///3157\n")},4944:function(__unused_webpack_module,__unused_webpack_exports,__webpack_require__){"use strict";eval("\nvar $ = __webpack_require__(2109);\nvar flattenIntoArray = __webpack_require__(6790);\nvar toObject = __webpack_require__(7908);\nvar toLength = __webpack_require__(7466);\nvar toInteger = __webpack_require__(9958);\nvar arraySpeciesCreate = __webpack_require__(5417);\n\n// `Array.prototype.flat` method\n// https://tc39.es/ecma262/#sec-array.prototype.flat\n$({ target: 'Array', proto: true }, {\n flat: function flat(/* depthArg = 1 */) {\n var depthArg = arguments.length ? arguments[0] : undefined;\n var O = toObject(this);\n var sourceLen = toLength(O.length);\n var A = arraySpeciesCreate(O, 0);\n A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toInteger(depthArg));\n return A;\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuZmxhdC5qcz8wNDgxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFhO0FBQ2IsUUFBUSxtQkFBTyxDQUFDLElBQXFCO0FBQ3JDLHVCQUF1QixtQkFBTyxDQUFDLElBQWlDO0FBQ2hFLGVBQWUsbUJBQU8sQ0FBQyxJQUF3QjtBQUMvQyxlQUFlLG1CQUFPLENBQUMsSUFBd0I7QUFDL0MsZ0JBQWdCLG1CQUFPLENBQUMsSUFBeUI7QUFDakQseUJBQXlCLG1CQUFPLENBQUMsSUFBbUM7O0FBRXBFO0FBQ0E7QUFDQSxHQUFHLCtCQUErQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQyIsImZpbGUiOiI0OTQ0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvZXhwb3J0Jyk7XG52YXIgZmxhdHRlbkludG9BcnJheSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9mbGF0dGVuLWludG8tYXJyYXknKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFscy90by1sZW5ndGgnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbHMvdG8taW50ZWdlcicpO1xudmFyIGFycmF5U3BlY2llc0NyZWF0ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFscy9hcnJheS1zcGVjaWVzLWNyZWF0ZScpO1xuXG4vLyBgQXJyYXkucHJvdG90eXBlLmZsYXRgIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1hcnJheS5wcm90b3R5cGUuZmxhdFxuJCh7IHRhcmdldDogJ0FycmF5JywgcHJvdG86IHRydWUgfSwge1xuICBmbGF0OiBmdW5jdGlvbiBmbGF0KC8qIGRlcHRoQXJnID0gMSAqLykge1xuICAgIHZhciBkZXB0aEFyZyA9IGFyZ3VtZW50cy5sZW5ndGggPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIE8gPSB0b09iamVjdCh0aGlzKTtcbiAgICB2YXIgc291cmNlTGVuID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBBID0gYXJyYXlTcGVjaWVzQ3JlYXRlKE8sIDApO1xuICAgIEEubGVuZ3RoID0gZmxhdHRlbkludG9BcnJheShBLCBPLCBPLCBzb3VyY2VMZW4sIDAsIGRlcHRoQXJnID09PSB1bmRlZmluZWQgPyAxIDogdG9JbnRlZ2VyKGRlcHRoQXJnKSk7XG4gICAgcmV0dXJuIEE7XG4gIH1cbn0pO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///4944\n")},5438:function(__unused_webpack_module,__unused_webpack_exports,__webpack_require__){eval("var $ = __webpack_require__(2109);\n\n// eslint-disable-next-line es/no-math-hypot -- required for testing\nvar $hypot = Math.hypot;\nvar abs = Math.abs;\nvar sqrt = Math.sqrt;\n\n// Chrome 77 bug\n// https://bugs.chromium.org/p/v8/issues/detail?id=9546\nvar BUGGY = !!$hypot && $hypot(Infinity, NaN) !== Infinity;\n\n// `Math.hypot` method\n// https://tc39.es/ecma262/#sec-math.hypot\n$({ target: 'Math', stat: true, forced: BUGGY }, {\n // eslint-disable-next-line no-unused-vars -- required for `.length`\n hypot: function hypot(value1, value2) {\n var sum = 0;\n var i = 0;\n var aLen = arguments.length;\n var larg = 0;\n var arg, div;\n while (i < aLen) {\n arg = abs(arguments[i++]);\n if (larg < arg) {\n div = larg / arg;\n sum = sum * div * div + 1;\n larg = arg;\n } else if (arg > 0) {\n div = arg / larg;\n sum += div * div;\n } else sum += arg;\n }\n return larg === Infinity ? Infinity : larg * sqrt(sum);\n }\n});\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXMubWF0aC5oeXBvdC5qcz80MDU3Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFFBQVEsbUJBQU8sQ0FBQyxJQUFxQjs7QUFFckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHLDRDQUE0QztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBLENBQUMiLCJmaWxlIjoiNTQzOC5qcyIsInNvdXJjZXNDb250ZW50IjpbInZhciAkID0gcmVxdWlyZSgnLi4vaW50ZXJuYWxzL2V4cG9ydCcpO1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXMvbm8tbWF0aC1oeXBvdCAtLSByZXF1aXJlZCBmb3IgdGVzdGluZ1xudmFyICRoeXBvdCA9IE1hdGguaHlwb3Q7XG52YXIgYWJzID0gTWF0aC5hYnM7XG52YXIgc3FydCA9IE1hdGguc3FydDtcblxuLy8gQ2hyb21lIDc3IGJ1Z1xuLy8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9OTU0NlxudmFyIEJVR0dZID0gISEkaHlwb3QgJiYgJGh5cG90KEluZmluaXR5LCBOYU4pICE9PSBJbmZpbml0eTtcblxuLy8gYE1hdGguaHlwb3RgIG1ldGhvZFxuLy8gaHR0cHM6Ly90YzM5LmVzL2VjbWEyNjIvI3NlYy1tYXRoLmh5cG90XG4kKHsgdGFyZ2V0OiAnTWF0aCcsIHN0YXQ6IHRydWUsIGZvcmNlZDogQlVHR1kgfSwge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMgLS0gcmVxdWlyZWQgZm9yIGAubGVuZ3RoYFxuICBoeXBvdDogZnVuY3Rpb24gaHlwb3QodmFsdWUxLCB2YWx1ZTIpIHtcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIHNxcnQoc3VtKTtcbiAgfVxufSk7XG4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5438\n")},7998:function(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n "default": function() { return /* binding */ cejst; }\n});\n\n// NAMESPACE OBJECT: ./src/components/legend.module.scss\nvar legend_module_namespaceObject = {};\n__webpack_require__.r(legend_module_namespaceObject);\n__webpack_require__.d(legend_module_namespaceObject, {\n "Ww": function() { return colorSwatch; },\n "nm": function() { return legendContainer; },\n "oI": function() { return legendItem; },\n "KW": function() { return nonPrioritized; },\n "ah": function() { return prioritized; },\n "VV": function() { return swatchContainer; },\n "Lj": function() { return threshold; }\n});\n\n// EXTERNAL MODULE: ./node_modules/react/index.js\nvar react = __webpack_require__(7294);\n// EXTERNAL MODULE: ./src/components/layout.tsx + 7 modules\nvar layout = __webpack_require__(1857);\n// EXTERNAL MODULE: ./src/contexts/FlagContext.tsx\nvar FlagContext = __webpack_require__(774);\n// EXTERNAL MODULE: ./node_modules/mapbox-gl/dist/mapbox-gl.js\nvar mapbox_gl = __webpack_require__(2974);\n// EXTERNAL MODULE: ./node_modules/chroma-js/chroma.js\nvar chroma = __webpack_require__(3873);\nvar chroma_default = /*#__PURE__*/__webpack_require__.n(chroma);\n;// CONCATENATED MODULE: ./src/data/constants.tsx\n// Properties\nvar SCORE_PROPERTY=\'Score D (percentile)\';var GEOID_PROPERTY=\'GEOID10\';// Zoom\nvar GLOBAL_MIN_ZOOM=3;var GLOBAL_MAX_ZOOM=22;var GLOBAL_MIN_ZOOM_LOW=3;var GLOBAL_MAX_ZOOM_LOW=9;var GLOBAL_MIN_ZOOM_HIGH=9;var GLOBAL_MAX_ZOOM_HIGH=12;// Bounds\nvar GLOBAL_MAX_BOUNDS=[[-167.276413,5.499550],[-52.233040,83.162102]];var DEFAULT_CENTER=[32.4687126,-86.502136];// Opacity\nvar DEFAULT_LAYER_OPACITY=0.6;// Colors\nvar DEFAULT_OUTLINE_COLOR=\'#4EA5CF\';var MIN_COLOR=\'#FFFFFF\';var MED_COLOR=\'#D1DAE6\';var MAX_COLOR=\'#768FB3\';\n;// CONCATENATED MODULE: ./src/data/mapStyle.tsx\n// eslint-disable-next-line require-jsdoc\nfunction hexToHSLA(hex,alpha){return chroma_default()(hex).alpha(alpha).css(\'hsl\');}/**\n * `MakePaint` generates a zoom-faded Mapbox style formatted layer given a set of parameters.\n *\n * @param {string} field : the field within the data to consult\n * @param {number} minRamp : the minimum value this can assume\n * @param {number} medRamp : the medium value this can assume\n * @param {number} maxRamp : the maximum value this can assume\n * @param {boolean} high : whether this is a "high" or "low" layer\n * @return {FillPaint} a mapboxgl fill layer\n **/function makePaint(_ref){var field=_ref.field,minRamp=_ref.minRamp,medRamp=_ref.medRamp,maxRamp=_ref.maxRamp,_ref$high=_ref.high,high=_ref$high===void 0?true:_ref$high;var paintDescriptor={\'fill-color\':[\'step\',[\'get\',field],hexToHSLA(MIN_COLOR,DEFAULT_LAYER_OPACITY),minRamp,hexToHSLA(MIN_COLOR,DEFAULT_LAYER_OPACITY),medRamp,hexToHSLA(MED_COLOR,DEFAULT_LAYER_OPACITY),maxRamp,hexToHSLA(MAX_COLOR,DEFAULT_LAYER_OPACITY)]};return paintDescriptor;}var mapStyle={\'version\':8,\'sources\':{\'carto\':{\'type\':\'raster\',\'tiles\':[\'https://a.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png\',\'https://b.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png\',\'https://c.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png\',\'https://d.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png\']},\'geo\':{\'type\':\'raster\',\'tiles\':[\'https://mt0.google.com/vt/lyrs=p&hl=en&x={x}&y={y}&z={z}\']},\'score\':{\'type\':\'vector\',\'tiles\':[\'https://d2zjid6n5ja2pt.cloudfront.net/0629_demo/{z}/{x}/{y}.pbf\'// For local development, use:\n// \'http://localhost:8080/data/tl_2010_bg_with_data/{z}/{x}/{y}.pbf\',\n]},\'labels\':{\'type\':\'raster\',\'tiles\':[\'https://cartodb-basemaps-a.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}@2x.png\',\'https://cartodb-basemaps-b.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}@2x.png\',\'https://cartodb-basemaps-c.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}@2x.png\',\'https://cartodb-basemaps-d.global.ssl.fastly.net/light_only_labels/{z}/{x}/{y}@2x.png\']}},\'layers\':[{\'id\':\'carto\',\'source\':\'carto\',\'type\':\'raster\',\'minzoom\':GLOBAL_MIN_ZOOM-1,\'maxzoom\':GLOBAL_MAX_ZOOM+1},{\'id\':\'geo\',\'source\':\'geo\',\'type\':\'raster\',\'minzoom\':GLOBAL_MIN_ZOOM-1,\'maxzoom\':GLOBAL_MAX_ZOOM+1,\'layout\':{// Make the layer visible by default.\n\'visibility\':\'none\'}},{\'id\':\'score\',\'source\':\'score\',\'source-layer\':\'blocks\',\'type\':\'fill\',\'filter\':[\'all\',[\'>\',SCORE_PROPERTY,0.6]// [\'in\', \'STATEFP10\', \'01\', \'30\', \'34\', \'35\', \'36\'],\n],\'paint\':makePaint({field:SCORE_PROPERTY,minRamp:0,medRamp:0.6,maxRamp:0.75,high:true}),\'minzoom\':GLOBAL_MIN_ZOOM,\'maxzoom\':GLOBAL_MAX_ZOOM},{\'id\':\'score-highlights\',\'source\':\'score\',\'source-layer\':\'blocks\',\'type\':\'line\',\'minzoom\':GLOBAL_MIN_ZOOM_HIGH,\'maxzoom\':GLOBAL_MAX_ZOOM_HIGH,\'layout\':{\'visibility\':\'visible\',\'line-join\':\'round\',\'line-cap\':\'round\'},\'paint\':{\'line-color\':DEFAULT_OUTLINE_COLOR,\'line-width\':0.8,\'line-opacity\':0.5}},{\'id\':\'labels-only\',\'type\':\'raster\',\'source\':\'labels\',\'minzoom\':GLOBAL_MIN_ZOOM,\'maxzoom\':GLOBAL_MAX_ZOOM}]};/* harmony default export */ var data_mapStyle = (mapStyle);\n;// CONCATENATED MODULE: ./src/components/zoomWarning.module.scss\n// extracted by mini-css-extract-plugin\nvar zoomWarning = "zoomWarning-module--zoomWarning--jGeOk";\n;// CONCATENATED MODULE: ./node_modules/uswds/dist/img/usa-icons/zoom_in.svg\n/* harmony default export */ var zoom_in = ("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNMTUuNSAxNGgtLjc5bC0uMjgtLjI3QzE1LjQxIDEyLjU5IDE2IDExLjExIDE2IDkuNSAxNiA1LjkxIDEzLjA5IDMgOS41IDNTMyA1LjkxIDMgOS41IDUuOTEgMTYgOS41IDE2YzEuNjEgMCAzLjA5LS41OSA0LjIzLTEuNTdsLjI3LjI4di43OWw1IDQuOTlMMjAuNDkgMTlsLTQuOTktNXptLTYgMEM3LjAxIDE0IDUgMTEuOTkgNSA5LjVTNy4wMSA1IDkuNSA1IDE0IDcuMDEgMTQgOS41IDExLjk5IDE0IDkuNSAxNHoiLz48cGF0aCBkPSJNMTIgMTBoLTJ2Mkg5di0ySDdWOWgyVjdoMXYyaDJ2MXoiLz48L3N2Zz4=");\n;// CONCATENATED MODULE: ./src/components/zoomWarning.tsx\n// @ts-ignore\nvar ZoomWarning=function ZoomWarning(_ref){var zoomLevel=_ref.zoomLevel;return/*#__PURE__*/react.createElement(react.Fragment,null,zoomLevel<=5?/*#__PURE__*/react.createElement("div",{className:zoomWarning},/*#__PURE__*/react.createElement("img",{src:zoom_in,alt:\'zoom icon\'}),"Zoom in to the state or regional level to see prioritized communities on the map."):\'\');};/* harmony default export */ var components_zoomWarning = (ZoomWarning);\n;// CONCATENATED MODULE: ./src/components/popupContent.module.scss\n// extracted by mini-css-extract-plugin\nvar popupContentTable = "popupContent-module--popupContentTable--1y4c9";\nvar titleContainer = "popupContent-module--titleContainer--17Oy9";\nvar titleIndicatorName = "popupContent-module--titleIndicatorName--3yoDh";\n;// CONCATENATED MODULE: ./src/components/popupContent.tsx\nfunction _createForOfIteratorHelperLoose(o,allowArrayLike){var it=typeof Symbol!=="undefined"&&o[Symbol.iterator]||o["@@iterator"];if(it)return(it=it.call(o)).next.bind(it);if(Array.isArray(o)||(it=_unsupportedIterableToArray(o))||allowArrayLike&&o&&typeof o.length==="number"){if(it)o=it;var i=0;return function(){if(i>=o.length)return{done:true};return{done:false,value:o[i++]};};}throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _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);}function _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;}var PopupContent=function PopupContent(_ref){var properties=_ref.properties;var readablePercent=function readablePercent(percent){return""+(percent*100).toFixed(2);};var getCategorization=function getCategorization(percentile){var categorization;if(percentile>=0.75){categorization=\'Prioritized\';}else if(0.60<=percentile&&percentile<0.75){categorization=\'Threshold\';}else{categorization=\'Non-prioritized\';}return categorization;};var getTitleContent=function getTitleContent(properties){var blockGroup=properties[GEOID_PROPERTY];var score=properties[SCORE_PROPERTY];return/*#__PURE__*/react.createElement("div",{className:titleContainer},/*#__PURE__*/react.createElement("div",null,/*#__PURE__*/react.createElement("span",{className:titleIndicatorName},"Census Block Group: "),/*#__PURE__*/react.createElement("span",null,blockGroup)),/*#__PURE__*/react.createElement("div",null,/*#__PURE__*/react.createElement("span",{className:titleIndicatorName},"Just Progress Categorization: "),/*#__PURE__*/react.createElement("span",null,getCategorization(score))),/*#__PURE__*/react.createElement("div",null,/*#__PURE__*/react.createElement("span",{className:titleIndicatorName},"Cumulative Index Score: "),/*#__PURE__*/react.createElement("span",null,readablePercent(score))));};var getBodyContent=function getBodyContent(properties){var rows=[];var sortedKeys=Object.entries(properties).sort();for(var _iterator=_createForOfIteratorHelperLoose(sortedKeys),_step;!(_step=_iterator()).done;){var _step$value=_step.value,key=_step$value[0],value=_step$value[1];// We should only format floats\nif(typeof value===\'number\'&&value%1!==0){value=readablePercent(value);}// Filter out all caps\nif(!key.match(/^[A-Z0-9]+$/)){rows.push(/*#__PURE__*/react.createElement("tr",{key:key},/*#__PURE__*/react.createElement("td",null,key),/*#__PURE__*/react.createElement("td",null,value)));}}return rows;};return/*#__PURE__*/react.createElement(react.Fragment,null,properties?/*#__PURE__*/react.createElement("div",{id:"popupContainer"},getTitleContent(properties),/*#__PURE__*/react.createElement("table",{className:\'usa-table usa-table--borderless \'+popupContentTable},/*#__PURE__*/react.createElement("thead",null,/*#__PURE__*/react.createElement("tr",null,/*#__PURE__*/react.createElement("th",{scope:"col"},"INDICATOR"),/*#__PURE__*/react.createElement("th",{scope:"col"},"VALUE"))),/*#__PURE__*/react.createElement("tbody",null,getBodyContent(properties)))):\'\');};/* harmony default export */ var popupContent = (PopupContent);\n// EXTERNAL MODULE: ./node_modules/react-dom/index.js\nvar react_dom = __webpack_require__(3935);\n;// CONCATENATED MODULE: ./src/components/mapboxMap.module.scss\n// extracted by mini-css-extract-plugin\nvar mapboxMap_module_mapContainer = "mapboxMap-module--mapContainer--3rGD6";\nvar j40Popup = "mapboxMap-module--j40Popup--mt6lB";\n;// CONCATENATED MODULE: ./src/components/mapboxMap.tsx\n/* eslint-disable no-unused-vars */var MapboxMap=function MapboxMap(){var mapContainer=react.useRef(null);var map=(0,react.useRef)();var _useState=(0,react.useState)(GLOBAL_MIN_ZOOM),zoom=_useState[0],setZoom=_useState[1];(0,react.useEffect)(function(){// Only initialize once\nif(map.current&&mapContainer.current)return;var initialMap=new mapbox_gl.Map({container:mapContainer.current,style:data_mapStyle,center:DEFAULT_CENTER,zoom:zoom,minZoom:GLOBAL_MIN_ZOOM,maxZoom:GLOBAL_MAX_ZOOM,maxBounds:GLOBAL_MAX_BOUNDS});// disable map rotation using right click + drag\ninitialMap.dragRotate.disable();// disable map rotation using touch rotation gesture\ninitialMap.touchZoomRotate.disableRotation();initialMap.on(\'click\',handleClick);initialMap.addControl(new mapbox_gl.NavigationControl({showCompass:false}),\'top-left\');map.current=initialMap;});var handleClick=function handleClick(e){var map=e.target;var clickedCoord=e.point;var features=map.queryRenderedFeatures(clickedCoord,{layers:[\'score\']});if(features.length&&features[0].properties){var placeholder=document.createElement(\'div\');react_dom.render(/*#__PURE__*/react.createElement(popupContent,{properties:features[0].properties}),placeholder);var options={offset:[0,0],className:j40Popup,focusAfterOpen:false};new mapbox_gl.Popup(options).setLngLat(e.lngLat).setDOMContent(placeholder).addTo(map);}};(0,react.useEffect)(function(){if(!map.current)return;// wait for map to initialize\nmap.current.on(\'move\',function(){setZoom(map.current.getZoom());});map.current.on(\'mouseenter\',\'score\',function(){map.current.getCanvas().style.cursor=\'pointer\';});map.current.on(\'mouseleave\',\'score\',function(){map.current.getCanvas().style.cursor=\'\';});});return/*#__PURE__*/react.createElement("div",null,/*#__PURE__*/react.createElement("div",{ref:mapContainer,className:mapboxMap_module_mapContainer}),/*#__PURE__*/react.createElement(components_zoomWarning,{zoomLevel:zoom}));};/* harmony default export */ var mapboxMap = (MapboxMap);\n// EXTERNAL MODULE: ./node_modules/core-js/modules/es.array.flat.js\nvar es_array_flat = __webpack_require__(4944);\n;// CONCATENATED MODULE: ./node_modules/ol/Disposable.js\n/**\n * @module ol/Disposable\n */\n\n/**\n * @classdesc\n * Objects that need to clean up after themselves.\n */\nvar Disposable =\n/** @class */\nfunction () {\n function Disposable() {\n /**\n * The object has already been disposed.\n * @type {boolean}\n * @protected\n */\n this.disposed = false;\n }\n /**\n * Clean up.\n */\n\n\n Disposable.prototype.dispose = function () {\n if (!this.disposed) {\n this.disposed = true;\n this.disposeInternal();\n }\n };\n /**\n * Extension point for disposable objects.\n * @protected\n */\n\n\n Disposable.prototype.disposeInternal = function () {};\n\n return Disposable;\n}();\n\n/* harmony default export */ var ol_Disposable = (Disposable);\n;// CONCATENATED MODULE: ./node_modules/ol/array.js\n/**\n * @module ol/array\n */\n\n/**\n * Performs a binary search on the provided sorted list and returns the index of the item if found. If it can\'t be found it\'ll return -1.\n * https://github.com/darkskyapp/binary-search\n *\n * @param {Array<*>} haystack Items to search through.\n * @param {*} needle The item to look for.\n * @param {Function=} opt_comparator Comparator function.\n * @return {number} The index of the item if found, -1 if not.\n */\nfunction binarySearch(haystack, needle, opt_comparator) {\n var mid, cmp;\n var comparator = opt_comparator || numberSafeCompareFunction;\n var low = 0;\n var high = haystack.length;\n var found = false;\n\n while (low < high) {\n /* Note that "(low + high) >>> 1" may overflow, and results in a typecast\n * to double (which gives the wrong results). */\n mid = low + (high - low >> 1);\n cmp = +comparator(haystack[mid], needle);\n\n if (cmp < 0.0) {\n /* Too low. */\n low = mid + 1;\n } else {\n /* Key found or too high */\n high = mid;\n found = !cmp;\n }\n }\n /* Key not found. */\n\n\n return found ? low : ~low;\n}\n/**\n * Compare function for array sort that is safe for numbers.\n * @param {*} a The first object to be compared.\n * @param {*} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second.\n */\n\nfunction numberSafeCompareFunction(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\n/**\n * Whether the array contains the given object.\n * @param {Array<*>} arr The array to test for the presence of the element.\n * @param {*} obj The object for which to test.\n * @return {boolean} The object is in the array.\n */\n\nfunction includes(arr, obj) {\n return arr.indexOf(obj) >= 0;\n}\n/**\n * @param {Array<number>} arr Array.\n * @param {number} target Target.\n * @param {number} direction 0 means return the nearest, > 0\n * means return the largest nearest, < 0 means return the\n * smallest nearest.\n * @return {number} Index.\n */\n\nfunction linearFindNearest(arr, target, direction) {\n var n = arr.length;\n\n if (arr[0] <= target) {\n return 0;\n } else if (target <= arr[n - 1]) {\n return n - 1;\n } else {\n var i = void 0;\n\n if (direction > 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] < target) {\n return i - 1;\n }\n }\n } else if (direction < 0) {\n for (i = 1; i < n; ++i) {\n if (arr[i] <= target) {\n return i;\n }\n }\n } else {\n for (i = 1; i < n; ++i) {\n if (arr[i] == target) {\n return i;\n } else if (arr[i] < target) {\n if (arr[i - 1] - target < target - arr[i]) {\n return i - 1;\n } else {\n return i;\n }\n }\n }\n }\n\n return n - 1;\n }\n}\n/**\n * @param {Array<*>} arr Array.\n * @param {number} begin Begin index.\n * @param {number} end End index.\n */\n\nfunction reverseSubArray(arr, begin, end) {\n while (begin < end) {\n var tmp = arr[begin];\n arr[begin] = arr[end];\n arr[end] = tmp;\n ++begin;\n --end;\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {!Array<VALUE>|VALUE} data The elements or arrays of elements to add to arr.\n * @template VALUE\n */\n\nfunction array_extend(arr, data) {\n var extension = Array.isArray(data) ? data : [data];\n var length = extension.length;\n\n for (var i = 0; i < length; i++) {\n arr[arr.length] = extension[i];\n }\n}\n/**\n * @param {Array<VALUE>} arr The array to modify.\n * @param {VALUE} obj The element to remove.\n * @template VALUE\n * @return {boolean} If the element was removed.\n */\n\nfunction remove(arr, obj) {\n var i = arr.indexOf(obj);\n var found = i > -1;\n\n if (found) {\n arr.splice(i, 1);\n }\n\n return found;\n}\n/**\n * @param {Array<VALUE>} arr The array to search in.\n * @param {function(VALUE, number, ?) : boolean} func The function to compare.\n * @template VALUE\n * @return {VALUE|null} The element found or null.\n */\n\nfunction find(arr, func) {\n var length = arr.length >>> 0;\n var value;\n\n for (var i = 0; i < length; i++) {\n value = arr[i];\n\n if (func(value, i, arr)) {\n return value;\n }\n }\n\n return null;\n}\n/**\n * @param {Array|Uint8ClampedArray} arr1 The first array to compare.\n * @param {Array|Uint8ClampedArray} arr2 The second array to compare.\n * @return {boolean} Whether the two arrays are equal.\n */\n\nfunction equals(arr1, arr2) {\n var len1 = arr1.length;\n\n if (len1 !== arr2.length) {\n return false;\n }\n\n for (var i = 0; i < len1; i++) {\n if (arr1[i] !== arr2[i]) {\n return false;\n }\n }\n\n return true;\n}\n/**\n * Sort the passed array such that the relative order of equal elements is preverved.\n * See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.\n * @param {Array<*>} arr The array to sort (modifies original).\n * @param {!function(*, *): number} compareFnc Comparison function.\n * @api\n */\n\nfunction stableSort(arr, compareFnc) {\n var length = arr.length;\n var tmp = Array(arr.length);\n var i;\n\n for (i = 0; i < length; i++) {\n tmp[i] = {\n index: i,\n value: arr[i]\n };\n }\n\n tmp.sort(function (a, b) {\n return compareFnc(a.value, b.value) || a.index - b.index;\n });\n\n for (i = 0; i < arr.length; i++) {\n arr[i] = tmp[i].value;\n }\n}\n/**\n * @param {Array<*>} arr The array to search in.\n * @param {Function} func Comparison function.\n * @return {number} Return index.\n */\n\nfunction findIndex(arr, func) {\n var index;\n var found = !arr.every(function (el, idx) {\n index = idx;\n return !func(el, idx, arr);\n });\n return found ? index : -1;\n}\n/**\n * @param {Array<*>} arr The array to test.\n * @param {Function=} opt_func Comparison function.\n * @param {boolean=} opt_strict Strictly sorted (default false).\n * @return {boolean} Return index.\n */\n\nfunction isSorted(arr, opt_func, opt_strict) {\n var compare = opt_func || numberSafeCompareFunction;\n return arr.every(function (currentVal, index) {\n if (index === 0) {\n return true;\n }\n\n var res = compare(arr[index - 1], currentVal);\n return !(res > 0 || opt_strict && res === 0);\n });\n}\n;// CONCATENATED MODULE: ./node_modules/ol/functions.js\n/**\n * @module ol/functions\n */\n\n/**\n * Always returns true.\n * @returns {boolean} true.\n */\n\nfunction TRUE() {\n return true;\n}\n/**\n * Always returns false.\n * @returns {boolean} false.\n */\n\nfunction functions_FALSE() {\n return false;\n}\n/**\n * A reusable function, used e.g. as a default for callbacks.\n *\n * @return {void} Nothing.\n */\n\nfunction VOID() {}\n/**\n * Wrap a function in another function that remembers the last return. If the\n * returned function is called twice in a row with the same arguments and the same\n * this object, it will return the value from the first call in the second call.\n *\n * @param {function(...any): ReturnType} fn The function to memoize.\n * @return {function(...any): ReturnType} The memoized function.\n * @template ReturnType\n */\n\nfunction memoizeOne(fn) {\n var called = false;\n /** @type {ReturnType} */\n\n var lastResult;\n /** @type {Array<any>} */\n\n var lastArgs;\n var lastThis;\n return function () {\n var nextArgs = Array.prototype.slice.call(arguments);\n\n if (!called || this !== lastThis || !equals(nextArgs, lastArgs)) {\n called = true;\n lastThis = this;\n lastArgs = nextArgs;\n lastResult = fn.apply(this, arguments);\n }\n\n return lastResult;\n };\n}\n;// CONCATENATED MODULE: ./node_modules/ol/util.js\n/**\n * @module ol/util\n */\n\n/**\n * @return {?} Any return.\n */\nfunction util_abstract() {\n return (\n /** @type {?} */\n function () {\n throw new Error(\'Unimplemented abstract method.\');\n }()\n );\n}\n/**\n * Counter for getUid.\n * @type {number}\n * @private\n */\n\nvar uidCounter_ = 0;\n/**\n * Gets a unique ID for an object. This mutates the object so that further calls\n * with the same object as a parameter returns the same value. Unique IDs are generated\n * as a strictly increasing sequence. Adapted from goog.getUid.\n *\n * @param {Object} obj The object to get the unique ID for.\n * @return {string} The unique ID for the object.\n * @api\n */\n\nfunction getUid(obj) {\n return obj.ol_uid || (obj.ol_uid = String(++uidCounter_));\n}\n/**\n * OpenLayers version.\n * @type {string}\n */\n\nvar VERSION = \'6.5.0\';\n;// CONCATENATED MODULE: ./node_modules/ol/AssertionError.js\nvar __extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/AssertionError\n */\n\n\n\n/**\n * Error object thrown when an assertion failed. This is an ECMA-262 Error,\n * extended with a `code` property.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.\n */\n\nvar AssertionError =\n/** @class */\nfunction (_super) {\n __extends(AssertionError, _super);\n /**\n * @param {number} code Error code.\n */\n\n\n function AssertionError(code) {\n var _this = this;\n\n var path = VERSION === \'latest\' ? VERSION : \'v\' + VERSION.split(\'-\')[0];\n var message = \'Assertion failed. See https://openlayers.org/en/\' + path + \'/doc/errors/#\' + code + \' for details.\';\n _this = _super.call(this, message) || this;\n /**\n * Error code. The meaning of the code can be found on\n * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with\n * the version found in the OpenLayers script\'s header comment if a version\n * other than the latest is used).\n * @type {number}\n * @api\n */\n\n _this.code = code;\n /**\n * @type {string}\n */\n\n _this.name = \'AssertionError\'; // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40\n\n _this.message = message;\n return _this;\n }\n\n return AssertionError;\n}(Error);\n\n/* harmony default export */ var ol_AssertionError = (AssertionError);\n;// CONCATENATED MODULE: ./node_modules/ol/asserts.js\n/**\n * @module ol/asserts\n */\n\n/**\n * @param {*} assertion Assertion we expected to be truthy.\n * @param {number} errorCode Error code.\n */\n\nfunction asserts_assert(assertion, errorCode) {\n if (!assertion) {\n throw new ol_AssertionError(errorCode);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/transform.js\n/**\n * @module ol/transform\n */\n\n/**\n * An array representing an affine 2d transformation for use with\n * {@link module:ol/transform} functions. The array has 6 elements.\n * @typedef {!Array<number>} Transform\n * @api\n */\n\n/**\n * Collection of affine 2d transformation functions. The functions work on an\n * array of 6 elements. The element order is compatible with the [SVGMatrix\n * interface](https://developer.mozilla.org/en-US/docs/Web/API/SVGMatrix) and is\n * a subset (elements a to f) of a 3×3 matrix:\n * ```\n * [ a c e ]\n * [ b d f ]\n * [ 0 0 1 ]\n * ```\n */\n\n/**\n * @private\n * @type {Transform}\n */\n\nvar tmp_ = new Array(6);\n/**\n * Create an identity transform.\n * @return {!Transform} Identity transform.\n */\n\nfunction create() {\n return [1, 0, 0, 1, 0, 0];\n}\n/**\n * Resets the given transform to an identity transform.\n * @param {!Transform} transform Transform.\n * @return {!Transform} Transform.\n */\n\nfunction transform_reset(transform) {\n return set(transform, 1, 0, 0, 1, 0, 0);\n}\n/**\n * Multiply the underlying matrices of two transforms and return the result in\n * the first transform.\n * @param {!Transform} transform1 Transform parameters of matrix 1.\n * @param {!Transform} transform2 Transform parameters of matrix 2.\n * @return {!Transform} transform1 multiplied with transform2.\n */\n\nfunction multiply(transform1, transform2) {\n var a1 = transform1[0];\n var b1 = transform1[1];\n var c1 = transform1[2];\n var d1 = transform1[3];\n var e1 = transform1[4];\n var f1 = transform1[5];\n var a2 = transform2[0];\n var b2 = transform2[1];\n var c2 = transform2[2];\n var d2 = transform2[3];\n var e2 = transform2[4];\n var f2 = transform2[5];\n transform1[0] = a1 * a2 + c1 * b2;\n transform1[1] = b1 * a2 + d1 * b2;\n transform1[2] = a1 * c2 + c1 * d2;\n transform1[3] = b1 * c2 + d1 * d2;\n transform1[4] = a1 * e2 + c1 * f2 + e1;\n transform1[5] = b1 * e2 + d1 * f2 + f1;\n return transform1;\n}\n/**\n * Set the transform components a-f on a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} a The a component of the transform.\n * @param {number} b The b component of the transform.\n * @param {number} c The c component of the transform.\n * @param {number} d The d component of the transform.\n * @param {number} e The e component of the transform.\n * @param {number} f The f component of the transform.\n * @return {!Transform} Matrix with transform applied.\n */\n\nfunction set(transform, a, b, c, d, e, f) {\n transform[0] = a;\n transform[1] = b;\n transform[2] = c;\n transform[3] = d;\n transform[4] = e;\n transform[5] = f;\n return transform;\n}\n/**\n * Set transform on one matrix from another matrix.\n * @param {!Transform} transform1 Matrix to set transform to.\n * @param {!Transform} transform2 Matrix to set transform from.\n * @return {!Transform} transform1 with transform from transform2 applied.\n */\n\nfunction setFromArray(transform1, transform2) {\n transform1[0] = transform2[0];\n transform1[1] = transform2[1];\n transform1[2] = transform2[2];\n transform1[3] = transform2[3];\n transform1[4] = transform2[4];\n transform1[5] = transform2[5];\n return transform1;\n}\n/**\n * Transforms the given coordinate with the given transform returning the\n * resulting, transformed coordinate. The coordinate will be modified in-place.\n *\n * @param {Transform} transform The transformation.\n * @param {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} coordinate The coordinate to transform.\n * @return {import("./coordinate.js").Coordinate|import("./pixel.js").Pixel} return coordinate so that operations can be\n * chained together.\n */\n\nfunction apply(transform, coordinate) {\n var x = coordinate[0];\n var y = coordinate[1];\n coordinate[0] = transform[0] * x + transform[2] * y + transform[4];\n coordinate[1] = transform[1] * x + transform[3] * y + transform[5];\n return coordinate;\n}\n/**\n * Applies rotation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} angle Angle in radians.\n * @return {!Transform} The rotated transform.\n */\n\nfunction rotate(transform, angle) {\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n return multiply(transform, set(tmp_, cos, sin, -sin, cos, 0, 0));\n}\n/**\n * Applies scale to a given transform.\n * @param {!Transform} transform Transform.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scaled transform.\n */\n\nfunction scale(transform, x, y) {\n return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0));\n}\n/**\n * Creates a scale transform.\n * @param {!Transform} target Transform to overwrite.\n * @param {number} x Scale factor x.\n * @param {number} y Scale factor y.\n * @return {!Transform} The scale transform.\n */\n\nfunction makeScale(target, x, y) {\n return set(target, x, 0, 0, y, 0, 0);\n}\n/**\n * Applies translation to the given transform.\n * @param {!Transform} transform Transform.\n * @param {number} dx Translation x.\n * @param {number} dy Translation y.\n * @return {!Transform} The translated transform.\n */\n\nfunction translate(transform, dx, dy) {\n return multiply(transform, set(tmp_, 1, 0, 0, 1, dx, dy));\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative).\n * @param {!Transform} transform The transform (will be modified in place).\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {!Transform} The composite transform.\n */\n\nfunction compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) {\n var sin = Math.sin(angle);\n var cos = Math.cos(angle);\n transform[0] = sx * cos;\n transform[1] = sy * sin;\n transform[2] = -sx * sin;\n transform[3] = sy * cos;\n transform[4] = dx2 * sx * cos - dy2 * sx * sin + dx1;\n transform[5] = dx2 * sy * sin + dy2 * sy * cos + dy1;\n return transform;\n}\n/**\n * Creates a composite transform given an initial translation, scale, rotation, and\n * final translation (in that order only, not commutative). The resulting transform\n * string can be applied as `transform` porperty of an HTMLElement\'s style.\n * @param {number} dx1 Initial translation x.\n * @param {number} dy1 Initial translation y.\n * @param {number} sx Scale factor x.\n * @param {number} sy Scale factor y.\n * @param {number} angle Rotation (in counter-clockwise radians).\n * @param {number} dx2 Final translation x.\n * @param {number} dy2 Final translation y.\n * @return {string} The composite css transform.\n * @api\n */\n\nfunction composeCssTransform(dx1, dy1, sx, sy, angle, dx2, dy2) {\n return transform_toString(compose(create(), dx1, dy1, sx, sy, angle, dx2, dy2));\n}\n/**\n * Invert the given transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (source) transform.\n */\n\nfunction invert(source) {\n return makeInverse(source, source);\n}\n/**\n * Invert the given transform.\n * @param {!Transform} target Transform to be set as the inverse of\n * the source transform.\n * @param {!Transform} source The source transform to invert.\n * @return {!Transform} The inverted (target) transform.\n */\n\nfunction makeInverse(target, source) {\n var det = determinant(source);\n asserts_assert(det !== 0, 32); // Transformation matrix cannot be inverted\n\n var a = source[0];\n var b = source[1];\n var c = source[2];\n var d = source[3];\n var e = source[4];\n var f = source[5];\n target[0] = d / det;\n target[1] = -b / det;\n target[2] = -c / det;\n target[3] = a / det;\n target[4] = (c * f - d * e) / det;\n target[5] = -(a * f - b * e) / det;\n return target;\n}\n/**\n * Returns the determinant of the given matrix.\n * @param {!Transform} mat Matrix.\n * @return {number} Determinant.\n */\n\nfunction determinant(mat) {\n return mat[0] * mat[3] - mat[1] * mat[2];\n}\n/**\n * A string version of the transform. This can be used\n * for CSS transforms.\n * @param {!Transform} mat Matrix.\n * @return {string} The transform as a string.\n */\n\nfunction transform_toString(mat) {\n return \'matrix(\' + mat.join(\', \') + \')\';\n}\n;// CONCATENATED MODULE: ./node_modules/ol/extent/Corner.js\n/**\n * @module ol/extent/Corner\n */\n\n/**\n * Extent corner.\n * @enum {string}\n */\n/* harmony default export */ var extent_Corner = ({\n BOTTOM_LEFT: \'bottom-left\',\n BOTTOM_RIGHT: \'bottom-right\',\n TOP_LEFT: \'top-left\',\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/extent/Relationship.js\n/**\n * @module ol/extent/Relationship\n */\n\n/**\n * Relationship to an extent.\n * @enum {number}\n */\n/* harmony default export */ var extent_Relationship = ({\n UNKNOWN: 0,\n INTERSECTING: 1,\n ABOVE: 2,\n RIGHT: 4,\n BELOW: 8,\n LEFT: 16\n});\n;// CONCATENATED MODULE: ./node_modules/ol/extent.js\n/**\n * @module ol/extent\n */\n\n\n\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array<number>} Extent\n * @api\n */\n\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Bounding extent.\n * @api\n */\n\nfunction boundingExtent(coordinates) {\n var extent = createEmpty();\n\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Array<number>} xs Xs.\n * @param {Array<number>} ys Ys.\n * @param {Extent=} opt_extent Destination extent.\n * @private\n * @return {Extent} Extent.\n */\n\nfunction _boundingExtentXYs(xs, ys, opt_extent) {\n var minX = Math.min.apply(null, xs);\n var minY = Math.min.apply(null, ys);\n var maxX = Math.max.apply(null, xs);\n var maxY = Math.max.apply(null, ys);\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n}\n/**\n * Return extent increased by the provided value.\n * @param {Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n * @api\n */\n\n\nfunction buffer(extent, value, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0] - value;\n opt_extent[1] = extent[1] - value;\n opt_extent[2] = extent[2] + value;\n opt_extent[3] = extent[3] + value;\n return opt_extent;\n } else {\n return [extent[0] - value, extent[1] - value, extent[2] + value, extent[3] + value];\n }\n}\n/**\n * Creates a clone of an extent.\n *\n * @param {Extent} extent Extent to clone.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} The clone.\n */\n\nfunction clone(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent.slice();\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\n\nfunction closestSquaredDistanceXY(extent, x, y) {\n var dx, dy;\n\n if (x < extent[0]) {\n dx = extent[0] - x;\n } else if (extent[2] < x) {\n dx = x - extent[2];\n } else {\n dx = 0;\n }\n\n if (y < extent[1]) {\n dy = extent[1] - y;\n } else if (extent[3] < y) {\n dy = y - extent[3];\n } else {\n dy = 0;\n }\n\n return dx * dx + dy * dy;\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\n\nfunction containsCoordinate(extent, coordinate) {\n return containsXY(extent, coordinate[0], coordinate[1]);\n}\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n * first.\n * @api\n */\n\nfunction containsExtent(extent1, extent2) {\n return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && extent1[1] <= extent2[1] && extent2[3] <= extent1[3];\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\n\nfunction containsXY(extent, x, y) {\n return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n/**\n * Get the relationship between a coordinate and extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} coordinate The coordinate.\n * @return {import("./extent/Relationship.js").default} The relationship (bitwise compare with\n * import("./extent/Relationship.js").Relationship).\n */\n\nfunction coordinateRelationship(extent, coordinate) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var x = coordinate[0];\n var y = coordinate[1];\n var relationship = extent_Relationship.UNKNOWN;\n\n if (x < minX) {\n relationship = relationship | extent_Relationship.LEFT;\n } else if (x > maxX) {\n relationship = relationship | extent_Relationship.RIGHT;\n }\n\n if (y < minY) {\n relationship = relationship | extent_Relationship.BELOW;\n } else if (y > maxY) {\n relationship = relationship | extent_Relationship.ABOVE;\n }\n\n if (relationship === extent_Relationship.UNKNOWN) {\n relationship = extent_Relationship.INTERSECTING;\n }\n\n return relationship;\n}\n/**\n * Create an empty extent.\n * @return {Extent} Empty extent.\n * @api\n */\n\nfunction createEmpty() {\n return [Infinity, Infinity, -Infinity, -Infinity];\n}\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdate(minX, minY, maxX, maxY, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = minX;\n opt_extent[1] = minY;\n opt_extent[2] = maxX;\n opt_extent[3] = maxY;\n return opt_extent;\n } else {\n return [minX, minY, maxX, maxY];\n }\n}\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateEmpty(opt_extent) {\n return createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, opt_extent);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromCoordinate(coordinate, opt_extent) {\n var x = coordinate[0];\n var y = coordinate[1];\n return createOrUpdate(x, y, x, y, opt_extent);\n}\n/**\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromCoordinates(coordinates, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendCoordinates(extent, coordinates);\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n/**\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction createOrUpdateFromRings(rings, opt_extent) {\n var extent = createOrUpdateEmpty(opt_extent);\n return extendRings(extent, rings);\n}\n/**\n * Determine if two extents are equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\n\nfunction extent_equals(extent1, extent2) {\n return extent1[0] == extent2[0] && extent1[2] == extent2[2] && extent1[1] == extent2[1] && extent1[3] == extent2[3];\n}\n/**\n * Determine if two extents are approximately equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {number} tolerance Tolerance in extent coordinate units.\n * @return {boolean} The two extents differ by less than the tolerance.\n */\n\nfunction approximatelyEquals(extent1, extent2, tolerance) {\n return Math.abs(extent1[0] - extent2[0]) < tolerance && Math.abs(extent1[2] - extent2[2]) < tolerance && Math.abs(extent1[1] - extent2[1]) < tolerance && Math.abs(extent1[3] - extent2[3]) < tolerance;\n}\n/**\n * Modify an extent to include another extent.\n * @param {Extent} extent1 The extent to be modified.\n * @param {Extent} extent2 The extent that will be included in the first.\n * @return {Extent} A reference to the first (extended) extent.\n * @api\n */\n\nfunction extent_extend(extent1, extent2) {\n if (extent2[0] < extent1[0]) {\n extent1[0] = extent2[0];\n }\n\n if (extent2[2] > extent1[2]) {\n extent1[2] = extent2[2];\n }\n\n if (extent2[1] < extent1[1]) {\n extent1[1] = extent2[1];\n }\n\n if (extent2[3] > extent1[3]) {\n extent1[3] = extent2[3];\n }\n\n return extent1;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n */\n\nfunction extendCoordinate(extent, coordinate) {\n if (coordinate[0] < extent[0]) {\n extent[0] = coordinate[0];\n }\n\n if (coordinate[0] > extent[2]) {\n extent[2] = coordinate[0];\n }\n\n if (coordinate[1] < extent[1]) {\n extent[1] = coordinate[1];\n }\n\n if (coordinate[1] > extent[3]) {\n extent[3] = coordinate[1];\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Extent.\n */\n\nfunction extendCoordinates(extent, coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Extent} Extent.\n */\n\nfunction extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {\n for (; offset < end; offset += stride) {\n extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @return {Extent} Extent.\n */\n\nfunction extendRings(extent, rings) {\n for (var i = 0, ii = rings.length; i < ii; ++i) {\n extendCoordinates(extent, rings[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\n\nfunction extendXY(extent, x, y) {\n extent[0] = Math.min(extent[0], x);\n extent[1] = Math.min(extent[1], y);\n extent[2] = Math.max(extent[2], x);\n extent[3] = Math.max(extent[3], y);\n}\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {Extent} extent Extent.\n * @param {function(import("./coordinate.js").Coordinate): S} callback Callback.\n * @return {S|boolean} Value.\n * @template S\n */\n\nfunction forEachCorner(extent, callback) {\n var val;\n val = callback(getBottomLeft(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getBottomRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getTopRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(getTopLeft(extent));\n\n if (val) {\n return val;\n }\n\n return false;\n}\n/**\n * Get the size of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\n\nfunction getArea(extent) {\n var area = 0;\n\n if (!extent_isEmpty(extent)) {\n area = extent_getWidth(extent) * getHeight(extent);\n }\n\n return area;\n}\n/**\n * Get the bottom left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom left coordinate.\n * @api\n */\n\nfunction getBottomLeft(extent) {\n return [extent[0], extent[1]];\n}\n/**\n * Get the bottom right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom right coordinate.\n * @api\n */\n\nfunction getBottomRight(extent) {\n return [extent[2], extent[1]];\n}\n/**\n * Get the center coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Center.\n * @api\n */\n\nfunction getCenter(extent) {\n return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n/**\n * Get a corner coordinate of an extent.\n * @param {Extent} extent Extent.\n * @param {import("./extent/Corner.js").default} corner Corner.\n * @return {import("./coordinate.js").Coordinate} Corner coordinate.\n */\n\nfunction getCorner(extent, corner) {\n var coordinate;\n\n if (corner === extent_Corner.BOTTOM_LEFT) {\n coordinate = getBottomLeft(extent);\n } else if (corner === extent_Corner.BOTTOM_RIGHT) {\n coordinate = getBottomRight(extent);\n } else if (corner === extent_Corner.TOP_LEFT) {\n coordinate = getTopLeft(extent);\n } else if (corner === extent_Corner.TOP_RIGHT) {\n coordinate = getTopRight(extent);\n } else {\n asserts_assert(false, 13); // Invalid corner\n }\n\n return coordinate;\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\n\nfunction getEnlargedArea(extent1, extent2) {\n var minX = Math.min(extent1[0], extent2[0]);\n var minY = Math.min(extent1[1], extent2[1]);\n var maxX = Math.max(extent1[2], extent2[2]);\n var maxY = Math.max(extent1[3], extent2[3]);\n return (maxX - minX) * (maxY - minY);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import("./size.js").Size} size Size.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction getForViewAndSize(center, resolution, rotation, size, opt_extent) {\n var dx = resolution * size[0] / 2;\n var dy = resolution * size[1] / 2;\n var cosRotation = Math.cos(rotation);\n var sinRotation = Math.sin(rotation);\n var xCos = dx * cosRotation;\n var xSin = dx * sinRotation;\n var yCos = dy * cosRotation;\n var ySin = dy * sinRotation;\n var x = center[0];\n var y = center[1];\n var x0 = x - xCos + ySin;\n var x1 = x - xCos - ySin;\n var x2 = x + xCos - ySin;\n var x3 = x + xCos + ySin;\n var y0 = y - xSin - yCos;\n var y1 = y - xSin + yCos;\n var y2 = y + xSin + yCos;\n var y3 = y + xSin - yCos;\n return createOrUpdate(Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3), Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3), opt_extent);\n}\n/**\n * Get the height of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\n\nfunction getHeight(extent) {\n return extent[3] - extent[1];\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\n\nfunction getIntersectionArea(extent1, extent2) {\n var intersection = getIntersection(extent1, extent2);\n return getArea(intersection);\n}\n/**\n * Get the intersection of two extents.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {Extent=} opt_extent Optional extent to populate with intersection.\n * @return {Extent} Intersecting extent.\n * @api\n */\n\nfunction getIntersection(extent1, extent2, opt_extent) {\n var intersection = opt_extent ? opt_extent : createEmpty();\n\n if (intersects(extent1, extent2)) {\n if (extent1[0] > extent2[0]) {\n intersection[0] = extent1[0];\n } else {\n intersection[0] = extent2[0];\n }\n\n if (extent1[1] > extent2[1]) {\n intersection[1] = extent1[1];\n } else {\n intersection[1] = extent2[1];\n }\n\n if (extent1[2] < extent2[2]) {\n intersection[2] = extent1[2];\n } else {\n intersection[2] = extent2[2];\n }\n\n if (extent1[3] < extent2[3]) {\n intersection[3] = extent1[3];\n } else {\n intersection[3] = extent2[3];\n }\n } else {\n createOrUpdateEmpty(intersection);\n }\n\n return intersection;\n}\n/**\n * @param {Extent} extent Extent.\n * @return {number} Margin.\n */\n\nfunction getMargin(extent) {\n return extent_getWidth(extent) + getHeight(extent);\n}\n/**\n * Get the size (width, height) of an extent.\n * @param {Extent} extent The extent.\n * @return {import("./size.js").Size} The extent size.\n * @api\n */\n\nfunction getSize(extent) {\n return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n/**\n * Get the top left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top left coordinate.\n * @api\n */\n\nfunction getTopLeft(extent) {\n return [extent[0], extent[3]];\n}\n/**\n * Get the top right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top right coordinate.\n * @api\n */\n\nfunction getTopRight(extent) {\n return [extent[2], extent[3]];\n}\n/**\n * Get the width of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\n\nfunction extent_getWidth(extent) {\n return extent[2] - extent[0];\n}\n/**\n * Determine if one extent intersects another.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\n\nfunction intersects(extent1, extent2) {\n return extent1[0] <= extent2[2] && extent1[2] >= extent2[0] && extent1[1] <= extent2[3] && extent1[3] >= extent2[1];\n}\n/**\n * Determine if an extent is empty.\n * @param {Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\n\nfunction extent_isEmpty(extent) {\n return extent[2] < extent[0] || extent[3] < extent[1];\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction returnOrUpdate(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent;\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} value Value.\n */\n\nfunction scaleFromCenter(extent, value) {\n var deltaX = (extent[2] - extent[0]) / 2 * (value - 1);\n var deltaY = (extent[3] - extent[1]) / 2 * (value - 1);\n extent[0] -= deltaX;\n extent[2] += deltaX;\n extent[1] -= deltaY;\n extent[3] += deltaY;\n}\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} start Segment start coordinate.\n * @param {import("./coordinate.js").Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\n\nfunction intersectsSegment(extent, start, end) {\n var intersects = false;\n var startRel = coordinateRelationship(extent, start);\n var endRel = coordinateRelationship(extent, end);\n\n if (startRel === extent_Relationship.INTERSECTING || endRel === extent_Relationship.INTERSECTING) {\n intersects = true;\n } else {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var startX = start[0];\n var startY = start[1];\n var endX = end[0];\n var endY = end[1];\n var slope = (endY - startY) / (endX - startX);\n var x = void 0,\n y = void 0;\n\n if (!!(endRel & extent_Relationship.ABOVE) && !(startRel & extent_Relationship.ABOVE)) {\n // potentially intersects top\n x = endX - (endY - maxY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & extent_Relationship.RIGHT) && !(startRel & extent_Relationship.RIGHT)) {\n // potentially intersects right\n y = endY - (endX - maxX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n\n if (!intersects && !!(endRel & extent_Relationship.BELOW) && !(startRel & extent_Relationship.BELOW)) {\n // potentially intersects bottom\n x = endX - (endY - minY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & extent_Relationship.LEFT) && !(startRel & extent_Relationship.LEFT)) {\n // potentially intersects left\n y = endY - (endX - minX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n }\n\n return intersects;\n}\n/**\n * Apply a transform function to the extent.\n * @param {Extent} extent Extent.\n * @param {import("./proj.js").TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {Extent=} opt_extent Destination extent.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {Extent} Extent.\n * @api\n */\n\nfunction applyTransform(extent, transformFn, opt_extent, opt_stops) {\n var coordinates = [];\n\n if (opt_stops > 1) {\n var width = extent[2] - extent[0];\n var height = extent[3] - extent[1];\n\n for (var i = 0; i < opt_stops; ++i) {\n coordinates.push(extent[0] + width * i / opt_stops, extent[1], extent[2], extent[1] + height * i / opt_stops, extent[2] - width * i / opt_stops, extent[3], extent[0], extent[3] - height * i / opt_stops);\n }\n } else {\n coordinates = [extent[0], extent[1], extent[2], extent[1], extent[2], extent[3], extent[0], extent[3]];\n }\n\n transformFn(coordinates, coordinates, 2);\n var xs = [];\n var ys = [];\n\n for (var i = 0, l = coordinates.length; i < l; i += 2) {\n xs.push(coordinates[i]);\n ys.push(coordinates[i + 1]);\n }\n\n return _boundingExtentXYs(xs, ys, opt_extent);\n}\n/**\n * Modifies the provided extent in-place to be within the real world\n * extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./proj/Projection.js").default} projection Projection\n * @return {Extent} The extent within the real world extent.\n */\n\nfunction wrapX(extent, projection) {\n var projectionExtent = projection.getExtent();\n var center = getCenter(extent);\n\n if (projection.canWrapX() && (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {\n var worldWidth = extent_getWidth(projectionExtent);\n var worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);\n var offset = worldsAway * worldWidth;\n extent[0] -= offset;\n extent[2] -= offset;\n }\n\n return extent;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/math.js\n/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n * number within the bounds.\n */\nfunction math_clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n/**\n * Return the hyperbolic cosine of a given number. The method will use the\n * native `Math.cosh` function if it is available, otherwise the hyperbolic\n * cosine will be calculated via the reference implementation of the Mozilla\n * developer network.\n *\n * @param {number} x X.\n * @return {number} Hyperbolic cosine of x.\n */\n\nvar cosh = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var cosh;\n\n if (\'cosh\' in Math) {\n // The environment supports the native Math.cosh function, use it…\n cosh = Math.cosh;\n } else {\n // … else, use the reference implementation of MDN:\n cosh = function cosh(x) {\n var y =\n /** @type {Math} */\n Math.exp(x);\n return (y + 1 / y) / 2;\n };\n }\n\n return cosh;\n}();\n/**\n * Return the base 2 logarithm of a given number. The method will use the\n * native `Math.log2` function if it is available, otherwise the base 2\n * logarithm will be calculated via the reference implementation of the\n * Mozilla developer network.\n *\n * @param {number} x X.\n * @return {number} Base 2 logarithm of x.\n */\n\nvar log2 = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var log2;\n\n if (\'log2\' in Math) {\n // The environment supports the native Math.log2 function, use it…\n log2 = Math.log2;\n } else {\n // … else, use the reference implementation of MDN:\n log2 = function log2(x) {\n return Math.log(x) * Math.LOG2E;\n };\n }\n\n return log2;\n}();\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n\n if (dx !== 0 || dy !== 0) {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n x1 = x2;\n y1 = y2;\n } else if (t > 0) {\n x1 += dx * t;\n y1 += dy * t;\n }\n }\n\n return math_squaredDistance(x, y, x1, y1);\n}\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction math_squaredDistance(x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n return dx * dx + dy * dy;\n}\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n * in row-major order.\n * @return {Array<number>} The resulting vector.\n */\n\nfunction solveLinearSystem(mat) {\n var n = mat.length;\n\n for (var i = 0; i < n; i++) {\n // Find max in the i-th column (ignoring i - 1 first rows)\n var maxRow = i;\n var maxEl = Math.abs(mat[i][i]);\n\n for (var r = i + 1; r < n; r++) {\n var absValue = Math.abs(mat[r][i]);\n\n if (absValue > maxEl) {\n maxEl = absValue;\n maxRow = r;\n }\n }\n\n if (maxEl === 0) {\n return null; // matrix is singular\n } // Swap max row with i-th (current) row\n\n\n var tmp = mat[maxRow];\n mat[maxRow] = mat[i];\n mat[i] = tmp; // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n\n for (var j = i + 1; j < n; j++) {\n var coef = -mat[j][i] / mat[i][i];\n\n for (var k = i; k < n + 1; k++) {\n if (i == k) {\n mat[j][k] = 0;\n } else {\n mat[j][k] += coef * mat[i][k];\n }\n }\n }\n } // Solve Ax=b for upper triangular matrix A (mat)\n\n\n var x = new Array(n);\n\n for (var l = n - 1; l >= 0; l--) {\n x[l] = mat[l][n] / mat[l][l];\n\n for (var m = l - 1; m >= 0; m--) {\n mat[m][n] -= mat[m][l] * x[l];\n }\n }\n\n return x;\n}\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\n\nfunction math_toDegrees(angleInRadians) {\n return angleInRadians * 180 / Math.PI;\n}\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\n\nfunction math_toRadians(angleInDegrees) {\n return angleInDegrees * Math.PI / 180;\n}\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\n\nfunction math_modulo(a, b) {\n var r = a % b;\n return r * b < 0 ? r + b : r;\n}\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\n\nfunction lerp(a, b, x) {\n return a + x * (b - a);\n}\n;// CONCATENATED MODULE: ./node_modules/ol/color.js\n/**\n * @module ol/color\n */\n\n\n/**\n * A color represented as a short array [red, green, blue, alpha].\n * red, green, and blue should be integers in the range 0..255 inclusive.\n * alpha should be a float in the range 0..1 inclusive. If no alpha value is\n * given then `1` will be used.\n * @typedef {Array<number>} Color\n * @api\n */\n\n/**\n * This RegExp matches # followed by 3, 4, 6, or 8 hex digits.\n * @const\n * @type {RegExp}\n * @private\n */\n\nvar HEX_COLOR_RE_ = /^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i;\n/**\n * Regular expression for matching potential named color style strings.\n * @const\n * @type {RegExp}\n * @private\n */\n\nvar NAMED_COLOR_RE_ = /^([a-z]*)$|^hsla?\\(.*\\)$/i;\n/**\n * Return the color as an rgba string.\n * @param {Color|string} color Color.\n * @return {string} Rgba string.\n * @api\n */\n\nfunction asString(color) {\n if (typeof color === \'string\') {\n return color;\n } else {\n return color_toString(color);\n }\n}\n/**\n * Return named color as an rgba string.\n * @param {string} color Named color.\n * @return {string} Rgb string.\n */\n\nfunction fromNamed(color) {\n var el = document.createElement(\'div\');\n el.style.color = color;\n\n if (el.style.color !== \'\') {\n document.body.appendChild(el);\n var rgb = getComputedStyle(el).color;\n document.body.removeChild(el);\n return rgb;\n } else {\n return \'\';\n }\n}\n/**\n * @param {string} s String.\n * @return {Color} Color.\n */\n\n\nvar fromString = function () {\n // We maintain a small cache of parsed strings. To provide cheap LRU-like\n // semantics, whenever the cache grows too large we simply delete an\n // arbitrary 25% of the entries.\n\n /**\n * @const\n * @type {number}\n */\n var MAX_CACHE_SIZE = 1024;\n /**\n * @type {Object<string, Color>}\n */\n\n var cache = {};\n /**\n * @type {number}\n */\n\n var cacheSize = 0;\n return (\n /**\n * @param {string} s String.\n * @return {Color} Color.\n */\n function (s) {\n var color;\n\n if (cache.hasOwnProperty(s)) {\n color = cache[s];\n } else {\n if (cacheSize >= MAX_CACHE_SIZE) {\n var i = 0;\n\n for (var key in cache) {\n if ((i++ & 3) === 0) {\n delete cache[key];\n --cacheSize;\n }\n }\n }\n\n color = fromStringInternal_(s);\n cache[s] = color;\n ++cacheSize;\n }\n\n return color;\n }\n );\n}();\n/**\n * Return the color as an array. This function maintains a cache of calculated\n * arrays which means the result should not be modified.\n * @param {Color|string} color Color.\n * @return {Color} Color.\n * @api\n */\n\nfunction asArray(color) {\n if (Array.isArray(color)) {\n return color;\n } else {\n return fromString(color);\n }\n}\n/**\n * @param {string} s String.\n * @private\n * @return {Color} Color.\n */\n\nfunction fromStringInternal_(s) {\n var r, g, b, a, color;\n\n if (NAMED_COLOR_RE_.exec(s)) {\n s = fromNamed(s);\n }\n\n if (HEX_COLOR_RE_.exec(s)) {\n // hex\n var n = s.length - 1; // number of hex digits\n\n var d = // number of digits per channel\n void 0; // number of digits per channel\n\n if (n <= 4) {\n d = 1;\n } else {\n d = 2;\n }\n\n var hasAlpha = n === 4 || n === 8;\n r = parseInt(s.substr(1 + 0 * d, d), 16);\n g = parseInt(s.substr(1 + 1 * d, d), 16);\n b = parseInt(s.substr(1 + 2 * d, d), 16);\n\n if (hasAlpha) {\n a = parseInt(s.substr(1 + 3 * d, d), 16);\n } else {\n a = 255;\n }\n\n if (d == 1) {\n r = (r << 4) + r;\n g = (g << 4) + g;\n b = (b << 4) + b;\n\n if (hasAlpha) {\n a = (a << 4) + a;\n }\n }\n\n color = [r, g, b, a / 255];\n } else if (s.indexOf(\'rgba(\') == 0) {\n // rgba()\n color = s.slice(5, -1).split(\',\').map(Number);\n normalize(color);\n } else if (s.indexOf(\'rgb(\') == 0) {\n // rgb()\n color = s.slice(4, -1).split(\',\').map(Number);\n color.push(1);\n normalize(color);\n } else {\n asserts_assert(false, 14); // Invalid color\n }\n\n return color;\n}\n/**\n * TODO this function is only used in the test, we probably shouldn\'t export it\n * @param {Color} color Color.\n * @return {Color} Clamped color.\n */\n\n\nfunction normalize(color) {\n color[0] = math_clamp(color[0] + 0.5 | 0, 0, 255);\n color[1] = math_clamp(color[1] + 0.5 | 0, 0, 255);\n color[2] = math_clamp(color[2] + 0.5 | 0, 0, 255);\n color[3] = math_clamp(color[3], 0, 1);\n return color;\n}\n/**\n * @param {Color} color Color.\n * @return {string} String.\n */\n\nfunction color_toString(color) {\n var r = color[0];\n\n if (r != (r | 0)) {\n r = r + 0.5 | 0;\n }\n\n var g = color[1];\n\n if (g != (g | 0)) {\n g = g + 0.5 | 0;\n }\n\n var b = color[2];\n\n if (b != (b | 0)) {\n b = b + 0.5 | 0;\n }\n\n var a = color[3] === undefined ? 1 : color[3];\n return \'rgba(\' + r + \',\' + g + \',\' + b + \',\' + a + \')\';\n}\n/**\n * @param {string} s String.\n * @return {boolean} Whether the string is actually a valid color\n */\n\nfunction isStringColor(s) {\n if (NAMED_COLOR_RE_.test(s)) {\n s = fromNamed(s);\n }\n\n return HEX_COLOR_RE_.test(s) || s.indexOf(\'rgba(\') === 0 || s.indexOf(\'rgb(\') === 0;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconImageCache.js\n/**\n * @module ol/style/IconImageCache\n */\n\n/**\n * @classdesc\n * Singleton class. Available through {@link module:ol/style/IconImageCache~shared}.\n */\n\nvar IconImageCache =\n/** @class */\nfunction () {\n function IconImageCache() {\n /**\n * @type {!Object<string, import("./IconImage.js").default>}\n * @private\n */\n this.cache_ = {};\n /**\n * @type {number}\n * @private\n */\n\n this.cacheSize_ = 0;\n /**\n * @type {number}\n * @private\n */\n\n this.maxCacheSize_ = 32;\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n IconImageCache.prototype.clear = function () {\n this.cache_ = {};\n this.cacheSize_ = 0;\n };\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n IconImageCache.prototype.canExpireCache = function () {\n return this.cacheSize_ > this.maxCacheSize_;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n IconImageCache.prototype.expire = function () {\n if (this.canExpireCache()) {\n var i = 0;\n\n for (var key in this.cache_) {\n var iconImage = this.cache_[key];\n\n if ((i++ & 3) === 0 && !iconImage.hasListener()) {\n delete this.cache_[key];\n --this.cacheSize_;\n }\n }\n }\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @return {import("./IconImage.js").default} Icon image.\n */\n\n\n IconImageCache.prototype.get = function (src, crossOrigin, color) {\n var key = getKey(src, crossOrigin, color);\n return key in this.cache_ ? this.cache_[key] : null;\n };\n /**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @param {import("./IconImage.js").default} iconImage Icon image.\n */\n\n\n IconImageCache.prototype.set = function (src, crossOrigin, color, iconImage) {\n var key = getKey(src, crossOrigin, color);\n this.cache_[key] = iconImage;\n ++this.cacheSize_;\n };\n /**\n * Set the cache size of the icon cache. Default is `32`. Change this value when\n * your map uses more than 32 different icon images and you are not caching icon\n * styles on the application level.\n * @param {number} maxCacheSize Cache max size.\n * @api\n */\n\n\n IconImageCache.prototype.setSize = function (maxCacheSize) {\n this.maxCacheSize_ = maxCacheSize;\n this.expire();\n };\n\n return IconImageCache;\n}();\n/**\n * @param {string} src Src.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../color.js").Color} color Color.\n * @return {string} Cache key.\n */\n\n\nfunction getKey(src, crossOrigin, color) {\n var colorString = color ? asString(color) : \'null\';\n return crossOrigin + \':\' + src + \':\' + colorString;\n}\n\n/* harmony default export */ var style_IconImageCache = ((/* unused pure expression or super */ null && (IconImageCache)));\n/**\n * The {@link module:ol/style/IconImageCache~IconImageCache} for\n * {@link module:ol/style/Icon~Icon} images.\n * @api\n */\n\nvar shared = new IconImageCache();\n;// CONCATENATED MODULE: ./node_modules/ol/events/Event.js\n/**\n * @module ol/events/Event\n */\n\n/**\n * @classdesc\n * Stripped down implementation of the W3C DOM Level 2 Event interface.\n * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.\n *\n * This implementation only provides `type` and `target` properties, and\n * `stopPropagation` and `preventDefault` methods. It is meant as base class\n * for higher level events defined in the library, and works with\n * {@link module:ol/events/Target~Target}.\n */\nvar BaseEvent =\n/** @class */\nfunction () {\n /**\n * @param {string} type Type.\n */\n function BaseEvent(type) {\n /**\n * @type {boolean}\n */\n this.propagationStopped;\n /**\n * The event type.\n * @type {string}\n * @api\n */\n\n this.type = type;\n /**\n * The event target.\n * @type {Object}\n * @api\n */\n\n this.target = null;\n }\n /**\n * Stop event propagation.\n * @api\n */\n\n\n BaseEvent.prototype.preventDefault = function () {\n this.propagationStopped = true;\n };\n /**\n * Stop event propagation.\n * @api\n */\n\n\n BaseEvent.prototype.stopPropagation = function () {\n this.propagationStopped = true;\n };\n\n return BaseEvent;\n}();\n/**\n * @param {Event|import("./Event.js").default} evt Event\n */\n\n\nfunction stopPropagation(evt) {\n evt.stopPropagation();\n}\n/**\n * @param {Event|import("./Event.js").default} evt Event\n */\n\nfunction preventDefault(evt) {\n evt.preventDefault();\n}\n/* harmony default export */ var Event = (BaseEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/ObjectEventType.js\n/**\n * @module ol/ObjectEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var ObjectEventType = ({\n /**\n * Triggered when a property is changed.\n * @event module:ol/Object.ObjectEvent#propertychange\n * @api\n */\n PROPERTYCHANGE: \'propertychange\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/obj.js\n/**\n * @module ol/obj\n */\n\n/**\n * Polyfill for Object.assign(). Assigns enumerable and own properties from\n * one or more source objects to a target object.\n * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.\n *\n * @param {!Object} target The target object.\n * @param {...Object} var_sources The source object(s).\n * @return {!Object} The modified target object.\n */\nvar obj_assign = typeof Object.assign === \'function\' ? Object.assign : function (target, var_sources) {\n if (target === undefined || target === null) {\n throw new TypeError(\'Cannot convert undefined or null to object\');\n }\n\n var output = Object(target);\n\n for (var i = 1, ii = arguments.length; i < ii; ++i) {\n var source = arguments[i];\n\n if (source !== undefined && source !== null) {\n for (var key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n\n return output;\n};\n/**\n * Removes all properties from an object.\n * @param {Object} object The object to clear.\n */\n\nfunction clear(object) {\n for (var property in object) {\n delete object[property];\n }\n}\n/**\n * Polyfill for Object.values(). Get an array of property values from an object.\n * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values\n *\n * @param {!Object<K,V>} object The object from which to get the values.\n * @return {!Array<V>} The property values.\n * @template K,V\n */\n\nvar getValues = typeof Object.values === \'function\' ? Object.values : function (object) {\n var values = [];\n\n for (var property in object) {\n values.push(object[property]);\n }\n\n return values;\n};\n/**\n * Determine if an object has any properties.\n * @param {Object} object The object to check.\n * @return {boolean} The object is empty.\n */\n\nfunction obj_isEmpty(object) {\n var property;\n\n for (property in object) {\n return false;\n }\n\n return !property;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/events/Target.js\nvar Target_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/events/Target\n */\n\n\n\n\n\n\n/**\n * @typedef {EventTarget|Target} EventTargetLike\n */\n\n/**\n * @classdesc\n * A simplified implementation of the W3C DOM Level 2 EventTarget interface.\n * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.\n *\n * There are two important simplifications compared to the specification:\n *\n * 1. The handling of `useCapture` in `addEventListener` and\n * `removeEventListener`. There is no real capture model.\n * 2. The handling of `stopPropagation` and `preventDefault` on `dispatchEvent`.\n * There is no event target hierarchy. When a listener calls\n * `stopPropagation` or `preventDefault` on an event object, it means that no\n * more listeners after this one will be called. Same as when the listener\n * returns false.\n */\n\nvar Target =\n/** @class */\nfunction (_super) {\n Target_extends(Target, _super);\n /**\n * @param {*=} opt_target Default event target for dispatched events.\n */\n\n\n function Target(opt_target) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {*}\n */\n\n\n _this.eventTarget_ = opt_target;\n /**\n * @private\n * @type {Object<string, number>}\n */\n\n _this.pendingRemovals_ = null;\n /**\n * @private\n * @type {Object<string, number>}\n */\n\n _this.dispatching_ = null;\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").Listener>>}\n */\n\n _this.listeners_ = null;\n return _this;\n }\n /**\n * @param {string} type Type.\n * @param {import("../events.js").Listener} listener Listener.\n */\n\n\n Target.prototype.addEventListener = function (type, listener) {\n if (!type || !listener) {\n return;\n }\n\n var listeners = this.listeners_ || (this.listeners_ = {});\n var listenersForType = listeners[type] || (listeners[type] = []);\n\n if (listenersForType.indexOf(listener) === -1) {\n listenersForType.push(listener);\n }\n };\n /**\n * Dispatches an event and calls all listeners listening for events\n * of this type. The event parameter can either be a string or an\n * Object with a `type` property.\n *\n * @param {import("./Event.js").default|string} event Event object.\n * @return {boolean|undefined} `false` if anyone called preventDefault on the\n * event object or if any of the listeners returned false.\n * @api\n */\n\n\n Target.prototype.dispatchEvent = function (event) {\n /** @type {import("./Event.js").default|Event} */\n var evt = typeof event === \'string\' ? new Event(event) : event;\n var type = evt.type;\n\n if (!evt.target) {\n evt.target = this.eventTarget_ || this;\n }\n\n var listeners = this.listeners_ && this.listeners_[type];\n var propagate;\n\n if (listeners) {\n var dispatching = this.dispatching_ || (this.dispatching_ = {});\n var pendingRemovals = this.pendingRemovals_ || (this.pendingRemovals_ = {});\n\n if (!(type in dispatching)) {\n dispatching[type] = 0;\n pendingRemovals[type] = 0;\n }\n\n ++dispatching[type];\n\n for (var i = 0, ii = listeners.length; i < ii; ++i) {\n if (\'handleEvent\' in listeners[i]) {\n propagate =\n /** @type {import("../events.js").ListenerObject} */\n listeners[i].handleEvent(evt);\n } else {\n propagate =\n /** @type {import("../events.js").ListenerFunction} */\n listeners[i].call(this, evt);\n }\n\n if (propagate === false || evt.propagationStopped) {\n propagate = false;\n break;\n }\n }\n\n --dispatching[type];\n\n if (dispatching[type] === 0) {\n var pr = pendingRemovals[type];\n delete pendingRemovals[type];\n\n while (pr--) {\n this.removeEventListener(type, VOID);\n }\n\n delete dispatching[type];\n }\n\n return propagate;\n }\n };\n /**\n * Clean up.\n */\n\n\n Target.prototype.disposeInternal = function () {\n this.listeners_ && clear(this.listeners_);\n };\n /**\n * Get the listeners for a specified event type. Listeners are returned in the\n * order that they will be called in.\n *\n * @param {string} type Type.\n * @return {Array<import("../events.js").Listener>|undefined} Listeners.\n */\n\n\n Target.prototype.getListeners = function (type) {\n return this.listeners_ && this.listeners_[type] || undefined;\n };\n /**\n * @param {string=} opt_type Type. If not provided,\n * `true` will be returned if this event target has any listeners.\n * @return {boolean} Has listeners.\n */\n\n\n Target.prototype.hasListener = function (opt_type) {\n if (!this.listeners_) {\n return false;\n }\n\n return opt_type ? opt_type in this.listeners_ : Object.keys(this.listeners_).length > 0;\n };\n /**\n * @param {string} type Type.\n * @param {import("../events.js").Listener} listener Listener.\n */\n\n\n Target.prototype.removeEventListener = function (type, listener) {\n var listeners = this.listeners_ && this.listeners_[type];\n\n if (listeners) {\n var index = listeners.indexOf(listener);\n\n if (index !== -1) {\n if (this.pendingRemovals_ && type in this.pendingRemovals_) {\n // make listener a no-op, and remove later in #dispatchEvent()\n listeners[index] = VOID;\n ++this.pendingRemovals_[type];\n } else {\n listeners.splice(index, 1);\n\n if (listeners.length === 0) {\n delete this.listeners_[type];\n }\n }\n }\n }\n };\n\n return Target;\n}(ol_Disposable);\n\n/* harmony default export */ var events_Target = (Target);\n;// CONCATENATED MODULE: ./node_modules/ol/events/EventType.js\n/**\n * @module ol/events/EventType\n */\n\n/**\n * @enum {string}\n * @const\n */\n/* harmony default export */ var EventType = ({\n /**\n * Generic change event. Triggered when the revision counter is increased.\n * @event module:ol/events/Event~BaseEvent#change\n * @api\n */\n CHANGE: \'change\',\n\n /**\n * Generic error event. Triggered when an error occurs.\n * @event module:ol/events/Event~BaseEvent#error\n * @api\n */\n ERROR: \'error\',\n BLUR: \'blur\',\n CLEAR: \'clear\',\n CONTEXTMENU: \'contextmenu\',\n CLICK: \'click\',\n DBLCLICK: \'dblclick\',\n DRAGENTER: \'dragenter\',\n DRAGOVER: \'dragover\',\n DROP: \'drop\',\n FOCUS: \'focus\',\n KEYDOWN: \'keydown\',\n KEYPRESS: \'keypress\',\n LOAD: \'load\',\n RESIZE: \'resize\',\n TOUCHMOVE: \'touchmove\',\n WHEEL: \'wheel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/events.js\n/**\n * @module ol/events\n */\n\n/**\n * Key to use with {@link module:ol/Observable~Observable#unByKey}.\n * @typedef {Object} EventsKey\n * @property {ListenerFunction} listener\n * @property {import("./events/Target.js").EventTargetLike} target\n * @property {string} type\n * @api\n */\n\n/**\n * Listener function. This function is called with an event object as argument.\n * When the function returns `false`, event propagation will stop.\n *\n * @typedef {function((Event|import("./events/Event.js").default)): (void|boolean)} ListenerFunction\n * @api\n */\n\n/**\n * @typedef {Object} ListenerObject\n * @property {ListenerFunction} handleEvent\n */\n\n/**\n * @typedef {ListenerFunction|ListenerObject} Listener\n */\n\n/**\n * Registers an event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` to a `this` object, and returns\n * a key for use with {@link module:ol/events~unlistenByKey}.\n *\n * @param {import("./events/Target.js").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @param {boolean=} opt_once If true, add the listener as one-off listener.\n * @return {EventsKey} Unique key for the listener.\n */\n\nfunction listen(target, type, _listener, opt_this, opt_once) {\n if (opt_this && opt_this !== target) {\n _listener = _listener.bind(opt_this);\n }\n\n if (opt_once) {\n var originalListener_1 = _listener;\n\n _listener = function listener() {\n target.removeEventListener(type, _listener);\n originalListener_1.apply(this, arguments);\n };\n }\n\n var eventsKey = {\n target: target,\n type: type,\n listener: _listener\n };\n target.addEventListener(type, _listener);\n return eventsKey;\n}\n/**\n * Registers a one-off event listener on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * This function efficiently binds a `listener` as self-unregistering listener\n * to a `this` object, and returns a key for use with\n * {@link module:ol/events~unlistenByKey} in case the listener needs to be\n * unregistered before it is called.\n *\n * When {@link module:ol/events~listen} is called with the same arguments after this\n * function, the self-unregistering listener will be turned into a permanent\n * listener.\n *\n * @param {import("./events/Target.js").EventTargetLike} target Event target.\n * @param {string} type Event type.\n * @param {ListenerFunction} listener Listener.\n * @param {Object=} opt_this Object referenced by the `this` keyword in the\n * listener. Default is the `target`.\n * @return {EventsKey} Key for unlistenByKey.\n */\n\nfunction listenOnce(target, type, listener, opt_this) {\n return listen(target, type, listener, opt_this, true);\n}\n/**\n * Unregisters event listeners on an event target. Inspired by\n * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html\n *\n * The argument passed to this function is the key returned from\n * {@link module:ol/events~listen} or {@link module:ol/events~listenOnce}.\n *\n * @param {EventsKey} key The key.\n */\n\nfunction unlistenByKey(key) {\n if (key && key.target) {\n key.target.removeEventListener(key.type, key.listener);\n clear(key);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/Observable.js\nvar Observable_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Observable\n */\n\n\n\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * An event target providing convenient methods for listener registration\n * and unregistration. A generic `change` event is always available through\n * {@link module:ol/Observable~Observable#changed}.\n *\n * @fires import("./events/Event.js").default\n * @api\n */\n\nvar Observable =\n/** @class */\nfunction (_super) {\n Observable_extends(Observable, _super);\n\n function Observable() {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number}\n */\n\n\n _this.revision_ = 0;\n return _this;\n }\n /**\n * Increases the revision counter and dispatches a \'change\' event.\n * @api\n */\n\n\n Observable.prototype.changed = function () {\n ++this.revision_;\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Get the version number for this object. Each time the object is modified,\n * its version number will be incremented.\n * @return {number} Revision.\n * @api\n */\n\n\n Observable.prototype.getRevision = function () {\n return this.revision_;\n };\n /**\n * Listen for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\n\n\n Observable.prototype.on = function (type, listener) {\n if (Array.isArray(type)) {\n var len = type.length;\n var keys = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n keys[i] = listen(this, type[i], listener);\n }\n\n return keys;\n } else {\n return listen(this,\n /** @type {string} */\n type, listener);\n }\n };\n /**\n * Listen once for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @return {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} Unique key for the listener. If\n * called with an array of event types as the first argument, the return\n * will be an array of keys.\n * @api\n */\n\n\n Observable.prototype.once = function (type, listener) {\n var key;\n\n if (Array.isArray(type)) {\n var len = type.length;\n key = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n key[i] = listenOnce(this, type[i], listener);\n }\n } else {\n key = listenOnce(this,\n /** @type {string} */\n type, listener);\n }\n /** @type {Object} */\n\n\n listener.ol_key = key;\n return key;\n };\n /**\n * Unlisten for a certain type of event.\n * @param {string|Array<string>} type The event type or array of event types.\n * @param {function(?): ?} listener The listener function.\n * @api\n */\n\n\n Observable.prototype.un = function (type, listener) {\n var key =\n /** @type {Object} */\n listener.ol_key;\n\n if (key) {\n unByKey(key);\n } else if (Array.isArray(type)) {\n for (var i = 0, ii = type.length; i < ii; ++i) {\n this.removeEventListener(type[i], listener);\n }\n } else {\n this.removeEventListener(type, listener);\n }\n };\n\n return Observable;\n}(events_Target);\n/**\n * Removes an event listener using the key returned by `on()` or `once()`.\n * @param {import("./events.js").EventsKey|Array<import("./events.js").EventsKey>} key The key returned by `on()`\n * or `once()` (or an array of keys).\n * @api\n */\n\n\nfunction unByKey(key) {\n if (Array.isArray(key)) {\n for (var i = 0, ii = key.length; i < ii; ++i) {\n unlistenByKey(key[i]);\n }\n } else {\n unlistenByKey(\n /** @type {import("./events.js").EventsKey} */\n key);\n }\n}\n/* harmony default export */ var ol_Observable = (Observable);\n;// CONCATENATED MODULE: ./node_modules/ol/Object.js\nvar Object_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Object\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.\n */\n\nvar ObjectEvent =\n/** @class */\nfunction (_super) {\n Object_extends(ObjectEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {string} key The property name.\n * @param {*} oldValue The old value for `key`.\n */\n\n\n function ObjectEvent(type, key, oldValue) {\n var _this = _super.call(this, type) || this;\n /**\n * The name of the property whose value is changing.\n * @type {string}\n * @api\n */\n\n\n _this.key = key;\n /**\n * The old value. To get the new value use `e.target.get(e.key)` where\n * `e` is the event object.\n * @type {*}\n * @api\n */\n\n _this.oldValue = oldValue;\n return _this;\n }\n\n return ObjectEvent;\n}(Event);\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Most non-trivial classes inherit from this.\n *\n * This extends {@link module:ol/Observable} with observable\n * properties, where each property is observable as well as the object as a\n * whole.\n *\n * Classes that inherit from this have pre-defined properties, to which you can\n * add your owns. The pre-defined properties are listed in this documentation as\n * \'Observable Properties\', and have their own accessors; for example,\n * {@link module:ol/Map~Map} has a `target` property, accessed with\n * `getTarget()` and changed with `setTarget()`. Not all properties are however\n * settable. There are also general-purpose accessors `get()` and `set()`. For\n * example, `get(\'target\')` is equivalent to `getTarget()`.\n *\n * The `set` accessors trigger a change event, and you can monitor this by\n * registering a listener. For example, {@link module:ol/View~View} has a\n * `center` property, so `view.on(\'change:center\', function(evt) {...});` would\n * call the function whenever the value of the center property changes. Within\n * the function, `evt.target` would be the view, so `evt.target.getCenter()`\n * would return the new center.\n *\n * You can add your own observable properties with\n * `object.set(\'prop\', \'value\')`, and retrieve that with `object.get(\'prop\')`.\n * You can listen for changes on that property value with\n * `object.on(\'change:prop\', listener)`. You can get a list of all\n * properties with {@link module:ol/Object~BaseObject#getProperties}.\n *\n * Note that the observable properties are separate from standard JS properties.\n * You can, for example, give your map object a title with\n * `map.title=\'New title\'` and with `map.set(\'title\', \'Another title\')`. The\n * first will be a `hasOwnProperty`; the second will appear in\n * `getProperties()`. Only the second is observable.\n *\n * Properties can be deleted by using the unset method. E.g.\n * object.unset(\'foo\').\n *\n * @fires ObjectEvent\n * @api\n */\n\nvar BaseObject =\n/** @class */\nfunction (_super) {\n Object_extends(BaseObject, _super);\n /**\n * @param {Object<string, *>=} opt_values An object with key-value pairs.\n */\n\n\n function BaseObject(opt_values) {\n var _this = _super.call(this) || this; // Call {@link module:ol/util~getUid} to ensure that the order of objects\' ids is\n // the same as the order in which they were created. This also helps to\n // ensure that object properties are always added in the same order, which\n // helps many JavaScript engines generate faster code.\n\n\n getUid(_this);\n /**\n * @private\n * @type {Object<string, *>}\n */\n\n _this.values_ = null;\n\n if (opt_values !== undefined) {\n _this.setProperties(opt_values);\n }\n\n return _this;\n }\n /**\n * Gets a value.\n * @param {string} key Key name.\n * @return {*} Value.\n * @api\n */\n\n\n BaseObject.prototype.get = function (key) {\n var value;\n\n if (this.values_ && this.values_.hasOwnProperty(key)) {\n value = this.values_[key];\n }\n\n return value;\n };\n /**\n * Get a list of object property names.\n * @return {Array<string>} List of property names.\n * @api\n */\n\n\n BaseObject.prototype.getKeys = function () {\n return this.values_ && Object.keys(this.values_) || [];\n };\n /**\n * Get an object of all property names and values.\n * @return {Object<string, *>} Object.\n * @api\n */\n\n\n BaseObject.prototype.getProperties = function () {\n return this.values_ && obj_assign({}, this.values_) || {};\n };\n /**\n * @return {boolean} The object has properties.\n */\n\n\n BaseObject.prototype.hasProperties = function () {\n return !!this.values_;\n };\n /**\n * @param {string} key Key name.\n * @param {*} oldValue Old value.\n */\n\n\n BaseObject.prototype.notify = function (key, oldValue) {\n var eventType;\n eventType = getChangeEventType(key);\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n eventType = ObjectEventType.PROPERTYCHANGE;\n this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));\n };\n /**\n * Sets a value.\n * @param {string} key Key name.\n * @param {*} value Value.\n * @param {boolean=} opt_silent Update without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.set = function (key, value, opt_silent) {\n var values = this.values_ || (this.values_ = {});\n\n if (opt_silent) {\n values[key] = value;\n } else {\n var oldValue = values[key];\n values[key] = value;\n\n if (oldValue !== value) {\n this.notify(key, oldValue);\n }\n }\n };\n /**\n * Sets a collection of key-value pairs. Note that this changes any existing\n * properties and adds new ones (it does not remove any existing properties).\n * @param {Object<string, *>} values Values.\n * @param {boolean=} opt_silent Update without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.setProperties = function (values, opt_silent) {\n for (var key in values) {\n this.set(key, values[key], opt_silent);\n }\n };\n /**\n * Apply any properties from another object without triggering events.\n * @param {BaseObject} source The source object.\n * @protected\n */\n\n\n BaseObject.prototype.applyProperties = function (source) {\n if (!source.values_) {\n return;\n }\n\n obj_assign(this.values_ || (this.values_ = {}), source.values_);\n };\n /**\n * Unsets a property.\n * @param {string} key Key name.\n * @param {boolean=} opt_silent Unset without triggering an event.\n * @api\n */\n\n\n BaseObject.prototype.unset = function (key, opt_silent) {\n if (this.values_ && key in this.values_) {\n var oldValue = this.values_[key];\n delete this.values_[key];\n\n if (obj_isEmpty(this.values_)) {\n this.values_ = null;\n }\n\n if (!opt_silent) {\n this.notify(key, oldValue);\n }\n }\n };\n\n return BaseObject;\n}(ol_Observable);\n/**\n * @type {Object<string, string>}\n */\n\n\nvar changeEventTypeCache = {};\n/**\n * @param {string} key Key name.\n * @return {string} Change name.\n */\n\nfunction getChangeEventType(key) {\n return changeEventTypeCache.hasOwnProperty(key) ? changeEventTypeCache[key] : changeEventTypeCache[key] = \'change:\' + key;\n}\n/* harmony default export */ var ol_Object = (BaseObject);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Property.js\n/**\n * @module ol/layer/Property\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var Property = ({\n OPACITY: \'opacity\',\n VISIBLE: \'visible\',\n EXTENT: \'extent\',\n Z_INDEX: \'zIndex\',\n MAX_RESOLUTION: \'maxResolution\',\n MIN_RESOLUTION: \'minResolution\',\n MAX_ZOOM: \'maxZoom\',\n MIN_ZOOM: \'minZoom\',\n SOURCE: \'source\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Base.js\nvar Base_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Base\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Note that with {@link module:ol/layer/Base} and all its subclasses, any property set in\n * the options is set as a {@link module:ol/Object} property on the layer object, so\n * is observable, and has get/set accessors.\n *\n * @api\n */\n\nvar BaseLayer =\n/** @class */\nfunction (_super) {\n Base_extends(BaseLayer, _super);\n /**\n * @param {Options} options Layer options.\n */\n\n\n function BaseLayer(options) {\n var _this = _super.call(this) || this;\n /**\n * @type {Object<string, *>}\n */\n\n\n var properties = obj_assign({}, options);\n properties[Property.OPACITY] = options.opacity !== undefined ? options.opacity : 1;\n asserts_assert(typeof properties[Property.OPACITY] === \'number\', 64); // Layer opacity must be a number\n\n properties[Property.VISIBLE] = options.visible !== undefined ? options.visible : true;\n properties[Property.Z_INDEX] = options.zIndex;\n properties[Property.MAX_RESOLUTION] = options.maxResolution !== undefined ? options.maxResolution : Infinity;\n properties[Property.MIN_RESOLUTION] = options.minResolution !== undefined ? options.minResolution : 0;\n properties[Property.MIN_ZOOM] = options.minZoom !== undefined ? options.minZoom : -Infinity;\n properties[Property.MAX_ZOOM] = options.maxZoom !== undefined ? options.maxZoom : Infinity;\n /**\n * @type {string}\n * @private\n */\n\n _this.className_ = properties.className !== undefined ? options.className : \'ol-layer\';\n delete properties.className;\n\n _this.setProperties(properties);\n /**\n * @type {import("./Layer.js").State}\n * @private\n */\n\n\n _this.state_ = null;\n return _this;\n }\n /**\n * @return {string} CSS class name.\n */\n\n\n BaseLayer.prototype.getClassName = function () {\n return this.className_;\n };\n /**\n * This method is not meant to be called by layers or layer renderers because the state\n * is incorrect if the layer is included in a layer group.\n *\n * @param {boolean=} opt_managed Layer is managed.\n * @return {import("./Layer.js").State} Layer state.\n */\n\n\n BaseLayer.prototype.getLayerState = function (opt_managed) {\n /** @type {import("./Layer.js").State} */\n var state = this.state_ ||\n /** @type {?} */\n {\n layer: this,\n managed: opt_managed === undefined ? true : opt_managed\n };\n var zIndex = this.getZIndex();\n state.opacity = math_clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);\n state.sourceState = this.getSourceState();\n state.visible = this.getVisible();\n state.extent = this.getExtent();\n state.zIndex = zIndex !== undefined ? zIndex : state.managed === false ? Infinity : 0;\n state.maxResolution = this.getMaxResolution();\n state.minResolution = Math.max(this.getMinResolution(), 0);\n state.minZoom = this.getMinZoom();\n state.maxZoom = this.getMaxZoom();\n this.state_ = state;\n return state;\n };\n /**\n * @abstract\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be\n * modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n BaseLayer.prototype.getLayersArray = function (opt_array) {\n return util_abstract();\n };\n /**\n * @abstract\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer\n * states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n BaseLayer.prototype.getLayerStatesArray = function (opt_states) {\n return util_abstract();\n };\n /**\n * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it\n * will be visible regardless of extent.\n * @return {import("../extent.js").Extent|undefined} The layer extent.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getExtent = function () {\n return (\n /** @type {import("../extent.js").Extent|undefined} */\n this.get(Property.EXTENT)\n );\n };\n /**\n * Return the maximum resolution of the layer.\n * @return {number} The maximum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMaxResolution = function () {\n return (\n /** @type {number} */\n this.get(Property.MAX_RESOLUTION)\n );\n };\n /**\n * Return the minimum resolution of the layer.\n * @return {number} The minimum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMinResolution = function () {\n return (\n /** @type {number} */\n this.get(Property.MIN_RESOLUTION)\n );\n };\n /**\n * Return the minimum zoom level of the layer.\n * @return {number} The minimum zoom level of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMinZoom = function () {\n return (\n /** @type {number} */\n this.get(Property.MIN_ZOOM)\n );\n };\n /**\n * Return the maximum zoom level of the layer.\n * @return {number} The maximum zoom level of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getMaxZoom = function () {\n return (\n /** @type {number} */\n this.get(Property.MAX_ZOOM)\n );\n };\n /**\n * Return the opacity of the layer (between 0 and 1).\n * @return {number} The opacity of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getOpacity = function () {\n return (\n /** @type {number} */\n this.get(Property.OPACITY)\n );\n };\n /**\n * @abstract\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n BaseLayer.prototype.getSourceState = function () {\n return util_abstract();\n };\n /**\n * Return the visibility of the layer (`true` or `false`).\n * @return {boolean} The visibility of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getVisible = function () {\n return (\n /** @type {boolean} */\n this.get(Property.VISIBLE)\n );\n };\n /**\n * Return the Z-index of the layer, which is used to order layers before\n * rendering. The default Z-index is 0.\n * @return {number} The Z-index of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.getZIndex = function () {\n return (\n /** @type {number} */\n this.get(Property.Z_INDEX)\n );\n };\n /**\n * Set the extent at which the layer is visible. If `undefined`, the layer\n * will be visible at all extents.\n * @param {import("../extent.js").Extent|undefined} extent The extent of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setExtent = function (extent) {\n this.set(Property.EXTENT, extent);\n };\n /**\n * Set the maximum resolution at which the layer is visible.\n * @param {number} maxResolution The maximum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMaxResolution = function (maxResolution) {\n this.set(Property.MAX_RESOLUTION, maxResolution);\n };\n /**\n * Set the minimum resolution at which the layer is visible.\n * @param {number} minResolution The minimum resolution of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMinResolution = function (minResolution) {\n this.set(Property.MIN_RESOLUTION, minResolution);\n };\n /**\n * Set the maximum zoom (exclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} maxZoom The maximum zoom of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMaxZoom = function (maxZoom) {\n this.set(Property.MAX_ZOOM, maxZoom);\n };\n /**\n * Set the minimum zoom (inclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} minZoom The minimum zoom of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setMinZoom = function (minZoom) {\n this.set(Property.MIN_ZOOM, minZoom);\n };\n /**\n * Set the opacity of the layer, allowed values range from 0 to 1.\n * @param {number} opacity The opacity of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setOpacity = function (opacity) {\n asserts_assert(typeof opacity === \'number\', 64); // Layer opacity must be a number\n\n this.set(Property.OPACITY, opacity);\n };\n /**\n * Set the visibility of the layer (`true` or `false`).\n * @param {boolean} visible The visibility of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setVisible = function (visible) {\n this.set(Property.VISIBLE, visible);\n };\n /**\n * Set Z-index of the layer, which is used to order layers before rendering.\n * The default Z-index is 0.\n * @param {number} zindex The z-index of the layer.\n * @observable\n * @api\n */\n\n\n BaseLayer.prototype.setZIndex = function (zindex) {\n this.set(Property.Z_INDEX, zindex);\n };\n /**\n * Clean up.\n */\n\n\n BaseLayer.prototype.disposeInternal = function () {\n if (this.state_) {\n this.state_.layer = null;\n this.state_ = null;\n }\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return BaseLayer;\n}(ol_Object);\n\n/* harmony default export */ var Base = (BaseLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/EventType.js\n/**\n * @module ol/render/EventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var render_EventType = ({\n /**\n * Triggered before a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#prerender\n * @api\n */\n PRERENDER: \'prerender\',\n\n /**\n * Triggered after a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#postrender\n * @api\n */\n POSTRENDER: \'postrender\',\n\n /**\n * Triggered before layers are rendered.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#precompose\n * @api\n */\n PRECOMPOSE: \'precompose\',\n\n /**\n * Triggered after all layers are rendered.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#postcompose\n * @api\n */\n POSTCOMPOSE: \'postcompose\',\n\n /**\n * Triggered when rendering is complete, i.e. all sources and tiles have\n * finished loading for the current viewport, and all tiles are faded in.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#rendercomplete\n * @api\n */\n RENDERCOMPLETE: \'rendercomplete\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/source/State.js\n/**\n * @module ol/source/State\n */\n\n/**\n * @enum {string}\n * State of the source, one of \'undefined\', \'loading\', \'ready\' or \'error\'.\n */\n/* harmony default export */ var State = ({\n UNDEFINED: \'undefined\',\n LOADING: \'loading\',\n READY: \'ready\',\n ERROR: \'error\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Layer.js\nvar Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Layer\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {function(import("../PluggableMap.js").FrameState):HTMLElement} RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../source/Source.js").default} [source] Source for this layer. If not provided to the constructor,\n * the source can be set by calling {@link module:ol/layer/Layer#setSource layer.setSource(source)} after\n * construction.\n * @property {import("../PluggableMap.js").default} [map] Map.\n * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an\n * HTML element. Will overwrite the default rendering for the layer.\n */\n\n/**\n * @typedef {Object} State\n * @property {import("./Layer.js").default} layer\n * @property {number} opacity Opacity, the value is rounded to two digits to appear after the decimal point.\n * @property {import("../source/State.js").default} sourceState\n * @property {boolean} visible\n * @property {boolean} managed\n * @property {import("../extent.js").Extent} [extent]\n * @property {number} zIndex\n * @property {number} maxResolution\n * @property {number} minResolution\n * @property {number} minZoom\n * @property {number} maxZoom\n */\n\n/**\n * @classdesc\n * Base class from which all layer types are derived. This should only be instantiated\n * in the case where a custom layer is be added to the map with a custom `render` function.\n * Such a function can be specified in the `options` object, and is expected to return an HTML element.\n *\n * A visual representation of raster or vector map data.\n * Layers group together those properties that pertain to how the data is to be\n * displayed, irrespective of the source of that data.\n *\n * Layers are usually added to a map with {@link module:ol/Map#addLayer}. Components\n * like {@link module:ol/interaction/Select~Select} use unmanaged layers\n * internally. These unmanaged layers are associated with the map using\n * {@link module:ol/layer/Layer~Layer#setMap} instead.\n *\n * A generic `change` event is fired when the state of the source changes.\n *\n * Please note that for performance reasons several layers might get rendered to\n * the same HTML element, which will cause {@link module:ol/Map~Map#forEachLayerAtPixel} to\n * give false positives. To avoid this, apply different `className` properties to the\n * layers at creation time.\n *\n * @fires import("../render/Event.js").RenderEvent#prerender\n * @fires import("../render/Event.js").RenderEvent#postrender\n *\n * @template {import("../source/Source.js").default} SourceType\n * @api\n */\n\nvar Layer =\n/** @class */\nfunction (_super) {\n Layer_extends(Layer, _super);\n /**\n * @param {Options} options Layer options.\n */\n\n\n function Layer(options) {\n var _this = this;\n\n var baseOptions = obj_assign({}, options);\n delete baseOptions.source;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.mapPrecomposeKey_ = null;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.mapRenderKey_ = null;\n /**\n * @private\n * @type {?import("../events.js").EventsKey}\n */\n\n _this.sourceChangeKey_ = null;\n /**\n * @private\n * @type {import("../renderer/Layer.js").default}\n */\n\n _this.renderer_ = null; // Overwrite default render method with a custom one\n\n if (options.render) {\n _this.render = options.render;\n }\n\n if (options.map) {\n _this.setMap(options.map);\n }\n\n _this.addEventListener(getChangeEventType(Property.SOURCE), _this.handleSourcePropertyChange_);\n\n var source = options.source ?\n /** @type {SourceType} */\n options.source : null;\n\n _this.setSource(source);\n\n return _this;\n }\n /**\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n Layer.prototype.getLayersArray = function (opt_array) {\n var array = opt_array ? opt_array : [];\n array.push(this);\n return array;\n };\n /**\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n Layer.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states ? opt_states : [];\n states.push(this.getLayerState());\n return states;\n };\n /**\n * Get the layer source.\n * @return {SourceType} The layer source (or `null` if not yet set).\n * @observable\n * @api\n */\n\n\n Layer.prototype.getSource = function () {\n return (\n /** @type {SourceType} */\n this.get(Property.SOURCE) || null\n );\n };\n /**\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n Layer.prototype.getSourceState = function () {\n var source = this.getSource();\n return !source ? State.UNDEFINED : source.getState();\n };\n /**\n * @private\n */\n\n\n Layer.prototype.handleSourceChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n\n\n Layer.prototype.handleSourcePropertyChange_ = function () {\n if (this.sourceChangeKey_) {\n unlistenByKey(this.sourceChangeKey_);\n this.sourceChangeKey_ = null;\n }\n\n var source = this.getSource();\n\n if (source) {\n this.sourceChangeKey_ = listen(source, EventType.CHANGE, this.handleSourceChange_, this);\n }\n\n this.changed();\n };\n /**\n * @param {import("../pixel").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with\n * an array of features.\n */\n\n\n Layer.prototype.getFeatures = function (pixel) {\n return this.renderer_.getFeatures(pixel);\n };\n /**\n * In charge to manage the rendering of the layer. One layer type is\n * bounded with one layer renderer.\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target which the renderer may (but need not) use\n * for rendering its content.\n * @return {HTMLElement} The rendered element.\n */\n\n\n Layer.prototype.render = function (frameState, target) {\n var layerRenderer = this.getRenderer();\n\n if (layerRenderer.prepareFrame(frameState)) {\n return layerRenderer.renderFrame(frameState, target);\n }\n };\n /**\n * Sets the layer to be rendered on top of other layers on a map. The map will\n * not manage this layer in its layers collection, and the callback in\n * {@link module:ol/Map#forEachLayerAtPixel} will receive `null` as layer. This\n * is useful for temporary layers. To remove an unmanaged layer from the map,\n * use `#setMap(null)`.\n *\n * To add the layer to a map and have it managed by the map, use\n * {@link module:ol/Map#addLayer} instead.\n * @param {import("../PluggableMap.js").default} map Map.\n * @api\n */\n\n\n Layer.prototype.setMap = function (map) {\n if (this.mapPrecomposeKey_) {\n unlistenByKey(this.mapPrecomposeKey_);\n this.mapPrecomposeKey_ = null;\n }\n\n if (!map) {\n this.changed();\n }\n\n if (this.mapRenderKey_) {\n unlistenByKey(this.mapRenderKey_);\n this.mapRenderKey_ = null;\n }\n\n if (map) {\n this.mapPrecomposeKey_ = listen(map, render_EventType.PRECOMPOSE, function (evt) {\n var renderEvent =\n /** @type {import("../render/Event.js").default} */\n evt;\n var layerStatesArray = renderEvent.frameState.layerStatesArray;\n var layerState = this.getLayerState(false); // A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both.\n\n asserts_assert(!layerStatesArray.some(function (arrayLayerState) {\n return arrayLayerState.layer === layerState.layer;\n }), 67);\n layerStatesArray.push(layerState);\n }, this);\n this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);\n this.changed();\n }\n };\n /**\n * Set the layer source.\n * @param {SourceType} source The layer source.\n * @observable\n * @api\n */\n\n\n Layer.prototype.setSource = function (source) {\n this.set(Property.SOURCE, source);\n };\n /**\n * Get the renderer for this layer.\n * @return {import("../renderer/Layer.js").default} The layer renderer.\n */\n\n\n Layer.prototype.getRenderer = function () {\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n\n return this.renderer_;\n };\n /**\n * @return {boolean} The layer has a renderer.\n */\n\n\n Layer.prototype.hasRenderer = function () {\n return !!this.renderer_;\n };\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n Layer.prototype.createRenderer = function () {\n return null;\n };\n /**\n * Clean up.\n */\n\n\n Layer.prototype.disposeInternal = function () {\n this.setSource(null);\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return Layer;\n}(Base);\n/**\n * Return `true` if the layer is visible and if the provided view state\n * has resolution and zoom levels that are in range of the layer\'s min/max.\n * @param {State} layerState Layer state.\n * @param {import("../View.js").State} viewState View state.\n * @return {boolean} The layer is visible at the given view state.\n */\n\n\nfunction inView(layerState, viewState) {\n if (!layerState.visible) {\n return false;\n }\n\n var resolution = viewState.resolution;\n\n if (resolution < layerState.minResolution || resolution >= layerState.maxResolution) {\n return false;\n }\n\n var zoom = viewState.zoom;\n return zoom > layerState.minZoom && zoom <= layerState.maxZoom;\n}\n/* harmony default export */ var layer_Layer = (Layer);\n;// CONCATENATED MODULE: ./node_modules/ol/coordinate.js\n/**\n * @module ol/coordinate\n */\n\n\n\n/**\n * An array of numbers representing an xy coordinate. Example: `[16, 48]`.\n * @typedef {Array<number>} Coordinate\n * @api\n */\n\n/**\n * A function that takes a {@link module:ol/coordinate~Coordinate} and\n * transforms it into a `{string}`.\n *\n * @typedef {function((Coordinate|undefined)): string} CoordinateFormat\n * @api\n */\n\n/**\n * Add `delta` to `coordinate`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {add} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * add(coord, [-2, 4]);\n * // coord is now [5.85, 51.983333]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {Coordinate} delta Delta.\n * @return {Coordinate} The input coordinate adjusted by\n * the given delta.\n * @api\n */\n\nfunction add(coordinate, delta) {\n coordinate[0] += +delta[0];\n coordinate[1] += +delta[1];\n return coordinate;\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed circle.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {import("./geom/Circle.js").default} circle The circle.\n * @return {Coordinate} Closest point on the circumference.\n */\n\nfunction closestOnCircle(coordinate, circle) {\n var r = circle.getRadius();\n var center = circle.getCenter();\n var x0 = center[0];\n var y0 = center[1];\n var x1 = coordinate[0];\n var y1 = coordinate[1];\n var dx = x1 - x0;\n var dy = y1 - y0;\n\n if (dx === 0 && dy === 0) {\n dx = 1;\n }\n\n var d = Math.sqrt(dx * dx + dy * dy);\n var x = x0 + r * dx / d;\n var y = y0 + r * dy / d;\n return [x, y];\n}\n/**\n * Calculates the point closest to the passed coordinate on the passed segment.\n * This is the foot of the perpendicular of the coordinate to the segment when\n * the foot is on the segment, or the closest segment coordinate when the foot\n * is outside the segment.\n *\n * @param {Coordinate} coordinate The coordinate.\n * @param {Array<Coordinate>} segment The two coordinates\n * of the segment.\n * @return {Coordinate} The foot of the perpendicular of\n * the coordinate to the segment.\n */\n\nfunction closestOnSegment(coordinate, segment) {\n var x0 = coordinate[0];\n var y0 = coordinate[1];\n var start = segment[0];\n var end = segment[1];\n var x1 = start[0];\n var y1 = start[1];\n var x2 = end[0];\n var y2 = end[1];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var along = dx === 0 && dy === 0 ? 0 : (dx * (x0 - x1) + dy * (y0 - y1)) / (dx * dx + dy * dy || 0);\n var x, y;\n\n if (along <= 0) {\n x = x1;\n y = y1;\n } else if (along >= 1) {\n x = x2;\n y = y2;\n } else {\n x = x1 + along * dx;\n y = y1 + along * dy;\n }\n\n return [x, y];\n}\n/**\n * Returns a {@link module:ol/coordinate~CoordinateFormat} function that can be\n * used to format\n * a {Coordinate} to a string.\n *\n * Example without specifying the fractional digits:\n *\n * import {createStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY();\n * var out = stringifyFunc(coord);\n * // out is now \'8, 48\'\n *\n * Example with explicitly specifying 2 fractional digits:\n *\n * import {createStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var stringifyFunc = createStringXY(2);\n * var out = stringifyFunc(coord);\n * // out is now \'7.85, 47.98\'\n *\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {CoordinateFormat} Coordinate format.\n * @api\n */\n\nfunction createStringXY(opt_fractionDigits) {\n return (\n /**\n * @param {Coordinate} coordinate Coordinate.\n * @return {string} String XY.\n */\n function (coordinate) {\n return toStringXY(coordinate, opt_fractionDigits);\n }\n );\n}\n/**\n * @param {string} hemispheres Hemispheres.\n * @param {number} degrees Degrees.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} String.\n */\n\nfunction degreesToStringHDMS(hemispheres, degrees, opt_fractionDigits) {\n var normalizedDegrees = modulo(degrees + 180, 360) - 180;\n var x = Math.abs(3600 * normalizedDegrees);\n var dflPrecision = opt_fractionDigits || 0;\n var precision = Math.pow(10, dflPrecision);\n var deg = Math.floor(x / 3600);\n var min = Math.floor((x - deg * 3600) / 60);\n var sec = x - deg * 3600 - min * 60;\n sec = Math.ceil(sec * precision) / precision;\n\n if (sec >= 60) {\n sec = 0;\n min += 1;\n }\n\n if (min >= 60) {\n min = 0;\n deg += 1;\n }\n\n return deg + "\\xB0 " + padNumber(min, 2) + "\\u2032 " + padNumber(sec, 2, dflPrecision) + "\\u2033" + (normalizedDegrees == 0 ? \'\' : \' \' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0));\n}\n/**\n * Transforms the given {@link module:ol/coordinate~Coordinate} to a string\n * using the given string template. The strings `{x}` and `{y}` in the template\n * will be replaced with the first and second coordinate values respectively.\n *\n * Example without specifying the fractional digits:\n *\n * import {format} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var template = \'Coordinate is ({x}|{y}).\';\n * var out = format(coord, template);\n * // out is now \'Coordinate is (8|48).\'\n *\n * Example explicitly specifying the fractional digits:\n *\n * import {format} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var template = \'Coordinate is ({x}|{y}).\';\n * var out = format(coord, template, 2);\n * // out is now \'Coordinate is (7.85|47.98).\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {string} template A template string with `{x}` and `{y}` placeholders\n * that will be replaced by first and second coordinate values.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Formatted coordinate.\n * @api\n */\n\nfunction format(coordinate, template, opt_fractionDigits) {\n if (coordinate) {\n return template.replace(\'{x}\', coordinate[0].toFixed(opt_fractionDigits)).replace(\'{y}\', coordinate[1].toFixed(opt_fractionDigits));\n } else {\n return \'\';\n }\n}\n/**\n * @param {Coordinate} coordinate1 First coordinate.\n * @param {Coordinate} coordinate2 Second coordinate.\n * @return {boolean} The two coordinates are equal.\n */\n\nfunction coordinate_equals(coordinate1, coordinate2) {\n var equals = true;\n\n for (var i = coordinate1.length - 1; i >= 0; --i) {\n if (coordinate1[i] != coordinate2[i]) {\n equals = false;\n break;\n }\n }\n\n return equals;\n}\n/**\n * Rotate `coordinate` by `angle`. `coordinate` is modified in place and\n * returned by the function.\n *\n * Example:\n *\n * import {rotate} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var rotateRadians = Math.PI / 2; // 90 degrees\n * rotate(coord, rotateRadians);\n * // coord is now [-47.983333, 7.85]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} angle Angle in radian.\n * @return {Coordinate} Coordinate.\n * @api\n */\n\nfunction coordinate_rotate(coordinate, angle) {\n var cosAngle = Math.cos(angle);\n var sinAngle = Math.sin(angle);\n var x = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var y = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n coordinate[0] = x;\n coordinate[1] = y;\n return coordinate;\n}\n/**\n * Scale `coordinate` by `scale`. `coordinate` is modified in place and returned\n * by the function.\n *\n * Example:\n *\n * import {scale as scaleCoordinate} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var scale = 1.2;\n * scaleCoordinate(coord, scale);\n * // coord is now [9.42, 57.5799996]\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number} scale Scale factor.\n * @return {Coordinate} Coordinate.\n */\n\nfunction coordinate_scale(coordinate, scale) {\n coordinate[0] *= scale;\n coordinate[1] *= scale;\n return coordinate;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Squared distance between coord1 and coord2.\n */\n\nfunction coordinate_squaredDistance(coord1, coord2) {\n var dx = coord1[0] - coord2[0];\n var dy = coord1[1] - coord2[1];\n return dx * dx + dy * dy;\n}\n/**\n * @param {Coordinate} coord1 First coordinate.\n * @param {Coordinate} coord2 Second coordinate.\n * @return {number} Distance between coord1 and coord2.\n */\n\nfunction distance(coord1, coord2) {\n return Math.sqrt(coordinate_squaredDistance(coord1, coord2));\n}\n/**\n * Calculate the squared distance from a coordinate to a line segment.\n *\n * @param {Coordinate} coordinate Coordinate of the point.\n * @param {Array<Coordinate>} segment Line segment (2\n * coordinates).\n * @return {number} Squared distance from the point to the line segment.\n */\n\nfunction squaredDistanceToSegment(coordinate, segment) {\n return coordinate_squaredDistance(coordinate, closestOnSegment(coordinate, segment));\n}\n/**\n * Format a geographic coordinate with the hemisphere, degrees, minutes, and\n * seconds.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringHDMS} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord);\n * // out is now \'47° 58′ 60″ N 7° 50′ 60″ E\'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringHDMS} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringHDMS(coord, 1);\n * // out is now \'47° 58′ 60.0″ N 7° 50′ 60.0″ E\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} Hemisphere, degrees, minutes and seconds.\n * @api\n */\n\nfunction toStringHDMS(coordinate, opt_fractionDigits) {\n if (coordinate) {\n return degreesToStringHDMS(\'NS\', coordinate[1], opt_fractionDigits) + \' \' + degreesToStringHDMS(\'EW\', coordinate[0], opt_fractionDigits);\n } else {\n return \'\';\n }\n}\n/**\n * Format a coordinate as a comma delimited string.\n *\n * Example without specifying fractional digits:\n *\n * import {toStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord);\n * // out is now \'8, 48\'\n *\n * Example explicitly specifying 1 fractional digit:\n *\n * import {toStringXY} from \'ol/coordinate\';\n *\n * var coord = [7.85, 47.983333];\n * var out = toStringXY(coord, 1);\n * // out is now \'7.8, 48.0\'\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {number=} opt_fractionDigits The number of digits to include\n * after the decimal point. Default is `0`.\n * @return {string} XY.\n * @api\n */\n\nfunction toStringXY(coordinate, opt_fractionDigits) {\n return format(coordinate, \'{x}, {y}\', opt_fractionDigits);\n}\n/**\n * Modifies the provided coordinate in-place to be within the real world\n * extent. The lower projection extent boundary is inclusive, the upper one\n * exclusive.\n *\n * @param {Coordinate} coordinate Coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {Coordinate} The coordinate within the real world extent.\n */\n\nfunction coordinate_wrapX(coordinate, projection) {\n if (projection.canWrapX()) {\n var worldWidth = extent_getWidth(projection.getExtent());\n var worldsAway = coordinate_getWorldsAway(coordinate, projection, worldWidth);\n\n if (worldsAway) {\n coordinate[0] -= worldsAway * worldWidth;\n }\n }\n\n return coordinate;\n}\n/**\n * @param {Coordinate} coordinate Coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {number=} opt_sourceExtentWidth Width of the source extent.\n * @return {number} Offset in world widths.\n */\n\nfunction coordinate_getWorldsAway(coordinate, projection, opt_sourceExtentWidth) {\n var projectionExtent = projection.getExtent();\n var worldsAway = 0;\n\n if (projection.canWrapX() && (coordinate[0] < projectionExtent[0] || coordinate[0] > projectionExtent[2])) {\n var sourceExtentWidth = opt_sourceExtentWidth || extent_getWidth(projectionExtent);\n worldsAway = Math.floor((coordinate[0] - projectionExtent[0]) / sourceExtentWidth);\n }\n\n return worldsAway;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Map.js\nvar Map_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Map\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef HitMatch\n * @property {import("../Feature.js").FeatureLike} feature\n * @property {import("../layer/Layer.js").default} layer\n * @property {import("../geom/SimpleGeometry.js").default} geometry\n * @property {number} distanceSq\n * @property {import("./vector.js").FeatureCallback<T>} callback\n * @template T\n */\n\n/**\n * @abstract\n */\n\nvar MapRenderer =\n/** @class */\nfunction (_super) {\n Map_extends(MapRenderer, _super);\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n function MapRenderer(map) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n\n _this.map_ = map;\n return _this;\n }\n /**\n * @abstract\n * @param {import("../render/EventType.js").default} type Event type.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n MapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n util_abstract();\n };\n /**\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @protected\n */\n\n\n MapRenderer.prototype.calculateMatrices2D = function (frameState) {\n var viewState = frameState.viewState;\n var coordinateToPixelTransform = frameState.coordinateToPixelTransform;\n var pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;\n compose(coordinateToPixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / viewState.resolution, -1 / viewState.resolution, -viewState.rotation, -viewState.center[0], -viewState.center[1]);\n makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);\n };\n /**\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {S} thisArg Value to use as `this` when executing `callback`.\n * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n * @return {T|undefined} Callback result.\n * @template S,T,U\n */\n\n\n MapRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, callback, thisArg, layerFilter, thisArg2) {\n var result;\n var viewState = frameState.viewState;\n /**\n * @param {boolean} managed Managed layer.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../layer/Layer.js").default} layer Layer.\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n\n function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {\n return callback.call(thisArg, feature, managed ? layer : null, geometry);\n }\n\n var projection = viewState.projection;\n var translatedCoordinate = coordinate_wrapX(coordinate.slice(), projection);\n var offsets = [[0, 0]];\n\n if (projection.canWrapX() && checkWrapped) {\n var projectionExtent = projection.getExtent();\n var worldWidth = extent_getWidth(projectionExtent);\n offsets.push([-worldWidth, 0], [worldWidth, 0]);\n }\n\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n var matches =\n /** @type {Array<HitMatch<T>>} */\n [];\n var tmpCoord = [];\n\n for (var i = 0; i < offsets.length; i++) {\n for (var j = numLayers - 1; j >= 0; --j) {\n var layerState = layerStates[j];\n var layer = layerState.layer;\n\n if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter.call(thisArg2, layer)) {\n var layerRenderer = layer.getRenderer();\n var source = layer.getSource();\n\n if (layerRenderer && source) {\n var coordinates = source.getWrapX() ? translatedCoordinate : coordinate;\n var callback_1 = forEachFeatureAtCoordinate.bind(null, layerState.managed);\n tmpCoord[0] = coordinates[0] + offsets[i][0];\n tmpCoord[1] = coordinates[1] + offsets[i][1];\n result = layerRenderer.forEachFeatureAtCoordinate(tmpCoord, frameState, hitTolerance, callback_1, matches);\n }\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n if (matches.length === 0) {\n return undefined;\n }\n\n var order = 1 / matches.length;\n matches.forEach(function (m, i) {\n return m.distanceSq += i * order;\n });\n matches.sort(function (a, b) {\n return a.distanceSq - b.distanceSq;\n });\n matches.some(function (m) {\n return result = m.callback(m.feature, m.layer, m.geometry);\n });\n return result;\n };\n /**\n * @abstract\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n MapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n return util_abstract();\n };\n /**\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg Value to use as `this` when executing `layerFilter`.\n * @return {boolean} Is there a feature at the given coordinate?\n * @template U\n */\n\n\n MapRenderer.prototype.hasFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, checkWrapped, layerFilter, thisArg) {\n var hasFeature = this.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, checkWrapped, TRUE, this, layerFilter, thisArg);\n return hasFeature !== undefined;\n };\n /**\n * @return {import("../PluggableMap.js").default} Map.\n */\n\n\n MapRenderer.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Render.\n * @abstract\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n MapRenderer.prototype.renderFrame = function (frameState) {\n util_abstract();\n };\n /**\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n MapRenderer.prototype.scheduleExpireIconCache = function (frameState) {\n if (shared.canExpireCache()) {\n frameState.postRenderFunctions.push(expireIconCache);\n }\n };\n\n return MapRenderer;\n}(ol_Disposable);\n/**\n * @param {import("../PluggableMap.js").default} map Map.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\nfunction expireIconCache(map, frameState) {\n shared.expire();\n}\n\n/* harmony default export */ var renderer_Map = (MapRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/Event.js\n/**\n * @module ol/render/Event\n */\nvar Event_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\nvar RenderEvent =\n/** @class */\nfunction (_super) {\n Event_extends(RenderEvent, _super);\n /**\n * @param {import("./EventType.js").default} type Type.\n * @param {import("../transform.js").Transform=} opt_inversePixelTransform Transform for\n * CSS pixels to rendered pixels.\n * @param {import("../PluggableMap.js").FrameState=} opt_frameState Frame state.\n * @param {?CanvasRenderingContext2D=} opt_context Context.\n */\n\n\n function RenderEvent(type, opt_inversePixelTransform, opt_frameState, opt_context) {\n var _this = _super.call(this, type) || this;\n /**\n * Transform from CSS pixels (relative to the top-left corner of the map viewport)\n * to rendered pixels on this event\'s `context`. Only available when a Canvas renderer is used, null otherwise.\n * @type {import("../transform.js").Transform|undefined}\n * @api\n */\n\n\n _this.inversePixelTransform = opt_inversePixelTransform;\n /**\n * An object representing the current render frame state.\n * @type {import("../PluggableMap.js").FrameState|undefined}\n * @api\n */\n\n _this.frameState = opt_frameState;\n /**\n * Canvas context. Not available when the event is dispatched by the map. Only available\n * when a Canvas renderer is used, null otherwise.\n * @type {CanvasRenderingContext2D|null|undefined}\n * @api\n */\n\n _this.context = opt_context;\n return _this;\n }\n\n return RenderEvent;\n}(Event);\n\n/* harmony default export */ var render_Event = (RenderEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/css.js\n/**\n * @module ol/css\n */\n\n/**\n * @typedef {Object} FontParameters\n * @property {string} style\n * @property {string} variant\n * @property {string} weight\n * @property {string} size\n * @property {string} lineHeight\n * @property {string} family\n * @property {Array<string>} families\n */\n\n/**\n * The CSS class for hidden feature.\n *\n * @const\n * @type {string}\n */\nvar CLASS_HIDDEN = \'ol-hidden\';\n/**\n * The CSS class that we\'ll give the DOM elements to have them selectable.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_SELECTABLE = \'ol-selectable\';\n/**\n * The CSS class that we\'ll give the DOM elements to have them unselectable.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_UNSELECTABLE = \'ol-unselectable\';\n/**\n * The CSS class for unsupported feature.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_UNSUPPORTED = \'ol-unsupported\';\n/**\n * The CSS class for controls.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_CONTROL = \'ol-control\';\n/**\n * The CSS class that we\'ll give the DOM elements that are collapsed, i.e.\n * to those elements which usually can be expanded.\n *\n * @const\n * @type {string}\n */\n\nvar CLASS_COLLAPSED = \'ol-collapsed\';\n/**\n * From http://stackoverflow.com/questions/10135697/regex-to-parse-any-css-font\n * @type {RegExp}\n */\n\nvar fontRegEx = new RegExp([\'^\\\\s*(?=(?:(?:[-a-z]+\\\\s*){0,2}(italic|oblique))?)\', \'(?=(?:(?:[-a-z]+\\\\s*){0,2}(small-caps))?)\', \'(?=(?:(?:[-a-z]+\\\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)\', \'(?:(?:normal|\\\\1|\\\\2|\\\\3)\\\\s*){0,3}((?:xx?-)?\', \'(?:small|large)|medium|smaller|larger|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx]))\', \'(?:\\\\s*\\\\/\\\\s*(normal|[\\\\.\\\\d]+(?:\\\\%|in|[cem]m|ex|p[ctx])?))\', \'?\\\\s*([-,\\\\"\\\\\\\'\\\\sa-z]+?)\\\\s*$\'].join(\'\'), \'i\');\nvar fontRegExMatchIndex = [\'style\', \'variant\', \'weight\', \'size\', \'lineHeight\', \'family\'];\n/**\n * Get the list of font families from a font spec. Note that this doesn\'t work\n * for font families that have commas in them.\n * @param {string} fontSpec The CSS font property.\n * @return {FontParameters} The font parameters (or null if the input spec is invalid).\n */\n\nvar getFontParameters = function getFontParameters(fontSpec) {\n var match = fontSpec.match(fontRegEx);\n\n if (!match) {\n return null;\n }\n\n var style =\n /** @type {FontParameters} */\n {\n lineHeight: \'normal\',\n size: \'1.2em\',\n style: \'normal\',\n weight: \'normal\',\n variant: \'normal\'\n };\n\n for (var i = 0, ii = fontRegExMatchIndex.length; i < ii; ++i) {\n var value = match[i + 1];\n\n if (value !== undefined) {\n style[fontRegExMatchIndex[i]] = value;\n }\n }\n\n style.families = style.family.split(/,\\s?/);\n return style;\n};\n;// CONCATENATED MODULE: ./node_modules/ol/has.js\n/**\n * @module ol/has\n */\nvar ua = typeof navigator !== \'undefined\' && typeof navigator.userAgent !== \'undefined\' ? navigator.userAgent.toLowerCase() : \'\';\n/**\n * User agent string says we are dealing with Firefox as browser.\n * @type {boolean}\n */\n\nvar FIREFOX = ua.indexOf(\'firefox\') !== -1;\n/**\n * User agent string says we are dealing with Safari as browser.\n * @type {boolean}\n */\n\nvar SAFARI = ua.indexOf(\'safari\') !== -1 && ua.indexOf(\'chrom\') == -1;\n/**\n * User agent string says we are dealing with a WebKit engine.\n * @type {boolean}\n */\n\nvar WEBKIT = ua.indexOf(\'webkit\') !== -1 && ua.indexOf(\'edge\') == -1;\n/**\n * User agent string says we are dealing with a Mac as platform.\n * @type {boolean}\n */\n\nvar has_MAC = ua.indexOf(\'macintosh\') !== -1;\n/**\n * The ratio between physical pixels and device-independent pixels\n * (dips) on the device (`window.devicePixelRatio`).\n * @const\n * @type {number}\n * @api\n */\n\nvar DEVICE_PIXEL_RATIO = typeof devicePixelRatio !== \'undefined\' ? devicePixelRatio : 1;\n/**\n * The execution context is a worker with OffscreenCanvas available.\n * @const\n * @type {boolean}\n */\n\nvar WORKER_OFFSCREEN_CANVAS = typeof WorkerGlobalScope !== \'undefined\' && typeof OffscreenCanvas !== \'undefined\' && self instanceof WorkerGlobalScope; //eslint-disable-line\n\n/**\n * Image.prototype.decode() is supported.\n * @type {boolean}\n */\n\nvar IMAGE_DECODE = typeof Image !== \'undefined\' && Image.prototype.decode;\n/**\n * @type {boolean}\n */\n\nvar PASSIVE_EVENT_LISTENERS = function () {\n var passive = false;\n\n try {\n var options = Object.defineProperty({}, \'passive\', {\n get: function get() {\n passive = true;\n }\n });\n window.addEventListener(\'_\', null, options);\n window.removeEventListener(\'_\', null, options);\n } catch (error) {// passive not supported\n }\n\n return passive;\n}();\n;// CONCATENATED MODULE: ./node_modules/ol/dom.js\n\n/**\n * @module ol/dom\n */\n//FIXME Move this function to the canvas module\n\n/**\n * Create an html canvas element and returns its 2d context.\n * @param {number=} opt_width Canvas width.\n * @param {number=} opt_height Canvas height.\n * @param {Array<HTMLCanvasElement>=} opt_canvasPool Canvas pool to take existing canvas from.\n * @return {CanvasRenderingContext2D} The context.\n */\n\nfunction createCanvasContext2D(opt_width, opt_height, opt_canvasPool) {\n var canvas = opt_canvasPool && opt_canvasPool.length ? opt_canvasPool.shift() : WORKER_OFFSCREEN_CANVAS ? new OffscreenCanvas(opt_width || 300, opt_height || 300) : document.createElement(\'canvas\');\n\n if (opt_width) {\n canvas.width = opt_width;\n }\n\n if (opt_height) {\n canvas.height = opt_height;\n } //FIXME Allow OffscreenCanvasRenderingContext2D as return type\n\n\n return (\n /** @type {CanvasRenderingContext2D} */\n canvas.getContext(\'2d\')\n );\n}\n/**\n * Get the current computed width for the given element including margin,\n * padding and border.\n * Equivalent to jQuery\'s `$(el).outerWidth(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The width.\n */\n\nfunction dom_outerWidth(element) {\n var width = element.offsetWidth;\n var style = getComputedStyle(element);\n width += parseInt(style.marginLeft, 10) + parseInt(style.marginRight, 10);\n return width;\n}\n/**\n * Get the current computed height for the given element including margin,\n * padding and border.\n * Equivalent to jQuery\'s `$(el).outerHeight(true)`.\n * @param {!HTMLElement} element Element.\n * @return {number} The height.\n */\n\nfunction dom_outerHeight(element) {\n var height = element.offsetHeight;\n var style = getComputedStyle(element);\n height += parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10);\n return height;\n}\n/**\n * @param {Node} newNode Node to replace old node\n * @param {Node} oldNode The node to be replaced\n */\n\nfunction replaceNode(newNode, oldNode) {\n var parent = oldNode.parentNode;\n\n if (parent) {\n parent.replaceChild(newNode, oldNode);\n }\n}\n/**\n * @param {Node} node The node to remove.\n * @returns {Node} The node that was removed or null.\n */\n\nfunction removeNode(node) {\n return node && node.parentNode ? node.parentNode.removeChild(node) : null;\n}\n/**\n * @param {Node} node The node to remove the children from.\n */\n\nfunction removeChildren(node) {\n while (node.lastChild) {\n node.removeChild(node.lastChild);\n }\n}\n/**\n * Transform the children of a parent node so they match the\n * provided list of children. This function aims to efficiently\n * remove, add, and reorder child nodes while maintaining a simple\n * implementation (it is not guaranteed to minimize DOM operations).\n * @param {Node} node The parent node whose children need reworking.\n * @param {Array<Node>} children The desired children.\n */\n\nfunction replaceChildren(node, children) {\n var oldChildren = node.childNodes;\n\n for (var i = 0; true; ++i) {\n var oldChild = oldChildren[i];\n var newChild = children[i]; // check if our work is done\n\n if (!oldChild && !newChild) {\n break;\n } // check if children match\n\n\n if (oldChild === newChild) {\n continue;\n } // check if a new child needs to be added\n\n\n if (!oldChild) {\n node.appendChild(newChild);\n continue;\n } // check if an old child needs to be removed\n\n\n if (!newChild) {\n node.removeChild(oldChild);\n --i;\n continue;\n } // reorder\n\n\n node.insertBefore(newChild, oldChild);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas.js\n/**\n * @module ol/render/canvas\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} FillState\n * @property {import("../colorlike.js").ColorLike} fillStyle\n */\n\n/**\n * @typedef Label\n * @property {number} width\n * @property {number} height\n * @property {Array<string|number>} contextInstructions\n */\n\n/**\n * @typedef {Object} FillStrokeState\n * @property {import("../colorlike.js").ColorLike} [currentFillStyle]\n * @property {import("../colorlike.js").ColorLike} [currentStrokeStyle]\n * @property {CanvasLineCap} [currentLineCap]\n * @property {Array<number>} currentLineDash\n * @property {number} [currentLineDashOffset]\n * @property {CanvasLineJoin} [currentLineJoin]\n * @property {number} [currentLineWidth]\n * @property {number} [currentMiterLimit]\n * @property {number} [lastStroke]\n * @property {import("../colorlike.js").ColorLike} [fillStyle]\n * @property {import("../colorlike.js").ColorLike} [strokeStyle]\n * @property {CanvasLineCap} [lineCap]\n * @property {Array<number>} lineDash\n * @property {number} [lineDashOffset]\n * @property {CanvasLineJoin} [lineJoin]\n * @property {number} [lineWidth]\n * @property {number} [miterLimit]\n */\n\n/**\n * @typedef {Object} StrokeState\n * @property {CanvasLineCap} lineCap\n * @property {Array<number>} lineDash\n * @property {number} lineDashOffset\n * @property {CanvasLineJoin} lineJoin\n * @property {number} lineWidth\n * @property {number} miterLimit\n * @property {import("../colorlike.js").ColorLike} strokeStyle\n */\n\n/**\n * @typedef {Object} TextState\n * @property {string} font\n * @property {string} [textAlign]\n * @property {string} textBaseline\n * @property {string} [placement]\n * @property {number} [maxAngle]\n * @property {boolean} [overflow]\n * @property {import("../style/Fill.js").default} [backgroundFill]\n * @property {import("../style/Stroke.js").default} [backgroundStroke]\n * @property {import("../size.js").Size} [scale]\n * @property {Array<number>} [padding]\n */\n\n/**\n * @typedef {Object} SerializableInstructions\n * @property {Array<*>} instructions The rendering instructions.\n * @property {Array<*>} hitDetectionInstructions The rendering hit detection instructions.\n * @property {Array<number>} coordinates The array of all coordinates.\n * @property {!Object<string, TextState>} [textStates] The text states (decluttering).\n * @property {!Object<string, FillState>} [fillStates] The fill states (decluttering).\n * @property {!Object<string, StrokeState>} [strokeStates] The stroke states (decluttering).\n */\n\n/**\n * @typedef {Object<number, import("./canvas/Executor.js").ReplayImageOrLabelArgs>} DeclutterImageWithText\n */\n\n/**\n * @const\n * @type {string}\n */\n\nvar defaultFont = \'10px sans-serif\';\n/**\n * @const\n * @type {import("../colorlike.js").ColorLike}\n */\n\nvar defaultFillStyle = \'#000\';\n/**\n * @const\n * @type {CanvasLineCap}\n */\n\nvar defaultLineCap = \'round\';\n/**\n * @const\n * @type {Array<number>}\n */\n\nvar defaultLineDash = [];\n/**\n * @const\n * @type {number}\n */\n\nvar defaultLineDashOffset = 0;\n/**\n * @const\n * @type {CanvasLineJoin}\n */\n\nvar defaultLineJoin = \'round\';\n/**\n * @const\n * @type {number}\n */\n\nvar defaultMiterLimit = 10;\n/**\n * @const\n * @type {import("../colorlike.js").ColorLike}\n */\n\nvar defaultStrokeStyle = \'#000\';\n/**\n * @const\n * @type {string}\n */\n\nvar defaultTextAlign = \'center\';\n/**\n * @const\n * @type {string}\n */\n\nvar defaultTextBaseline = \'middle\';\n/**\n * @const\n * @type {Array<number>}\n */\n\nvar defaultPadding = [0, 0, 0, 0];\n/**\n * @const\n * @type {number}\n */\n\nvar defaultLineWidth = 1;\n/**\n * @type {BaseObject}\n */\n\nvar checkedFonts = new ol_Object();\n/**\n * The label cache for text rendering. To change the default cache size of 2048\n * entries, use {@link module:ol/structs/LRUCache#setSize}.\n * Deprecated - there is no label cache any more.\n * @type {?}\n * @api\n * @deprecated\n */\n\nvar labelCache = new events_Target();\n\nlabelCache.setSize = function () {\n console.warn(\'labelCache is deprecated.\'); //eslint-disable-line\n};\n/**\n * @type {CanvasRenderingContext2D}\n */\n\n\nvar measureContext = null;\n/**\n * @type {string}\n */\n\nvar measureFont;\n/**\n * @type {!Object<string, number>}\n */\n\nvar textHeights = {};\n/**\n * Clears the label cache when a font becomes available.\n * @param {string} fontSpec CSS font spec.\n */\n\nvar registerFont = function () {\n var retries = 100;\n var size = \'32px \';\n var referenceFonts = [\'monospace\', \'serif\'];\n var len = referenceFonts.length;\n var text = "wmytzilWMYTZIL@#/&?$%10\\uF013";\n var interval, referenceWidth;\n /**\n * @param {string} fontStyle Css font-style\n * @param {string} fontWeight Css font-weight\n * @param {*} fontFamily Css font-family\n * @return {boolean} Font with style and weight is available\n */\n\n function isAvailable(fontStyle, fontWeight, fontFamily) {\n var available = true;\n\n for (var i = 0; i < len; ++i) {\n var referenceFont = referenceFonts[i];\n referenceWidth = measureTextWidth(fontStyle + \' \' + fontWeight + \' \' + size + referenceFont, text);\n\n if (fontFamily != referenceFont) {\n var width = measureTextWidth(fontStyle + \' \' + fontWeight + \' \' + size + fontFamily + \',\' + referenceFont, text); // If width and referenceWidth are the same, then the fallback was used\n // instead of the font we wanted, so the font is not available.\n\n available = available && width != referenceWidth;\n }\n }\n\n if (available) {\n return true;\n }\n\n return false;\n }\n\n function check() {\n var done = true;\n var fonts = checkedFonts.getKeys();\n\n for (var i = 0, ii = fonts.length; i < ii; ++i) {\n var font = fonts[i];\n\n if (checkedFonts.get(font) < retries) {\n if (isAvailable.apply(this, font.split(\'\\n\'))) {\n clear(textHeights); // Make sure that loaded fonts are picked up by Safari\n\n measureContext = null;\n measureFont = undefined;\n checkedFonts.set(font, retries);\n } else {\n checkedFonts.set(font, checkedFonts.get(font) + 1, true);\n done = false;\n }\n }\n }\n\n if (done) {\n clearInterval(interval);\n interval = undefined;\n }\n }\n\n return function (fontSpec) {\n var font = getFontParameters(fontSpec);\n\n if (!font) {\n return;\n }\n\n var families = font.families;\n\n for (var i = 0, ii = families.length; i < ii; ++i) {\n var family = families[i];\n var key = font.style + \'\\n\' + font.weight + \'\\n\' + family;\n\n if (checkedFonts.get(key) === undefined) {\n checkedFonts.set(key, retries, true);\n\n if (!isAvailable(font.style, font.weight, family)) {\n checkedFonts.set(key, 0, true);\n\n if (interval === undefined) {\n interval = setInterval(check, 32);\n }\n }\n }\n }\n };\n}();\n/**\n * @param {string} font Font to use for measuring.\n * @return {import("../size.js").Size} Measurement.\n */\n\nvar measureTextHeight = function () {\n /**\n * @type {HTMLDivElement}\n */\n var div;\n return function (fontSpec) {\n var height = textHeights[fontSpec];\n\n if (height == undefined) {\n if (WORKER_OFFSCREEN_CANVAS) {\n var font = getFontParameters(fontSpec);\n var metrics = measureText(fontSpec, \'Žg\');\n var lineHeight = isNaN(Number(font.lineHeight)) ? 1.2 : Number(font.lineHeight);\n height = lineHeight * (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);\n } else {\n if (!div) {\n div = document.createElement(\'div\');\n div.innerHTML = \'M\';\n div.style.margin = \'0 !important\';\n div.style.padding = \'0 !important\';\n div.style.position = \'absolute !important\';\n div.style.left = \'-99999px !important\';\n }\n\n div.style.font = fontSpec;\n document.body.appendChild(div);\n height = div.offsetHeight;\n document.body.removeChild(div);\n }\n\n textHeights[fontSpec] = height;\n }\n\n return height;\n };\n}();\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {TextMetrics} Text metrics.\n */\n\nfunction measureText(font, text) {\n if (!measureContext) {\n measureContext = createCanvasContext2D(1, 1);\n }\n\n if (font != measureFont) {\n measureContext.font = font;\n measureFont = measureContext.font;\n }\n\n return measureContext.measureText(text);\n}\n/**\n * @param {string} font Font.\n * @param {string} text Text.\n * @return {number} Width.\n */\n\n\nfunction measureTextWidth(font, text) {\n return measureText(font, text).width;\n}\n/**\n * Measure text width using a cache.\n * @param {string} font The font.\n * @param {string} text The text to measure.\n * @param {Object<string, number>} cache A lookup of cached widths by text.\n * @returns {number} The text width.\n */\n\nfunction measureAndCacheTextWidth(font, text, cache) {\n if (text in cache) {\n return cache[text];\n }\n\n var width = measureTextWidth(font, text);\n cache[text] = width;\n return width;\n}\n/**\n * @param {string} font Font to use for measuring.\n * @param {Array<string>} lines Lines to measure.\n * @param {Array<number>} widths Array will be populated with the widths of\n * each line.\n * @return {number} Width of the whole text.\n */\n\nfunction measureTextWidths(font, lines, widths) {\n var numLines = lines.length;\n var width = 0;\n\n for (var i = 0; i < numLines; ++i) {\n var currentWidth = measureTextWidth(font, lines[i]);\n width = Math.max(width, currentWidth);\n widths.push(currentWidth);\n }\n\n return width;\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} rotation Rotation.\n * @param {number} offsetX X offset.\n * @param {number} offsetY Y offset.\n */\n\nfunction rotateAtOffset(context, rotation, offsetX, offsetY) {\n if (rotation !== 0) {\n context.translate(offsetX, offsetY);\n context.rotate(rotation);\n context.translate(-offsetX, -offsetY);\n }\n}\n/**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../transform.js").Transform|null} transform Transform.\n * @param {number} opacity Opacity.\n * @param {Label|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} labelOrImage Label.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../size.js").Size} scale Scale.\n */\n\nfunction drawImageOrLabel(context, transform, opacity, labelOrImage, originX, originY, w, h, x, y, scale) {\n context.save();\n\n if (opacity !== 1) {\n context.globalAlpha *= opacity;\n }\n\n if (transform) {\n context.setTransform.apply(context, transform);\n }\n\n if (\n /** @type {*} */\n labelOrImage.contextInstructions) {\n // label\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n executeLabelInstructions(\n /** @type {Label} */\n labelOrImage, context);\n } else if (scale[0] < 0 || scale[1] < 0) {\n // flipped image\n context.translate(x, y);\n context.scale(scale[0], scale[1]);\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */\n labelOrImage, originX, originY, w, h, 0, 0, w, h);\n } else {\n // if image not flipped translate and scale can be avoided\n context.drawImage(\n /** @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} */\n labelOrImage, originX, originY, w, h, x, y, w * scale[0], h * scale[1]);\n }\n\n context.restore();\n}\n/**\n * @param {Label} label Label.\n * @param {CanvasRenderingContext2D} context Context.\n */\n\nfunction executeLabelInstructions(label, context) {\n var contextInstructions = label.contextInstructions;\n\n for (var i = 0, ii = contextInstructions.length; i < ii; i += 2) {\n if (Array.isArray(contextInstructions[i + 1])) {\n context[contextInstructions[i]].apply(context, contextInstructions[i + 1]);\n } else {\n context[contextInstructions[i]] = contextInstructions[i + 1];\n }\n }\n}\n/**\n * @type {HTMLCanvasElement}\n * @private\n */\n\n\nvar createTransformStringCanvas = null;\n/**\n * @param {import("../transform.js").Transform} transform Transform.\n * @return {string} CSS transform.\n */\n\nfunction createTransformString(transform) {\n if (WORKER_OFFSCREEN_CANVAS) {\n return transform_toString(transform);\n } else {\n if (!createTransformStringCanvas) {\n createTransformStringCanvas = createCanvasContext2D(1, 1).canvas;\n }\n\n createTransformStringCanvas.style.transform = transform_toString(transform);\n return createTransformStringCanvas.style.transform;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Composite.js\nvar Composite_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Composite\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas map renderer.\n * @api\n */\n\nvar CompositeMapRenderer =\n/** @class */\nfunction (_super) {\n Composite_extends(CompositeMapRenderer, _super);\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n function CompositeMapRenderer(map) {\n var _this = _super.call(this, map) || this;\n /**\n * @type {import("../events.js").EventsKey}\n */\n\n\n _this.fontChangeListenerKey_ = listen(checkedFonts, ObjectEventType.PROPERTYCHANGE, map.redrawText.bind(map));\n /**\n * @private\n * @type {HTMLDivElement}\n */\n\n _this.element_ = document.createElement(\'div\');\n var style = _this.element_.style;\n style.position = \'absolute\';\n style.width = \'100%\';\n style.height = \'100%\';\n style.zIndex = \'0\';\n _this.element_.className = CLASS_UNSELECTABLE + \' ol-layers\';\n var container = map.getViewport();\n container.insertBefore(_this.element_, container.firstChild || null);\n /**\n * @private\n * @type {Array<HTMLElement>}\n */\n\n _this.children_ = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * @param {import("../render/EventType.js").default} type Event type.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CompositeMapRenderer.prototype.dispatchRenderEvent = function (type, frameState) {\n var map = this.getMap();\n\n if (map.hasListener(type)) {\n var event_1 = new render_Event(type, undefined, frameState);\n map.dispatchEvent(event_1);\n }\n };\n\n CompositeMapRenderer.prototype.disposeInternal = function () {\n unlistenByKey(this.fontChangeListenerKey_);\n this.element_.parentNode.removeChild(this.element_);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Render.\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CompositeMapRenderer.prototype.renderFrame = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element_.style.display = \'none\';\n this.renderedVisible_ = false;\n }\n\n return;\n }\n\n this.calculateMatrices2D(frameState);\n this.dispatchRenderEvent(render_EventType.PRECOMPOSE, frameState);\n var layerStatesArray = frameState.layerStatesArray.sort(function (a, b) {\n return a.zIndex - b.zIndex;\n });\n var viewState = frameState.viewState;\n this.children_.length = 0;\n /**\n * @type {Array<import("../layer/BaseVector.js").default>}\n */\n\n var declutterLayers = [];\n var previousElement = null;\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n frameState.layerIndex = i;\n\n if (!inView(layerState, viewState) || layerState.sourceState != State.READY && layerState.sourceState != State.UNDEFINED) {\n continue;\n }\n\n var layer = layerState.layer;\n var element = layer.render(frameState, previousElement);\n\n if (!element) {\n continue;\n }\n\n if (element !== previousElement) {\n this.children_.push(element);\n previousElement = element;\n }\n\n if (\'getDeclutter\' in layer) {\n declutterLayers.push(layer);\n }\n }\n\n for (var i = declutterLayers.length - 1; i >= 0; --i) {\n declutterLayers[i].renderDeclutter(frameState);\n }\n\n replaceChildren(this.element_, this.children_);\n this.dispatchRenderEvent(render_EventType.POSTCOMPOSE, frameState);\n\n if (!this.renderedVisible_) {\n this.element_.style.display = \'\';\n this.renderedVisible_ = true;\n }\n\n this.scheduleExpireIconCache(frameState);\n };\n /**\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer\n * callback.\n * @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CompositeMapRenderer.prototype.forEachLayerAtPixel = function (pixel, frameState, hitTolerance, callback, layerFilter) {\n var viewState = frameState.viewState;\n var layerStates = frameState.layerStatesArray;\n var numLayers = layerStates.length;\n\n for (var i = numLayers - 1; i >= 0; --i) {\n var layerState = layerStates[i];\n var layer = layerState.layer;\n\n if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter(layer)) {\n var layerRenderer = layer.getRenderer();\n var data = layerRenderer.getDataAtPixel(pixel, frameState, hitTolerance);\n\n if (data) {\n var result = callback(layer, data);\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n return undefined;\n };\n\n return CompositeMapRenderer;\n}(renderer_Map);\n\n/* harmony default export */ var Composite = (CompositeMapRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/CollectionEventType.js\n/**\n * @module ol/CollectionEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var CollectionEventType = ({\n /**\n * Triggered when an item is added to the collection.\n * @event module:ol/Collection.CollectionEvent#add\n * @api\n */\n ADD: \'add\',\n\n /**\n * Triggered when an item is removed from the collection.\n * @event module:ol/Collection.CollectionEvent#remove\n * @api\n */\n REMOVE: \'remove\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/Collection.js\nvar Collection_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Collection\n */\n\n\n\n\n\n\n/**\n * @enum {string}\n * @private\n */\n\nvar Collection_Property = {\n LENGTH: \'length\'\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this\n * type.\n */\n\nvar CollectionEvent =\n/** @class */\nfunction (_super) {\n Collection_extends(CollectionEvent, _super);\n /**\n * @param {import("./CollectionEventType.js").default} type Type.\n * @param {*=} opt_element Element.\n * @param {number=} opt_index The index of the added or removed element.\n */\n\n\n function CollectionEvent(type, opt_element, opt_index) {\n var _this = _super.call(this, type) || this;\n /**\n * The element that is added to or removed from the collection.\n * @type {*}\n * @api\n */\n\n\n _this.element = opt_element;\n /**\n * The index of the added or removed element.\n * @type {number}\n * @api\n */\n\n _this.index = opt_index;\n return _this;\n }\n\n return CollectionEvent;\n}(Event);\n\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [unique=false] Disallow the same item from being added to\n * the collection twice.\n */\n\n/**\n * @classdesc\n * An expanded version of standard JS Array, adding convenience methods for\n * manipulation. Add and remove changes to the Collection trigger a Collection\n * event. Note that this does not cover changes to the objects _within_ the\n * Collection; they trigger events on the appropriate object, not on the\n * Collection as a whole.\n *\n * @fires CollectionEvent\n *\n * @template T\n * @api\n */\n\nvar Collection =\n/** @class */\nfunction (_super) {\n Collection_extends(Collection, _super);\n /**\n * @param {Array<T>=} opt_array Array.\n * @param {Options=} opt_options Collection options.\n */\n\n\n function Collection(opt_array, opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options || {};\n /**\n * @private\n * @type {boolean}\n */\n\n _this.unique_ = !!options.unique;\n /**\n * @private\n * @type {!Array<T>}\n */\n\n _this.array_ = opt_array ? opt_array : [];\n\n if (_this.unique_) {\n for (var i = 0, ii = _this.array_.length; i < ii; ++i) {\n _this.assertUnique_(_this.array_[i], i);\n }\n }\n\n _this.updateLength_();\n\n return _this;\n }\n /**\n * Remove all elements from the collection.\n * @api\n */\n\n\n Collection.prototype.clear = function () {\n while (this.getLength() > 0) {\n this.pop();\n }\n };\n /**\n * Add elements to the collection. This pushes each item in the provided array\n * to the end of the collection.\n * @param {!Array<T>} arr Array.\n * @return {Collection<T>} This collection.\n * @api\n */\n\n\n Collection.prototype.extend = function (arr) {\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n this.push(arr[i]);\n }\n\n return this;\n };\n /**\n * Iterate over each element, calling the provided callback.\n * @param {function(T, number, Array<T>): *} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array). The return value is ignored.\n * @api\n */\n\n\n Collection.prototype.forEach = function (f) {\n var array = this.array_;\n\n for (var i = 0, ii = array.length; i < ii; ++i) {\n f(array[i], i, array);\n }\n };\n /**\n * Get a reference to the underlying Array object. Warning: if the array\n * is mutated, no events will be dispatched by the collection, and the\n * collection\'s "length" property won\'t be in sync with the actual length\n * of the array.\n * @return {!Array<T>} Array.\n * @api\n */\n\n\n Collection.prototype.getArray = function () {\n return this.array_;\n };\n /**\n * Get the element at the provided index.\n * @param {number} index Index.\n * @return {T} Element.\n * @api\n */\n\n\n Collection.prototype.item = function (index) {\n return this.array_[index];\n };\n /**\n * Get the length of this collection.\n * @return {number} The length of the array.\n * @observable\n * @api\n */\n\n\n Collection.prototype.getLength = function () {\n return this.get(Collection_Property.LENGTH);\n };\n /**\n * Insert an element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n\n\n Collection.prototype.insertAt = function (index, elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n\n this.array_.splice(index, 0, elem);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n };\n /**\n * Remove the last element of the collection and return it.\n * Return `undefined` if the collection is empty.\n * @return {T|undefined} Element.\n * @api\n */\n\n\n Collection.prototype.pop = function () {\n return this.removeAt(this.getLength() - 1);\n };\n /**\n * Insert the provided element at the end of the collection.\n * @param {T} elem Element.\n * @return {number} New length of the collection.\n * @api\n */\n\n\n Collection.prototype.push = function (elem) {\n if (this.unique_) {\n this.assertUnique_(elem);\n }\n\n var n = this.getLength();\n this.insertAt(n, elem);\n return this.getLength();\n };\n /**\n * Remove the first occurrence of an element from the collection.\n * @param {T} elem Element.\n * @return {T|undefined} The removed element or undefined if none found.\n * @api\n */\n\n\n Collection.prototype.remove = function (elem) {\n var arr = this.array_;\n\n for (var i = 0, ii = arr.length; i < ii; ++i) {\n if (arr[i] === elem) {\n return this.removeAt(i);\n }\n }\n\n return undefined;\n };\n /**\n * Remove the element at the provided index and return it.\n * Return `undefined` if the collection does not contain this index.\n * @param {number} index Index.\n * @return {T|undefined} Value.\n * @api\n */\n\n\n Collection.prototype.removeAt = function (index) {\n var prev = this.array_[index];\n this.array_.splice(index, 1);\n this.updateLength_();\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n return prev;\n };\n /**\n * Set the element at the provided index.\n * @param {number} index Index.\n * @param {T} elem Element.\n * @api\n */\n\n\n Collection.prototype.setAt = function (index, elem) {\n var n = this.getLength();\n\n if (index < n) {\n if (this.unique_) {\n this.assertUnique_(elem, index);\n }\n\n var prev = this.array_[index];\n this.array_[index] = elem;\n this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev, index));\n this.dispatchEvent(new CollectionEvent(CollectionEventType.ADD, elem, index));\n } else {\n for (var j = n; j < index; ++j) {\n this.insertAt(j, undefined);\n }\n\n this.insertAt(index, elem);\n }\n };\n /**\n * @private\n */\n\n\n Collection.prototype.updateLength_ = function () {\n this.set(Collection_Property.LENGTH, this.array_.length);\n };\n /**\n * @private\n * @param {T} elem Element.\n * @param {number=} opt_except Optional index to ignore.\n */\n\n\n Collection.prototype.assertUnique_ = function (elem, opt_except) {\n for (var i = 0, ii = this.array_.length; i < ii; ++i) {\n if (this.array_[i] === elem && i !== opt_except) {\n throw new ol_AssertionError(58);\n }\n }\n };\n\n return Collection;\n}(ol_Object);\n\n/* harmony default export */ var ol_Collection = (Collection);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Group.js\nvar Group_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Group\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {Array<import("./Base.js").default>|import("../Collection.js").default<import("./Base.js").default>} [layers] Child layers.\n */\n\n/**\n * @enum {string}\n * @private\n */\n\nvar Group_Property = {\n LAYERS: \'layers\'\n};\n/**\n * @classdesc\n * A {@link module:ol/Collection~Collection} of layers that are handled together.\n *\n * A generic `change` event is triggered when the group/Collection changes.\n *\n * @api\n */\n\nvar LayerGroup =\n/** @class */\nfunction (_super) {\n Group_extends(LayerGroup, _super);\n /**\n * @param {Options=} opt_options Layer options.\n */\n\n\n function LayerGroup(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n var baseOptions =\n /** @type {Options} */\n obj_assign({}, options);\n delete baseOptions.layers;\n var layers = options.layers;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {Array<import("../events.js").EventsKey>}\n */\n\n _this.layersListenerKeys_ = [];\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").EventsKey>>}\n */\n\n _this.listenerKeys_ = {};\n\n _this.addEventListener(getChangeEventType(Group_Property.LAYERS), _this.handleLayersChanged_);\n\n if (layers) {\n if (Array.isArray(layers)) {\n layers = new ol_Collection(layers.slice(), {\n unique: true\n });\n } else {\n asserts_assert(typeof\n /** @type {?} */\n layers.getArray === \'function\', 43); // Expected `layers` to be an array or a `Collection`\n }\n } else {\n layers = new ol_Collection(undefined, {\n unique: true\n });\n }\n\n _this.setLayers(layers);\n\n return _this;\n }\n /**\n * @private\n */\n\n\n LayerGroup.prototype.handleLayerChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersChanged_ = function () {\n this.layersListenerKeys_.forEach(unlistenByKey);\n this.layersListenerKeys_.length = 0;\n var layers = this.getLayers();\n this.layersListenerKeys_.push(listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this), listen(layers, CollectionEventType.REMOVE, this.handleLayersRemove_, this));\n\n for (var id in this.listenerKeys_) {\n this.listenerKeys_[id].forEach(unlistenByKey);\n }\n\n clear(this.listenerKeys_);\n var layersArray = layers.getArray();\n\n for (var i = 0, ii = layersArray.length; i < ii; i++) {\n var layer = layersArray[i];\n this.listenerKeys_[getUid(layer)] = [listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this), listen(layer, EventType.CHANGE, this.handleLayerChange_, this)];\n }\n\n this.changed();\n };\n /**\n * @param {import("../Collection.js").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersAdd_ = function (collectionEvent) {\n var layer =\n /** @type {import("./Base.js").default} */\n collectionEvent.element;\n this.listenerKeys_[getUid(layer)] = [listen(layer, ObjectEventType.PROPERTYCHANGE, this.handleLayerChange_, this), listen(layer, EventType.CHANGE, this.handleLayerChange_, this)];\n this.changed();\n };\n /**\n * @param {import("../Collection.js").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n\n\n LayerGroup.prototype.handleLayersRemove_ = function (collectionEvent) {\n var layer =\n /** @type {import("./Base.js").default} */\n collectionEvent.element;\n var key = getUid(layer);\n this.listenerKeys_[key].forEach(unlistenByKey);\n delete this.listenerKeys_[key];\n this.changed();\n };\n /**\n * Returns the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @return {!import("../Collection.js").default<import("./Base.js").default>} Collection of\n * {@link module:ol/layer/Base layers} that are part of this group.\n * @observable\n * @api\n */\n\n\n LayerGroup.prototype.getLayers = function () {\n return (\n /** @type {!import("../Collection.js").default<import("./Base.js").default>} */\n this.get(Group_Property.LAYERS)\n );\n };\n /**\n * Set the {@link module:ol/Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @param {!import("../Collection.js").default<import("./Base.js").default>} layers Collection of\n * {@link module:ol/layer/Base layers} that are part of this group.\n * @observable\n * @api\n */\n\n\n LayerGroup.prototype.setLayers = function (layers) {\n this.set(Group_Property.LAYERS, layers);\n };\n /**\n * @param {Array<import("./Layer.js").default>=} opt_array Array of layers (to be modified in place).\n * @return {Array<import("./Layer.js").default>} Array of layers.\n */\n\n\n LayerGroup.prototype.getLayersArray = function (opt_array) {\n var array = opt_array !== undefined ? opt_array : [];\n this.getLayers().forEach(function (layer) {\n layer.getLayersArray(array);\n });\n return array;\n };\n /**\n * @param {Array<import("./Layer.js").State>=} opt_states Optional list of layer states (to be modified in place).\n * @return {Array<import("./Layer.js").State>} List of layer states.\n */\n\n\n LayerGroup.prototype.getLayerStatesArray = function (opt_states) {\n var states = opt_states !== undefined ? opt_states : [];\n var pos = states.length;\n this.getLayers().forEach(function (layer) {\n layer.getLayerStatesArray(states);\n });\n var ownLayerState = this.getLayerState();\n\n for (var i = pos, ii = states.length; i < ii; i++) {\n var layerState = states[i];\n layerState.opacity *= ownLayerState.opacity;\n layerState.visible = layerState.visible && ownLayerState.visible;\n layerState.maxResolution = Math.min(layerState.maxResolution, ownLayerState.maxResolution);\n layerState.minResolution = Math.max(layerState.minResolution, ownLayerState.minResolution);\n layerState.minZoom = Math.max(layerState.minZoom, ownLayerState.minZoom);\n layerState.maxZoom = Math.min(layerState.maxZoom, ownLayerState.maxZoom);\n\n if (ownLayerState.extent !== undefined) {\n if (layerState.extent !== undefined) {\n layerState.extent = getIntersection(layerState.extent, ownLayerState.extent);\n } else {\n layerState.extent = ownLayerState.extent;\n }\n }\n }\n\n return states;\n };\n /**\n * @return {import("../source/State.js").default} Source state.\n */\n\n\n LayerGroup.prototype.getSourceState = function () {\n return State.READY;\n };\n\n return LayerGroup;\n}(Base);\n\n/* harmony default export */ var Group = (LayerGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/MapEvent.js\nvar MapEvent_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/MapEvent\n */\n\n\n\n/**\n * @classdesc\n * Events emitted as map events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map event.\n */\n\nvar MapEvent =\n/** @class */\nfunction (_super) {\n MapEvent_extends(MapEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import("./PluggableMap.js").default} map Map.\n * @param {?import("./PluggableMap.js").FrameState=} opt_frameState Frame state.\n */\n\n\n function MapEvent(type, map, opt_frameState) {\n var _this = _super.call(this, type) || this;\n /**\n * The map where the event occurred.\n * @type {import("./PluggableMap.js").default}\n * @api\n */\n\n\n _this.map = map;\n /**\n * The frame state at the time of the event.\n * @type {?import("./PluggableMap.js").FrameState}\n * @api\n */\n\n _this.frameState = opt_frameState !== undefined ? opt_frameState : null;\n return _this;\n }\n\n return MapEvent;\n}(Event);\n\n/* harmony default export */ var ol_MapEvent = (MapEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEvent.js\nvar MapBrowserEvent_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/MapBrowserEvent\n */\n\n\n\n/**\n * @classdesc\n * Events emitted as map browser events are instances of this type.\n * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map browser event.\n * @template {UIEvent} EVENT\n */\n\nvar MapBrowserEvent =\n/** @class */\nfunction (_super) {\n MapBrowserEvent_extends(MapBrowserEvent, _super);\n /**\n * @param {string} type Event type.\n * @param {import("./PluggableMap.js").default} map Map.\n * @param {EVENT} originalEvent Original event.\n * @param {boolean=} opt_dragging Is the map currently being dragged?\n * @param {?import("./PluggableMap.js").FrameState=} opt_frameState Frame state.\n */\n\n\n function MapBrowserEvent(type, map, originalEvent, opt_dragging, opt_frameState) {\n var _this = _super.call(this, type, map, opt_frameState) || this;\n /**\n * The original browser event.\n * @const\n * @type {EVENT}\n * @api\n */\n\n\n _this.originalEvent = originalEvent;\n /**\n * The map pixel relative to the viewport corresponding to the original browser event.\n * @type {?import("./pixel.js").Pixel}\n */\n\n _this.pixel_ = null;\n /**\n * The coordinate in the user projection corresponding to the original browser event.\n * @type {?import("./coordinate.js").Coordinate}\n */\n\n _this.coordinate_ = null;\n /**\n * Indicates if the map is currently being dragged. Only set for\n * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`.\n *\n * @type {boolean}\n * @api\n */\n\n _this.dragging = opt_dragging !== undefined ? opt_dragging : false;\n return _this;\n }\n\n Object.defineProperty(MapBrowserEvent.prototype, "pixel", {\n /**\n * The map pixel relative to the viewport corresponding to the original event.\n * @type {import("./pixel.js").Pixel}\n * @api\n */\n get: function get() {\n if (!this.pixel_) {\n this.pixel_ = this.map.getEventPixel(this.originalEvent);\n }\n\n return this.pixel_;\n },\n set: function set(pixel) {\n this.pixel_ = pixel;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(MapBrowserEvent.prototype, "coordinate", {\n /**\n * The coordinate corresponding to the original browser event. This will be in the user\n * projection if one is set. Otherwise it will be in the view projection.\n * @type {import("./coordinate.js").Coordinate}\n * @api\n */\n get: function get() {\n if (!this.coordinate_) {\n this.coordinate_ = this.map.getCoordinateFromPixel(this.pixel);\n }\n\n return this.coordinate_;\n },\n set: function set(coordinate) {\n this.coordinate_ = coordinate;\n },\n enumerable: false,\n configurable: true\n });\n /**\n * Prevents the default browser action.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.\n * @api\n */\n\n MapBrowserEvent.prototype.preventDefault = function () {\n _super.prototype.preventDefault.call(this);\n\n this.originalEvent.preventDefault();\n };\n /**\n * Prevents further propagation of the current event.\n * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.\n * @api\n */\n\n\n MapBrowserEvent.prototype.stopPropagation = function () {\n _super.prototype.stopPropagation.call(this);\n\n this.originalEvent.stopPropagation();\n };\n\n return MapBrowserEvent;\n}(ol_MapEvent);\n\n/* harmony default export */ var ol_MapBrowserEvent = (MapBrowserEvent);\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventType.js\n/**\n * @module ol/MapBrowserEventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\n\n/* harmony default export */ var ol_MapBrowserEventType = ({\n /**\n * A true single click with no dragging and no double click. Note that this\n * event is delayed by 250 ms to ensure that it is not a double click.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick\n * @api\n */\n SINGLECLICK: \'singleclick\',\n\n /**\n * A click with no dragging. A double click will fire two of this.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#click\n * @api\n */\n CLICK: EventType.CLICK,\n\n /**\n * A true double click, with no dragging.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick\n * @api\n */\n DBLCLICK: EventType.DBLCLICK,\n\n /**\n * Triggered when a pointer is dragged.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag\n * @api\n */\n POINTERDRAG: \'pointerdrag\',\n\n /**\n * Triggered when a pointer is moved. Note that on touch devices this is\n * triggered when the map is panned, so is not the same as mousemove.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove\n * @api\n */\n POINTERMOVE: \'pointermove\',\n POINTERDOWN: \'pointerdown\',\n POINTERUP: \'pointerup\',\n POINTEROVER: \'pointerover\',\n POINTEROUT: \'pointerout\',\n POINTERENTER: \'pointerenter\',\n POINTERLEAVE: \'pointerleave\',\n POINTERCANCEL: \'pointercancel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/pointer/EventType.js\n/**\n * @module ol/pointer/EventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\n/* harmony default export */ var pointer_EventType = ({\n POINTERMOVE: \'pointermove\',\n POINTERDOWN: \'pointerdown\',\n POINTERUP: \'pointerup\',\n POINTEROVER: \'pointerover\',\n POINTEROUT: \'pointerout\',\n POINTERENTER: \'pointerenter\',\n POINTERLEAVE: \'pointerleave\',\n POINTERCANCEL: \'pointercancel\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/MapBrowserEventHandler.js\n/**\n * @module ol/MapBrowserEventHandler\n */\nvar MapBrowserEventHandler_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\nvar MapBrowserEventHandler =\n/** @class */\nfunction (_super) {\n MapBrowserEventHandler_extends(MapBrowserEventHandler, _super);\n /**\n * @param {import("./PluggableMap.js").default} map The map with the viewport to listen to events on.\n * @param {number=} moveTolerance The minimal distance the pointer must travel to trigger a move.\n */\n\n\n function MapBrowserEventHandler(map, moveTolerance) {\n var _this = _super.call(this, map) || this;\n /**\n * This is the element that we will listen to the real events on.\n * @type {import("./PluggableMap.js").default}\n * @private\n */\n\n\n _this.map_ = map;\n /**\n * @type {any}\n * @private\n */\n\n _this.clickTimeoutId_;\n /**\n * Emulate dblclick and singleclick. Will be true when only one pointer is active.\n * @type {boolean}\n */\n\n _this.emulateClicks_ = false;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.dragging_ = false;\n /**\n * @type {!Array<import("./events.js").EventsKey>}\n * @private\n */\n\n _this.dragListenerKeys_ = [];\n /**\n * @type {number}\n * @private\n */\n\n _this.moveTolerance_ = moveTolerance ? moveTolerance * DEVICE_PIXEL_RATIO : DEVICE_PIXEL_RATIO;\n /**\n * The most recent "down" type event (or null if none have occurred).\n * Set on pointerdown.\n * @type {PointerEvent}\n * @private\n */\n\n _this.down_ = null;\n\n var element = _this.map_.getViewport();\n /**\n * @type {number}\n * @private\n */\n\n\n _this.activePointers_ = 0;\n /**\n * @type {!Object<number, boolean>}\n * @private\n */\n\n _this.trackedTouches_ = {};\n _this.element_ = element;\n /**\n * @type {?import("./events.js").EventsKey}\n * @private\n */\n\n _this.pointerdownListenerKey_ = listen(element, pointer_EventType.POINTERDOWN, _this.handlePointerDown_, _this);\n /**\n * @type {PointerEvent}\n * @private\n */\n\n _this.originalPointerMoveEvent_;\n /**\n * @type {?import("./events.js").EventsKey}\n * @private\n */\n\n _this.relayedListenerKey_ = listen(element, pointer_EventType.POINTERMOVE, _this.relayEvent_, _this);\n /**\n * @private\n */\n\n _this.boundHandleTouchMove_ = _this.handleTouchMove_.bind(_this);\n\n _this.element_.addEventListener(EventType.TOUCHMOVE, _this.boundHandleTouchMove_, PASSIVE_EVENT_LISTENERS ? {\n passive: false\n } : false);\n\n return _this;\n }\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.emulateClick_ = function (pointerEvent) {\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.CLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n\n if (this.clickTimeoutId_ !== undefined) {\n // double-click\n clearTimeout(this.clickTimeoutId_);\n this.clickTimeoutId_ = undefined;\n newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.DBLCLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n } else {\n // click\n this.clickTimeoutId_ = setTimeout(\n /** @this {MapBrowserEventHandler} */\n function () {\n this.clickTimeoutId_ = undefined;\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.SINGLECLICK, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n }.bind(this), 250);\n }\n };\n /**\n * Keeps track on how many pointers are currently active.\n *\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.updateActivePointers_ = function (pointerEvent) {\n var event = pointerEvent;\n\n if (event.type == ol_MapBrowserEventType.POINTERUP || event.type == ol_MapBrowserEventType.POINTERCANCEL) {\n delete this.trackedTouches_[event.pointerId];\n } else if (event.type == ol_MapBrowserEventType.POINTERDOWN) {\n this.trackedTouches_[event.pointerId] = true;\n }\n\n this.activePointers_ = Object.keys(this.trackedTouches_).length;\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerUp_ = function (pointerEvent) {\n this.updateActivePointers_(pointerEvent);\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERUP, this.map_, pointerEvent);\n this.dispatchEvent(newEvent); // We emulate click events on left mouse button click, touch contact, and pen\n // contact. isMouseActionButton returns true in these cases (evt.button is set\n // to 0).\n // See http://www.w3.org/TR/pointerevents/#button-states\n // We only fire click, singleclick, and doubleclick if nobody has called\n // event.stopPropagation() or event.preventDefault().\n\n if (this.emulateClicks_ && !newEvent.propagationStopped && !this.dragging_ && this.isMouseActionButton_(pointerEvent)) {\n this.emulateClick_(this.down_);\n }\n\n if (this.activePointers_ === 0) {\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.dragging_ = false;\n this.down_ = null;\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} If the left mouse button was pressed.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.isMouseActionButton_ = function (pointerEvent) {\n return pointerEvent.button === 0;\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerDown_ = function (pointerEvent) {\n this.emulateClicks_ = this.activePointers_ === 0;\n this.updateActivePointers_(pointerEvent);\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent);\n this.dispatchEvent(newEvent);\n this.down_ = pointerEvent;\n\n if (this.dragListenerKeys_.length === 0) {\n var doc = this.map_.getOwnerDocument();\n this.dragListenerKeys_.push(listen(doc, ol_MapBrowserEventType.POINTERMOVE, this.handlePointerMove_, this), listen(doc, ol_MapBrowserEventType.POINTERUP, this.handlePointerUp_, this),\n /* Note that the listener for `pointercancel is set up on\n * `pointerEventHandler_` and not `documentPointerEventHandler_` like\n * the `pointerup` and `pointermove` listeners.\n *\n * The reason for this is the following: `TouchSource.vacuumTouches_()`\n * issues `pointercancel` events, when there was no `touchend` for a\n * `touchstart`. Now, let\'s say a first `touchstart` is registered on\n * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.\n * But `documentPointerEventHandler_` doesn\'t know about the first\n * `touchstart`. If there is no `touchend` for the `touchstart`, we can\n * only receive a `touchcancel` from `pointerEventHandler_`, because it is\n * only registered there.\n */\n listen(this.element_, ol_MapBrowserEventType.POINTERCANCEL, this.handlePointerUp_, this));\n\n if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {\n this.dragListenerKeys_.push(listen(this.element_.getRootNode(), ol_MapBrowserEventType.POINTERUP, this.handlePointerUp_, this));\n }\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handlePointerMove_ = function (pointerEvent) {\n // Between pointerdown and pointerup, pointermove events are triggered.\n // To avoid a \'false\' touchmove event to be dispatched, we test if the pointer\n // moved a significant distance.\n if (this.isMoving_(pointerEvent)) {\n this.dragging_ = true;\n var newEvent = new ol_MapBrowserEvent(ol_MapBrowserEventType.POINTERDRAG, this.map_, pointerEvent, this.dragging_);\n this.dispatchEvent(newEvent);\n }\n };\n /**\n * Wrap and relay a pointer event. Note that this requires that the type\n * string for the MapBrowserEvent matches the PointerEvent type.\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.relayEvent_ = function (pointerEvent) {\n this.originalPointerMoveEvent_ = pointerEvent;\n var dragging = !!(this.down_ && this.isMoving_(pointerEvent));\n this.dispatchEvent(new ol_MapBrowserEvent(pointerEvent.type, this.map_, pointerEvent, dragging));\n };\n /**\n * Flexible handling of a `touch-action: none` css equivalent: because calling\n * `preventDefault()` on a `pointermove` event does not stop native page scrolling\n * and zooming, we also listen for `touchmove` and call `preventDefault()` on it\n * when an interaction (currently `DragPan` handles the event.\n * @param {TouchEvent} event Event.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.handleTouchMove_ = function (event) {\n // Due to https://github.com/mpizenberg/elm-pep/issues/2, `this.originalPointerMoveEvent_`\n // may not be initialized yet when we get here on a platform without native pointer events.\n if (!this.originalPointerMoveEvent_ || this.originalPointerMoveEvent_.defaultPrevented) {\n event.preventDefault();\n }\n };\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} Is moving.\n * @private\n */\n\n\n MapBrowserEventHandler.prototype.isMoving_ = function (pointerEvent) {\n return this.dragging_ || Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ || Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;\n };\n /**\n * Clean up.\n */\n\n\n MapBrowserEventHandler.prototype.disposeInternal = function () {\n if (this.relayedListenerKey_) {\n unlistenByKey(this.relayedListenerKey_);\n this.relayedListenerKey_ = null;\n }\n\n this.element_.removeEventListener(EventType.TOUCHMOVE, this.boundHandleTouchMove_);\n\n if (this.pointerdownListenerKey_) {\n unlistenByKey(this.pointerdownListenerKey_);\n this.pointerdownListenerKey_ = null;\n }\n\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.element_ = null;\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return MapBrowserEventHandler;\n}(events_Target);\n\n/* harmony default export */ var ol_MapBrowserEventHandler = (MapBrowserEventHandler);\n;// CONCATENATED MODULE: ./node_modules/ol/MapEventType.js\n/**\n * @module ol/MapEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var MapEventType = ({\n /**\n * Triggered after a map frame is rendered.\n * @event module:ol/MapEvent~MapEvent#postrender\n * @api\n */\n POSTRENDER: \'postrender\',\n\n /**\n * Triggered when the map starts moving.\n * @event module:ol/MapEvent~MapEvent#movestart\n * @api\n */\n MOVESTART: \'movestart\',\n\n /**\n * Triggered after the map is moved.\n * @event module:ol/MapEvent~MapEvent#moveend\n * @api\n */\n MOVEEND: \'moveend\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/MapProperty.js\n/**\n * @module ol/MapProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var MapProperty = ({\n LAYERGROUP: \'layergroup\',\n SIZE: \'size\',\n TARGET: \'target\',\n VIEW: \'view\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/structs/PriorityQueue.js\n/**\n * @module ol/structs/PriorityQueue\n */\n\n\n/**\n * @type {number}\n */\n\nvar DROP = Infinity;\n/**\n * @classdesc\n * Priority queue.\n *\n * The implementation is inspired from the Closure Library\'s Heap class and\n * Python\'s heapq module.\n *\n * See http://closure-library.googlecode.com/svn/docs/closure_goog_structs_heap.js.source.html\n * and http://hg.python.org/cpython/file/2.7/Lib/heapq.py.\n *\n * @template T\n */\n\nvar PriorityQueue =\n/** @class */\nfunction () {\n /**\n * @param {function(T): number} priorityFunction Priority function.\n * @param {function(T): string} keyFunction Key function.\n */\n function PriorityQueue(priorityFunction, keyFunction) {\n /**\n * @type {function(T): number}\n * @private\n */\n this.priorityFunction_ = priorityFunction;\n /**\n * @type {function(T): string}\n * @private\n */\n\n this.keyFunction_ = keyFunction;\n /**\n * @type {Array<T>}\n * @private\n */\n\n this.elements_ = [];\n /**\n * @type {Array<number>}\n * @private\n */\n\n this.priorities_ = [];\n /**\n * @type {!Object<string, boolean>}\n * @private\n */\n\n this.queuedElements_ = {};\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n PriorityQueue.prototype.clear = function () {\n this.elements_.length = 0;\n this.priorities_.length = 0;\n clear(this.queuedElements_);\n };\n /**\n * Remove and return the highest-priority element. O(log N).\n * @return {T} Element.\n */\n\n\n PriorityQueue.prototype.dequeue = function () {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[0];\n\n if (elements.length == 1) {\n elements.length = 0;\n priorities.length = 0;\n } else {\n elements[0] = elements.pop();\n priorities[0] = priorities.pop();\n this.siftUp_(0);\n }\n\n var elementKey = this.keyFunction_(element);\n delete this.queuedElements_[elementKey];\n return element;\n };\n /**\n * Enqueue an element. O(log N).\n * @param {T} element Element.\n * @return {boolean} The element was added to the queue.\n */\n\n\n PriorityQueue.prototype.enqueue = function (element) {\n asserts_assert(!(this.keyFunction_(element) in this.queuedElements_), 31); // Tried to enqueue an `element` that was already added to the queue\n\n var priority = this.priorityFunction_(element);\n\n if (priority != DROP) {\n this.elements_.push(element);\n this.priorities_.push(priority);\n this.queuedElements_[this.keyFunction_(element)] = true;\n this.siftDown_(0, this.elements_.length - 1);\n return true;\n }\n\n return false;\n };\n /**\n * @return {number} Count.\n */\n\n\n PriorityQueue.prototype.getCount = function () {\n return this.elements_.length;\n };\n /**\n * Gets the index of the left child of the node at the given index.\n * @param {number} index The index of the node to get the left child for.\n * @return {number} The index of the left child.\n * @private\n */\n\n\n PriorityQueue.prototype.getLeftChildIndex_ = function (index) {\n return index * 2 + 1;\n };\n /**\n * Gets the index of the right child of the node at the given index.\n * @param {number} index The index of the node to get the right child for.\n * @return {number} The index of the right child.\n * @private\n */\n\n\n PriorityQueue.prototype.getRightChildIndex_ = function (index) {\n return index * 2 + 2;\n };\n /**\n * Gets the index of the parent of the node at the given index.\n * @param {number} index The index of the node to get the parent for.\n * @return {number} The index of the parent.\n * @private\n */\n\n\n PriorityQueue.prototype.getParentIndex_ = function (index) {\n return index - 1 >> 1;\n };\n /**\n * Make this a heap. O(N).\n * @private\n */\n\n\n PriorityQueue.prototype.heapify_ = function () {\n var i;\n\n for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {\n this.siftUp_(i);\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n PriorityQueue.prototype.isEmpty = function () {\n return this.elements_.length === 0;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Is key queued.\n */\n\n\n PriorityQueue.prototype.isKeyQueued = function (key) {\n return key in this.queuedElements_;\n };\n /**\n * @param {T} element Element.\n * @return {boolean} Is queued.\n */\n\n\n PriorityQueue.prototype.isQueued = function (element) {\n return this.isKeyQueued(this.keyFunction_(element));\n };\n /**\n * @param {number} index The index of the node to move down.\n * @private\n */\n\n\n PriorityQueue.prototype.siftUp_ = function (index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var count = elements.length;\n var element = elements[index];\n var priority = priorities[index];\n var startIndex = index;\n\n while (index < count >> 1) {\n var lIndex = this.getLeftChildIndex_(index);\n var rIndex = this.getRightChildIndex_(index);\n var smallerChildIndex = rIndex < count && priorities[rIndex] < priorities[lIndex] ? rIndex : lIndex;\n elements[index] = elements[smallerChildIndex];\n priorities[index] = priorities[smallerChildIndex];\n index = smallerChildIndex;\n }\n\n elements[index] = element;\n priorities[index] = priority;\n this.siftDown_(startIndex, index);\n };\n /**\n * @param {number} startIndex The index of the root.\n * @param {number} index The index of the node to move up.\n * @private\n */\n\n\n PriorityQueue.prototype.siftDown_ = function (startIndex, index) {\n var elements = this.elements_;\n var priorities = this.priorities_;\n var element = elements[index];\n var priority = priorities[index];\n\n while (index > startIndex) {\n var parentIndex = this.getParentIndex_(index);\n\n if (priorities[parentIndex] > priority) {\n elements[index] = elements[parentIndex];\n priorities[index] = priorities[parentIndex];\n index = parentIndex;\n } else {\n break;\n }\n }\n\n elements[index] = element;\n priorities[index] = priority;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n PriorityQueue.prototype.reprioritize = function () {\n var priorityFunction = this.priorityFunction_;\n var elements = this.elements_;\n var priorities = this.priorities_;\n var index = 0;\n var n = elements.length;\n var element, i, priority;\n\n for (i = 0; i < n; ++i) {\n element = elements[i];\n priority = priorityFunction(element);\n\n if (priority == DROP) {\n delete this.queuedElements_[this.keyFunction_(element)];\n } else {\n priorities[index] = priority;\n elements[index++] = element;\n }\n }\n\n elements.length = index;\n priorities.length = index;\n this.heapify_();\n };\n\n return PriorityQueue;\n}();\n\n/* harmony default export */ var structs_PriorityQueue = (PriorityQueue);\n;// CONCATENATED MODULE: ./node_modules/ol/TileState.js\n/**\n * @module ol/TileState\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var TileState = ({\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n\n /**\n * Indicates that tile loading failed\n * @type {number}\n */\n ERROR: 3,\n EMPTY: 4\n});\n;// CONCATENATED MODULE: ./node_modules/ol/TileQueue.js\nvar TileQueue_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/TileQueue\n */\n\n\n\n\n\n/**\n * @typedef {function(import("./Tile.js").default, string, import("./coordinate.js").Coordinate, number): number} PriorityFunction\n */\n\nvar TileQueue =\n/** @class */\nfunction (_super) {\n TileQueue_extends(TileQueue, _super);\n /**\n * @param {PriorityFunction} tilePriorityFunction Tile priority function.\n * @param {function(): ?} tileChangeCallback Function called on each tile change event.\n */\n\n\n function TileQueue(tilePriorityFunction, tileChangeCallback) {\n var _this = _super.call(this,\n /**\n * @param {Array} element Element.\n * @return {number} Priority.\n */\n function (element) {\n return tilePriorityFunction.apply(null, element);\n },\n /**\n * @param {Array} element Element.\n * @return {string} Key.\n */\n function (element) {\n return (\n /** @type {import("./Tile.js").default} */\n element[0].getKey()\n );\n }) || this;\n /** @private */\n\n\n _this.boundHandleTileChange_ = _this.handleTileChange.bind(_this);\n /**\n * @private\n * @type {function(): ?}\n */\n\n _this.tileChangeCallback_ = tileChangeCallback;\n /**\n * @private\n * @type {number}\n */\n\n _this.tilesLoading_ = 0;\n /**\n * @private\n * @type {!Object<string,boolean>}\n */\n\n _this.tilesLoadingKeys_ = {};\n return _this;\n }\n /**\n * @param {Array} element Element.\n * @return {boolean} The element was added to the queue.\n */\n\n\n TileQueue.prototype.enqueue = function (element) {\n var added = _super.prototype.enqueue.call(this, element);\n\n if (added) {\n var tile = element[0];\n tile.addEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n }\n\n return added;\n };\n /**\n * @return {number} Number of tiles loading.\n */\n\n\n TileQueue.prototype.getTilesLoading = function () {\n return this.tilesLoading_;\n };\n /**\n * @param {import("./events/Event.js").default} event Event.\n * @protected\n */\n\n\n TileQueue.prototype.handleTileChange = function (event) {\n var tile =\n /** @type {import("./Tile.js").default} */\n event.target;\n var state = tile.getState();\n\n if (tile.hifi && state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {\n tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n var tileKey = tile.getKey();\n\n if (tileKey in this.tilesLoadingKeys_) {\n delete this.tilesLoadingKeys_[tileKey];\n --this.tilesLoading_;\n }\n\n this.tileChangeCallback_();\n }\n };\n /**\n * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.\n * @param {number} maxNewLoads Maximum number of new tiles to load.\n */\n\n\n TileQueue.prototype.loadMoreTiles = function (maxTotalLoading, maxNewLoads) {\n var newLoads = 0;\n var state, tile, tileKey;\n\n while (this.tilesLoading_ < maxTotalLoading && newLoads < maxNewLoads && this.getCount() > 0) {\n tile =\n /** @type {import("./Tile.js").default} */\n this.dequeue()[0];\n tileKey = tile.getKey();\n state = tile.getState();\n\n if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {\n this.tilesLoadingKeys_[tileKey] = true;\n ++this.tilesLoading_;\n ++newLoads;\n tile.load();\n }\n }\n };\n\n return TileQueue;\n}(structs_PriorityQueue);\n\n/* harmony default export */ var ol_TileQueue = (TileQueue);\n/**\n * @param {import(\'./PluggableMap.js\').FrameState} frameState Frame state.\n * @param {import("./Tile.js").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\n\nfunction getTilePriority(frameState, tile, tileSourceKey, tileCenter, tileResolution) {\n // Filter out tiles at higher zoom levels than the current zoom level, or that\n // are outside the visible extent.\n if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {\n return DROP;\n }\n\n if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {\n return DROP;\n } // Prioritize the highest zoom level tiles closest to the focus.\n // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).\n // Within a zoom level, tiles are prioritized by the distance in pixels between\n // the center of the tile and the center of the viewport. The factor of 65536\n // means that the prioritization should behave as desired for tiles up to\n // 65536 * Math.log(2) = 45426 pixels from the focus.\n\n\n var center = frameState.viewState.center;\n var deltaX = tileCenter[0] - center[0];\n var deltaY = tileCenter[1] - center[1];\n return 65536 * Math.log(tileResolution) + Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryType.js\n/**\n * @module ol/geom/GeometryType\n */\n\n/**\n * The geometry type. One of `\'Point\'`, `\'LineString\'`, `\'LinearRing\'`,\n * `\'Polygon\'`, `\'MultiPoint\'`, `\'MultiLineString\'`, `\'MultiPolygon\'`,\n * `\'GeometryCollection\'`, `\'Circle\'`.\n * @enum {string}\n */\n/* harmony default export */ var geom_GeometryType = ({\n POINT: \'Point\',\n LINE_STRING: \'LineString\',\n LINEAR_RING: \'LinearRing\',\n POLYGON: \'Polygon\',\n MULTI_POINT: \'MultiPoint\',\n MULTI_LINE_STRING: \'MultiLineString\',\n MULTI_POLYGON: \'MultiPolygon\',\n GEOMETRY_COLLECTION: \'GeometryCollection\',\n CIRCLE: \'Circle\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/proj/Units.js\n/**\n * @module ol/proj/Units\n */\n\n/**\n * Projection units: `\'degrees\'`, `\'ft\'`, `\'m\'`, `\'pixels\'`, `\'tile-pixels\'` or\n * `\'us-ft\'`.\n * @enum {string}\n */\nvar Units_Units = {\n /**\n * Degrees\n * @api\n */\n DEGREES: \'degrees\',\n\n /**\n * Feet\n * @api\n */\n FEET: \'ft\',\n\n /**\n * Meters\n * @api\n */\n METERS: \'m\',\n\n /**\n * Pixels\n * @api\n */\n PIXELS: \'pixels\',\n\n /**\n * Tile Pixels\n * @api\n */\n TILE_PIXELS: \'tile-pixels\',\n\n /**\n * US Feet\n * @api\n */\n USFEET: \'us-ft\'\n};\n/**\n * Meters per unit lookup table.\n * @const\n * @type {Object<Units, number>}\n * @api\n */\n\nvar Units_METERS_PER_UNIT = {}; // use the radius of the Normal sphere\n\nUnits_METERS_PER_UNIT[Units_Units.DEGREES] = 2 * Math.PI * 6370997 / 360;\nUnits_METERS_PER_UNIT[Units_Units.FEET] = 0.3048;\nUnits_METERS_PER_UNIT[Units_Units.METERS] = 1;\nUnits_METERS_PER_UNIT[Units_Units.USFEET] = 1200 / 3937;\n/* harmony default export */ var proj_Units = (Units_Units);\n;// CONCATENATED MODULE: ./node_modules/ol/ViewHint.js\n/**\n * @module ol/ViewHint\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var ViewHint = ({\n ANIMATING: 0,\n INTERACTING: 1\n});\n;// CONCATENATED MODULE: ./node_modules/ol/ViewProperty.js\n/**\n * @module ol/ViewProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var ViewProperty = ({\n CENTER: \'center\',\n RESOLUTION: \'resolution\',\n ROTATION: \'rotation\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/common.js\n/**\n * @module ol/tilegrid/common\n */\n\n/**\n * Default maximum zoom for default tile grids.\n * @type {number}\n */\nvar DEFAULT_MAX_ZOOM = 42;\n/**\n * Default tile size.\n * @type {number}\n */\n\nvar DEFAULT_TILE_SIZE = 256;\n;// CONCATENATED MODULE: ./node_modules/ol/proj/Projection.js\n/**\n * @module ol/proj/Projection\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import("./Units.js").default|string} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import("../extent.js").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation=\'enu\'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link module:ol/proj/Units~METERS_PER_UNIT}\n * lookup table.\n * @property {import("../extent.js").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns\n * the `{number}` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj#getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj~get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n * http://www.opengis.net/gml/srs/epsg.xml#4326,\n * urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n * urn:ogc:def:crs:EPSG:6.18:3:3857,\n * http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4~register} function.\n *\n * @api\n */\n\nvar Projection =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Projection options.\n */\n function Projection(options) {\n /**\n * @private\n * @type {string}\n */\n this.code_ = options.code;\n /**\n * Units of projected coordinates. When set to `TILE_PIXELS`, a\n * `this.extent_` and `this.worldExtent_` must be configured properly for each\n * tile.\n * @private\n * @type {import("./Units.js").default}\n */\n\n this.units_ =\n /** @type {import("./Units.js").default} */\n options.units;\n /**\n * Validity extent of the projection in projected coordinates. For projections\n * with `TILE_PIXELS` units, this is the extent of the tile in\n * tile pixel space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.extent_ = options.extent !== undefined ? options.extent : null;\n /**\n * Extent of the world in EPSG:4326. For projections with\n * `TILE_PIXELS` units, this is the extent of the tile in\n * projected coordinate space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.worldExtent_ = options.worldExtent !== undefined ? options.worldExtent : null;\n /**\n * @private\n * @type {string}\n */\n\n this.axisOrientation_ = options.axisOrientation !== undefined ? options.axisOrientation : \'enu\';\n /**\n * @private\n * @type {boolean}\n */\n\n this.global_ = options.global !== undefined ? options.global : false;\n /**\n * @private\n * @type {boolean}\n */\n\n this.canWrapX_ = !!(this.global_ && this.extent_);\n /**\n * @private\n * @type {function(number, import("../coordinate.js").Coordinate):number|undefined}\n */\n\n this.getPointResolutionFunc_ = options.getPointResolution;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n this.defaultTileGrid_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.metersPerUnit_ = options.metersPerUnit;\n }\n /**\n * @return {boolean} The projection is suitable for wrapping the x-axis\n */\n\n\n Projection.prototype.canWrapX = function () {\n return this.canWrapX_;\n };\n /**\n * Get the code for this projection, e.g. \'EPSG:4326\'.\n * @return {string} Code.\n * @api\n */\n\n\n Projection.prototype.getCode = function () {\n return this.code_;\n };\n /**\n * Get the validity extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n Projection.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the units of this projection.\n * @return {import("./Units.js").default} Units.\n * @api\n */\n\n\n Projection.prototype.getUnits = function () {\n return this.units_;\n };\n /**\n * Get the amount of meters per unit of this projection. If the projection is\n * not configured with `metersPerUnit` or a units identifier, the return is\n * `undefined`.\n * @return {number|undefined} Meters.\n * @api\n */\n\n\n Projection.prototype.getMetersPerUnit = function () {\n return this.metersPerUnit_ || Units_METERS_PER_UNIT[this.units_];\n };\n /**\n * Get the world extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n Projection.prototype.getWorldExtent = function () {\n return this.worldExtent_;\n };\n /**\n * Get the axis orientation of this projection.\n * Example values are:\n * enu - the default easting, northing, elevation.\n * neu - northing, easting, up - useful for "lat/long" geographic coordinates,\n * or south orientated transverse mercator.\n * wnu - westing, northing, up - some planetary coordinate systems have\n * "west positive" coordinate systems\n * @return {string} Axis orientation.\n * @api\n */\n\n\n Projection.prototype.getAxisOrientation = function () {\n return this.axisOrientation_;\n };\n /**\n * Is this projection a global projection which spans the whole world?\n * @return {boolean} Whether the projection is global.\n * @api\n */\n\n\n Projection.prototype.isGlobal = function () {\n return this.global_;\n };\n /**\n * Set if the projection is a global projection which spans the whole world\n * @param {boolean} global Whether the projection is global.\n * @api\n */\n\n\n Projection.prototype.setGlobal = function (global) {\n this.global_ = global;\n this.canWrapX_ = !!(global && this.extent_);\n };\n /**\n * @return {import("../tilegrid/TileGrid.js").default} The default tile grid.\n */\n\n\n Projection.prototype.getDefaultTileGrid = function () {\n return this.defaultTileGrid_;\n };\n /**\n * @param {import("../tilegrid/TileGrid.js").default} tileGrid The default tile grid.\n */\n\n\n Projection.prototype.setDefaultTileGrid = function (tileGrid) {\n this.defaultTileGrid_ = tileGrid;\n };\n /**\n * Set the validity extent for this projection.\n * @param {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n Projection.prototype.setExtent = function (extent) {\n this.extent_ = extent;\n this.canWrapX_ = !!(this.global_ && extent);\n };\n /**\n * Set the world extent for this projection.\n * @param {import("../extent.js").Extent} worldExtent World extent\n * [minlon, minlat, maxlon, maxlat].\n * @api\n */\n\n\n Projection.prototype.setWorldExtent = function (worldExtent) {\n this.worldExtent_ = worldExtent;\n };\n /**\n * Set the getPointResolution function (see {@link module:ol/proj~getPointResolution}\n * for this projection.\n * @param {function(number, import("../coordinate.js").Coordinate):number} func Function\n * @api\n */\n\n\n Projection.prototype.setGetPointResolution = function (func) {\n this.getPointResolutionFunc_ = func;\n };\n /**\n * Get the custom point resolution function for this projection (if set).\n * @return {function(number, import("../coordinate.js").Coordinate):number|undefined} The custom point\n * resolution function (if set).\n */\n\n\n Projection.prototype.getPointResolutionFunc = function () {\n return this.getPointResolutionFunc_;\n };\n\n return Projection;\n}();\n\n/* harmony default export */ var proj_Projection = (Projection);\n;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg3857.js\nvar epsg3857_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/proj/epsg3857\n */\n\n\n\n\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\n\nvar RADIUS = 6378137;\n/**\n * @const\n * @type {number}\n */\n\nvar HALF_SIZE = Math.PI * RADIUS;\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar EXTENT = [-HALF_SIZE, -HALF_SIZE, HALF_SIZE, HALF_SIZE];\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar WORLD_EXTENT = [-180, -85, 180, 85];\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\n\nvar MAX_SAFE_Y = RADIUS * Math.log(Math.tan(Math.PI / 2));\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\n\nvar EPSG3857Projection =\n/** @class */\nfunction (_super) {\n epsg3857_extends(EPSG3857Projection, _super);\n /**\n * @param {string} code Code.\n */\n\n\n function EPSG3857Projection(code) {\n return _super.call(this, {\n code: code,\n units: proj_Units.METERS,\n extent: EXTENT,\n global: true,\n worldExtent: WORLD_EXTENT,\n getPointResolution: function getPointResolution(resolution, point) {\n return resolution / cosh(point[1] / RADIUS);\n }\n }) || this;\n }\n\n return EPSG3857Projection;\n}(proj_Projection);\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar PROJECTIONS = [new EPSG3857Projection(\'EPSG:3857\'), new EPSG3857Projection(\'EPSG:102100\'), new EPSG3857Projection(\'EPSG:102113\'), new EPSG3857Projection(\'EPSG:900913\'), new EPSG3857Projection(\'http://www.opengis.net/gml/srs/epsg.xml#3857\')];\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction fromEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = HALF_SIZE * input[i] / 180;\n var y = RADIUS * Math.log(Math.tan(Math.PI * (+input[i + 1] + 90) / 360));\n\n if (y > MAX_SAFE_Y) {\n y = MAX_SAFE_Y;\n } else if (y < -MAX_SAFE_Y) {\n y = -MAX_SAFE_Y;\n }\n\n output[i + 1] = y;\n }\n\n return output;\n}\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction toEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = 180 * input[i] / HALF_SIZE;\n output[i + 1] = 360 * Math.atan(Math.exp(input[i + 1] / RADIUS)) / Math.PI - 90;\n }\n\n return output;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj/epsg4326.js\nvar epsg4326_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/proj/epsg4326\n */\n\n\n\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\n\nvar epsg4326_RADIUS = 6378137;\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar epsg4326_EXTENT = [-180, -90, 180, 90];\n/**\n * @const\n * @type {number}\n */\n\nvar epsg4326_METERS_PER_UNIT = Math.PI * epsg4326_RADIUS / 180;\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\n\nvar EPSG4326Projection =\n/** @class */\nfunction (_super) {\n epsg4326_extends(EPSG4326Projection, _super);\n /**\n * @param {string} code Code.\n * @param {string=} opt_axisOrientation Axis orientation.\n */\n\n\n function EPSG4326Projection(code, opt_axisOrientation) {\n return _super.call(this, {\n code: code,\n units: proj_Units.DEGREES,\n extent: epsg4326_EXTENT,\n axisOrientation: opt_axisOrientation,\n global: true,\n metersPerUnit: epsg4326_METERS_PER_UNIT,\n worldExtent: epsg4326_EXTENT\n }) || this;\n }\n\n return EPSG4326Projection;\n}(proj_Projection);\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar epsg4326_PROJECTIONS = [new EPSG4326Projection(\'CRS:84\'), new EPSG4326Projection(\'EPSG:4326\', \'neu\'), new EPSG4326Projection(\'urn:ogc:def:crs:OGC:1.3:CRS84\'), new EPSG4326Projection(\'urn:ogc:def:crs:OGC:2:84\'), new EPSG4326Projection(\'http://www.opengis.net/gml/srs/epsg.xml#4326\', \'neu\')];\n;// CONCATENATED MODULE: ./node_modules/ol/proj/projections.js\n/**\n * @module ol/proj/projections\n */\n\n/**\n * @type {Object<string, import("./Projection.js").default>}\n */\nvar cache = {};\n/**\n * Clear the projections cache.\n */\n\nfunction projections_clear() {\n cache = {};\n}\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import("./Projection.js").default} The projection (if cached).\n */\n\nfunction get(code) {\n return cache[code] || cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, \'EPSG:$3\')] || null;\n}\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import("./Projection.js").default} projection The projection to cache.\n */\n\nfunction projections_add(code, projection) {\n cache[code] = projection;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj/transforms.js\n/**\n * @module ol/proj/transforms\n */\n\n/**\n * @private\n * @type {!Object<string, Object<string, import("../proj.js").TransformFunction>>}\n */\n\nvar transforms = {};\n/**\n * Clear the transform cache.\n */\n\nfunction transforms_clear() {\n transforms = {};\n}\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import("./Projection.js").default} source Source.\n * @param {import("./Projection.js").default} destination Destination.\n * @param {import("../proj.js").TransformFunction} transformFn Transform.\n */\n\nfunction transforms_add(source, destination, transformFn) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n\n if (!(sourceCode in transforms)) {\n transforms[sourceCode] = {};\n }\n\n transforms[sourceCode][destinationCode] = transformFn;\n}\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection. This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import("./Projection.js").default} source Source projection.\n * @param {import("./Projection.js").default} destination Destination projection.\n * @return {import("../proj.js").TransformFunction} transformFn The unregistered transform.\n */\n\nfunction transforms_remove(source, destination) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n var transform = transforms[sourceCode][destinationCode];\n delete transforms[sourceCode][destinationCode];\n\n if (isEmpty(transforms[sourceCode])) {\n delete transforms[sourceCode];\n }\n\n return transform;\n}\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import("../proj.js").TransformFunction|undefined} The transform function (if found).\n */\n\nfunction transforms_get(sourceCode, destinationCode) {\n var transform;\n\n if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {\n transform = transforms[sourceCode][destinationCode];\n }\n\n return transform;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/sphere.js\n/**\n * @module ol/sphere\n */\n\n\n/**\n * Object literal with options for the {@link getLength} or {@link getArea}\n * functions.\n * @typedef {Object} SphereMetricOptions\n * @property {import("./proj.js").ProjectionLike} [projection=\'EPSG:3857\']\n * Projection of the geometry. By default, the geometry is assumed to be in\n * Web Mercator.\n * @property {number} [radius=6371008.8] Sphere radius. By default, the\n * [mean Earth radius](https://en.wikipedia.org/wiki/Earth_radius#Mean_radius)\n * for the WGS84 ellipsoid is used.\n */\n\n/**\n * The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.\n * https://en.wikipedia.org/wiki/Earth_radius#Mean_radius\n * @type {number}\n */\n\nvar DEFAULT_RADIUS = 6371008.8;\n/**\n * Get the great circle distance (in meters) between two geographic coordinates.\n * @param {Array} c1 Starting coordinate.\n * @param {Array} c2 Ending coordinate.\n * @param {number=} opt_radius The sphere radius to use. Defaults to the Earth\'s\n * mean radius using the WGS84 ellipsoid.\n * @return {number} The great circle distance between the points (in meters).\n * @api\n */\n\nfunction sphere_getDistance(c1, c2, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = math_toRadians(c1[1]);\n var lat2 = math_toRadians(c2[1]);\n var deltaLatBy2 = (lat2 - lat1) / 2;\n var deltaLonBy2 = math_toRadians(c2[0] - c1[0]) / 2;\n var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * Math.cos(lat1) * Math.cos(lat2);\n return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n}\n/**\n * Get the cumulative great circle length of linestring coordinates (geographic).\n * @param {Array} coordinates Linestring coordinates.\n * @param {number} radius The sphere radius to use.\n * @return {number} The length (in meters).\n */\n\nfunction getLengthInternal(coordinates, radius) {\n var length = 0;\n\n for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {\n length += sphere_getDistance(coordinates[i], coordinates[i + 1], radius);\n }\n\n return length;\n}\n/**\n * Get the spherical length of a geometry. This length is the sum of the\n * great circle distances between coordinates. For polygons, the length is\n * the sum of all rings. For points, the length is zero. For multi-part\n * geometries, the length is the sum of the length of each part.\n * @param {import("./geom/Geometry.js").default} geometry A geometry.\n * @param {SphereMetricOptions=} opt_options Options for the\n * length calculation. By default, geometries are assumed to be in \'EPSG:3857\'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical length (in meters).\n * @api\n */\n\n\nfunction getLength(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || \'EPSG:3857\';\n var type = geometry.getType();\n\n if (type !== GeometryType.GEOMETRY_COLLECTION) {\n geometry = geometry.clone().transform(projection, \'EPSG:4326\');\n }\n\n var length = 0;\n var coordinates, coords, i, ii, j, jj;\n\n switch (type) {\n case GeometryType.POINT:\n case GeometryType.MULTI_POINT:\n {\n break;\n }\n\n case GeometryType.LINE_STRING:\n case GeometryType.LINEAR_RING:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n length = getLengthInternal(coordinates, radius);\n break;\n }\n\n case GeometryType.MULTI_LINE_STRING:\n case GeometryType.POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n length += getLengthInternal(coordinates[i], radius);\n }\n\n break;\n }\n\n case GeometryType.MULTI_POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n\n for (j = 0, jj = coords.length; j < jj; ++j) {\n length += getLengthInternal(coords[j], radius);\n }\n }\n\n break;\n }\n\n case GeometryType.GEOMETRY_COLLECTION:\n {\n var geometries =\n /** @type {import("./geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n length += getLength(geometries[i], opt_options);\n }\n\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported geometry type: \' + type);\n }\n }\n\n return length;\n}\n/**\n * Returns the spherical area for a list of coordinates.\n *\n * [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)\n * Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for\n * Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion\n * Laboratory, Pasadena, CA, June 2007\n *\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates List of coordinates of a linear\n * ring. If the ring is oriented clockwise, the area will be positive,\n * otherwise it will be negative.\n * @param {number} radius The sphere radius.\n * @return {number} Area (in square meters).\n */\n\nfunction getAreaInternal(coordinates, radius) {\n var area = 0;\n var len = coordinates.length;\n var x1 = coordinates[len - 1][0];\n var y1 = coordinates[len - 1][1];\n\n for (var i = 0; i < len; i++) {\n var x2 = coordinates[i][0];\n var y2 = coordinates[i][1];\n area += toRadians(x2 - x1) * (2 + Math.sin(toRadians(y1)) + Math.sin(toRadians(y2)));\n x1 = x2;\n y1 = y2;\n }\n\n return area * radius * radius / 2.0;\n}\n/**\n * Get the spherical area of a geometry. This is the area (in meters) assuming\n * that polygon edges are segments of great circles on a sphere.\n * @param {import("./geom/Geometry.js").default} geometry A geometry.\n * @param {SphereMetricOptions=} opt_options Options for the area\n * calculation. By default, geometries are assumed to be in \'EPSG:3857\'.\n * You can change this by providing a `projection` option.\n * @return {number} The spherical area (in square meters).\n * @api\n */\n\n\nfunction sphere_getArea(geometry, opt_options) {\n var options = opt_options || {};\n var radius = options.radius || DEFAULT_RADIUS;\n var projection = options.projection || \'EPSG:3857\';\n var type = geometry.getType();\n\n if (type !== GeometryType.GEOMETRY_COLLECTION) {\n geometry = geometry.clone().transform(projection, \'EPSG:4326\');\n }\n\n var area = 0;\n var coordinates, coords, i, ii, j, jj;\n\n switch (type) {\n case GeometryType.POINT:\n case GeometryType.MULTI_POINT:\n case GeometryType.LINE_STRING:\n case GeometryType.MULTI_LINE_STRING:\n case GeometryType.LINEAR_RING:\n {\n break;\n }\n\n case GeometryType.POLYGON:\n {\n coordinates =\n /** @type {import("./geom/Polygon.js").default} */\n geometry.getCoordinates();\n area = Math.abs(getAreaInternal(coordinates[0], radius));\n\n for (i = 1, ii = coordinates.length; i < ii; ++i) {\n area -= Math.abs(getAreaInternal(coordinates[i], radius));\n }\n\n break;\n }\n\n case GeometryType.MULTI_POLYGON:\n {\n coordinates =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometry.getCoordinates();\n\n for (i = 0, ii = coordinates.length; i < ii; ++i) {\n coords = coordinates[i];\n area += Math.abs(getAreaInternal(coords[0], radius));\n\n for (j = 1, jj = coords.length; j < jj; ++j) {\n area -= Math.abs(getAreaInternal(coords[j], radius));\n }\n }\n\n break;\n }\n\n case GeometryType.GEOMETRY_COLLECTION:\n {\n var geometries =\n /** @type {import("./geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n area += sphere_getArea(geometries[i], opt_options);\n }\n\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported geometry type: \' + type);\n }\n }\n\n return area;\n}\n/**\n * Returns the coordinate at the given distance and bearing from `c1`.\n *\n * @param {import("./coordinate.js").Coordinate} c1 The origin point (`[lon, lat]` in degrees).\n * @param {number} distance The great-circle distance between the origin\n * point and the target point.\n * @param {number} bearing The bearing (in radians).\n * @param {number=} opt_radius The sphere radius to use. Defaults to the Earth\'s\n * mean radius using the WGS84 ellipsoid.\n * @return {import("./coordinate.js").Coordinate} The target point.\n */\n\nfunction offset(c1, distance, bearing, opt_radius) {\n var radius = opt_radius || DEFAULT_RADIUS;\n var lat1 = toRadians(c1[1]);\n var lon1 = toRadians(c1[0]);\n var dByR = distance / radius;\n var lat = Math.asin(Math.sin(lat1) * Math.cos(dByR) + Math.cos(lat1) * Math.sin(dByR) * Math.cos(bearing));\n var lon = lon1 + Math.atan2(Math.sin(bearing) * Math.sin(dByR) * Math.cos(lat1), Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));\n return [toDegrees(lon), toDegrees(lat)];\n}\n;// CONCATENATED MODULE: ./node_modules/ol/proj.js\n/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4\'s registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don\'t\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get(\'EPSG:1234\').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj~addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection} object for the new projection and add it with\n * {@link module:ol/proj~addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj~addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection} with\n * {@link module:ol/proj~addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * A projection as {@link module:ol/proj/Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2). The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\n\n\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n * values).\n */\n\nfunction cloneTransform(input, opt_output, opt_dimension) {\n var output;\n\n if (opt_output !== undefined) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n output = opt_output;\n } else {\n output = input.slice();\n }\n\n return output;\n}\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\n\nfunction identityTransform(input, opt_output, opt_dimension) {\n if (opt_output !== undefined && input !== opt_output) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n input = opt_output;\n }\n\n return input;\n}\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\n\nfunction addProjection(projection) {\n projections_add(projection.getCode(), projection);\n transforms_add(projection, projection, cloneTransform);\n}\n/**\n * @param {Array<Projection>} projections Projections.\n */\n\nfunction addProjections(projections) {\n projections.forEach(addProjection);\n}\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n * a combination of authority and identifier such as "EPSG:4326", or an\n * existing projection object, or undefined.\n * @return {Projection} Projection object, or null if not in list.\n * @api\n */\n\nfunction proj_get(projectionLike) {\n return typeof projectionLike === \'string\' ? get(\n /** @type {string} */\n projectionLike) :\n /** @type {Projection} */\n projectionLike || null;\n}\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the \'point\' pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import("./coordinate.js").Coordinate} point Point to find adjusted resolution at.\n * @param {import("./proj/Units.js").default=} opt_units Units to get the point resolution in.\n * Default is the projection\'s units.\n * @return {number} Point resolution.\n * @api\n */\n\nfunction getPointResolution(projection, resolution, point, opt_units) {\n projection = proj_get(projection);\n var pointResolution;\n var getter = projection.getPointResolutionFunc();\n\n if (getter) {\n pointResolution = getter(resolution, point);\n\n if (opt_units && opt_units !== projection.getUnits()) {\n var metersPerUnit = projection.getMetersPerUnit();\n\n if (metersPerUnit) {\n pointResolution = pointResolution * metersPerUnit / Units_METERS_PER_UNIT[opt_units];\n }\n }\n } else {\n var units = projection.getUnits();\n\n if (units == proj_Units.DEGREES && !opt_units || opt_units == proj_Units.DEGREES) {\n pointResolution = resolution;\n } else {\n // Estimate point resolution by transforming the center pixel to EPSG:4326,\n // measuring its width and height on the normal sphere, and taking the\n // average of the width and height.\n var toEPSG4326_1 = getTransformFromProjections(projection, proj_get(\'EPSG:4326\'));\n\n if (toEPSG4326_1 === identityTransform && units !== proj_Units.DEGREES) {\n // no transform is available\n pointResolution = resolution * projection.getMetersPerUnit();\n } else {\n var vertices = [point[0] - resolution / 2, point[1], point[0] + resolution / 2, point[1], point[0], point[1] - resolution / 2, point[0], point[1] + resolution / 2];\n vertices = toEPSG4326_1(vertices, vertices, 2);\n var width = sphere_getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n var height = sphere_getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n pointResolution = (width + height) / 2;\n }\n\n var metersPerUnit = opt_units ? Units_METERS_PER_UNIT[opt_units] : projection.getMetersPerUnit();\n\n if (metersPerUnit !== undefined) {\n pointResolution /= metersPerUnit;\n }\n }\n }\n\n return pointResolution;\n}\n/**\n * Registers transformation functions that don\'t alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\n\nfunction addEquivalentProjections(projections) {\n addProjections(projections);\n projections.forEach(function (source) {\n projections.forEach(function (destination) {\n if (source !== destination) {\n transforms_add(source, destination, cloneTransform);\n }\n });\n });\n}\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n * meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n * meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n * projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n * in projection2 to any projection in projection1..\n */\n\nfunction addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {\n projections1.forEach(function (projection1) {\n projections2.forEach(function (projection2) {\n transforms_add(projection1, projection2, forwardTransform);\n transforms_add(projection2, projection1, inverseTransform);\n });\n });\n}\n/**\n * Clear all cached projections and transforms.\n */\n\nfunction clearAllProjections() {\n clearProj();\n clearTransformFuncs();\n}\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\n\nfunction createProjection(projection, defaultCode) {\n if (!projection) {\n return proj_get(defaultCode);\n } else if (typeof projection === \'string\') {\n return proj_get(projection);\n } else {\n return (\n /** @type {Projection} */\n projection\n );\n }\n}\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} coordTransform Coordinate\n * transform.\n * @return {TransformFunction} Transform function.\n */\n\nfunction createTransformFromCoordinateTransform(coordTransform) {\n return (\n /**\n * @param {Array<number>} input Input.\n * @param {Array<number>=} opt_output Output.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output.\n */\n function (input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension !== undefined ? opt_dimension : 2;\n var output = opt_output !== undefined ? opt_output : new Array(length);\n\n for (var i = 0; i < length; i += dimension) {\n var point = coordTransform([input[i], input[i + 1]]);\n output[i] = point[0];\n output[i + 1] = point[1];\n\n for (var j = dimension - 1; j >= 2; --j) {\n output[i + j] = input[i + j];\n }\n }\n\n return output;\n }\n );\n}\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} forward The forward transform\n * function (that is, from the source projection to the destination\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform\n * function (that is, from the destination projection to the source\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @api\n */\n\nfunction addCoordinateTransforms(source, destination, forward, inverse) {\n var sourceProj = proj_get(source);\n var destProj = proj_get(destination);\n addTransformFunc(sourceProj, destProj, createTransformFromCoordinateTransform(forward));\n addTransformFunc(destProj, sourceProj, createTransformFromCoordinateTransform(inverse));\n}\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n * an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike=} opt_projection Target projection. The\n * default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate projected to the target projection.\n * @api\n */\n\nfunction fromLonLat(coordinate, opt_projection) {\n return transform(coordinate, \'EPSG:4326\', opt_projection !== undefined ? opt_projection : \'EPSG:3857\');\n}\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import("./coordinate.js").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike=} opt_projection Projection of the coordinate.\n * The default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate as longitude and latitude, i.e. an array\n * with longitude as 1st and latitude as 2nd element.\n * @api\n */\n\nfunction toLonLat(coordinate, opt_projection) {\n var lonLat = transform(coordinate, opt_projection !== undefined ? opt_projection : \'EPSG:3857\', \'EPSG:4326\');\n var lon = lonLat[0];\n\n if (lon < -180 || lon > 180) {\n lonLat[0] = modulo(lon + 180, 360) - 180;\n }\n\n return lonLat;\n}\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\n\nfunction equivalent(projection1, projection2) {\n if (projection1 === projection2) {\n return true;\n }\n\n var equalUnits = projection1.getUnits() === projection2.getUnits();\n\n if (projection1.getCode() === projection2.getCode()) {\n return equalUnits;\n } else {\n var transformFunc = getTransformFromProjections(projection1, projection2);\n return transformFunc === cloneTransform && equalUnits;\n }\n}\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n * object.\n * @return {TransformFunction} Transform function.\n */\n\nfunction getTransformFromProjections(sourceProjection, destinationProjection) {\n var sourceCode = sourceProjection.getCode();\n var destinationCode = destinationProjection.getCode();\n var transformFunc = transforms_get(sourceCode, destinationCode);\n\n if (!transformFunc) {\n transformFunc = identityTransform;\n }\n\n return transformFunc;\n}\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\n\nfunction getTransform(source, destination) {\n var sourceProjection = proj_get(source);\n var destinationProjection = proj_get(destination);\n return getTransformFromProjections(sourceProjection, destinationProjection);\n}\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj~transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\nfunction transform(coordinate, source, destination) {\n var transformFunc = getTransform(source, destination);\n return transformFunc(coordinate, undefined, coordinate.length);\n}\n/**\n * Transforms an extent from source projection to destination projection. This\n * returns a new extent (and does not modify the original).\n *\n * @param {import("./extent.js").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import("./extent.js").Extent} The transformed extent.\n * @api\n */\n\nfunction proj_transformExtent(extent, source, destination, opt_stops) {\n var transformFunc = getTransform(source, destination);\n return applyTransform(extent, transformFunc, undefined, opt_stops);\n}\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import("./coordinate.js").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import("./coordinate.js").Coordinate} Point.\n */\n\nfunction transformWithProjections(point, sourceProjection, destinationProjection) {\n var transformFunc = getTransformFromProjections(sourceProjection, destinationProjection);\n return transformFunc(point);\n}\n/**\n * @type {?Projection}\n */\n\nvar userProjection = null;\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @param {ProjectionLike} projection The user projection.\n */\n\nfunction setUserProjection(projection) {\n userProjection = proj_get(projection);\n}\n/**\n * Clear the user projection if set. Note that this method is not yet a part of\n * the stable API. Support for user projections is not yet complete and should\n * be considered experimental.\n */\n\nfunction clearUserProjection() {\n userProjection = null;\n}\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @returns {?Projection} The user projection (or null if not set).\n */\n\nfunction getUserProjection() {\n return userProjection;\n}\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods. Note that this\n * method is not yet a part of the stable API. Support for user projections is\n * not yet complete and should be considered experimental.\n */\n\nfunction useGeographic() {\n setUserProjection(\'EPSG:4326\');\n}\n/**\n * Return a coordinate transformed into the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @returns {Array<number>} The input coordinate in the user projection.\n */\n\nfunction toUserCoordinate(coordinate, sourceProjection) {\n if (!userProjection) {\n return coordinate;\n }\n\n return transform(coordinate, sourceProjection, userProjection);\n}\n/**\n * Return a coordinate transformed from the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {Array<number>} The input coordinate transformed.\n */\n\nfunction fromUserCoordinate(coordinate, destProjection) {\n if (!userProjection) {\n return coordinate;\n }\n\n return transform(coordinate, userProjection, destProjection);\n}\n/**\n * Return an extent transformed into the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @returns {import("./extent.js").Extent} The input extent in the user projection.\n */\n\nfunction toUserExtent(extent, sourceProjection) {\n if (!userProjection) {\n return extent;\n }\n\n return proj_transformExtent(extent, sourceProjection, userProjection);\n}\n/**\n * Return an extent transformed from the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {import("./extent.js").Extent} The input extent transformed.\n */\n\nfunction fromUserExtent(extent, destProjection) {\n if (!userProjection) {\n return extent;\n }\n\n return proj_transformExtent(extent, userProjection, destProjection);\n}\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * "Safe" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent\'s range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} transform Transform function (source to destiation).\n * @return {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} Safe transform function (source to destiation).\n */\n\nfunction createSafeCoordinateTransform(sourceProj, destProj, transform) {\n return function (coord) {\n var sourceX = coord[0];\n var sourceY = coord[1];\n var transformed, worldsAway;\n\n if (sourceProj.canWrapX()) {\n var sourceExtent = sourceProj.getExtent();\n var sourceExtentWidth = getWidth(sourceExtent);\n worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n\n if (worldsAway) {\n // Move x to the real world\n sourceX = sourceX - worldsAway * sourceExtentWidth;\n }\n\n sourceX = clamp(sourceX, sourceExtent[0], sourceExtent[2]);\n sourceY = clamp(sourceY, sourceExtent[1], sourceExtent[3]);\n transformed = transform([sourceX, sourceY]);\n } else {\n transformed = transform(coord);\n }\n\n if (worldsAway && destProj.canWrapX()) {\n // Move transformed coordinate back to the offset world\n transformed[0] += worldsAway * getWidth(destProj.getExtent());\n }\n\n return transformed;\n };\n}\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\n\nfunction addCommon() {\n // Add transformations that don\'t alter coordinates to convert within set of\n // projections with equal meaning.\n addEquivalentProjections(PROJECTIONS);\n addEquivalentProjections(epsg4326_PROJECTIONS); // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n // coordinates and back.\n\n addEquivalentTransforms(epsg4326_PROJECTIONS, PROJECTIONS, fromEPSG4326, toEPSG4326);\n}\naddCommon();\n;// CONCATENATED MODULE: ./node_modules/ol/centerconstraint.js\n/**\n * @module ol/centerconstraint\n */\n\n/**\n * @typedef {function((import("./coordinate.js").Coordinate|undefined), number, import("./size.js").Size, boolean=, Array<number>=): (import("./coordinate.js").Coordinate|undefined)} Type\n */\n\n/**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {boolean} onlyCenter If true, the constraint will only apply to the view center.\n * @param {boolean} smooth If true, the view will be able to go slightly out of the given extent\n * (only during interaction and animation).\n * @return {Type} The constraint.\n */\n\nfunction createExtent(extent, onlyCenter, smooth) {\n return (\n /**\n * @param {import("./coordinate.js").Coordinate|undefined} center Center.\n * @param {number} resolution Resolution.\n * @param {import("./size.js").Size} size Viewport size; unused if `onlyCenter` was specified.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @param {Array<number>=} opt_centerShift Shift between map center and viewport center.\n * @return {import("./coordinate.js").Coordinate|undefined} Center.\n */\n function (center, resolution, size, opt_isMoving, opt_centerShift) {\n if (center) {\n var viewWidth = onlyCenter ? 0 : size[0] * resolution;\n var viewHeight = onlyCenter ? 0 : size[1] * resolution;\n var shiftX = opt_centerShift ? opt_centerShift[0] : 0;\n var shiftY = opt_centerShift ? opt_centerShift[1] : 0;\n var minX = extent[0] + viewWidth / 2 + shiftX;\n var maxX = extent[2] - viewWidth / 2 + shiftX;\n var minY = extent[1] + viewHeight / 2 + shiftY;\n var maxY = extent[3] - viewHeight / 2 + shiftY; // note: when zooming out of bounds, min and max values for x and y may\n // end up inverted (min > max); this has to be accounted for\n\n if (minX > maxX) {\n minX = (maxX + minX) / 2;\n maxX = minX;\n }\n\n if (minY > maxY) {\n minY = (maxY + minY) / 2;\n maxY = minY;\n }\n\n var x = math_clamp(center[0], minX, maxX);\n var y = math_clamp(center[1], minY, maxY);\n var ratio = 30 * resolution; // during an interaction, allow some overscroll\n\n if (opt_isMoving && smooth) {\n x += -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) + ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);\n y += -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) + ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);\n }\n\n return [x, y];\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {import("./coordinate.js").Coordinate=} center Center.\n * @return {import("./coordinate.js").Coordinate|undefined} Center.\n */\n\nfunction none(center) {\n return center;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/resolutionconstraint.js\n/**\n * @module ol/resolutionconstraint\n */\n\n\n\n/**\n * @typedef {function((number|undefined), number, import("./size.js").Size, boolean=): (number|undefined)} Type\n */\n\n/**\n * Returns a modified resolution taking into account the viewport size and maximum\n * allowed extent.\n * @param {number} resolution Resolution\n * @param {import("./extent.js").Extent} maxExtent Maximum allowed extent.\n * @param {import("./size.js").Size} viewportSize Viewport size.\n * @param {boolean} showFullExtent Whether to show the full extent.\n * @return {number} Capped resolution.\n */\n\nfunction getViewportClampedResolution(resolution, maxExtent, viewportSize, showFullExtent) {\n var xResolution = extent_getWidth(maxExtent) / viewportSize[0];\n var yResolution = getHeight(maxExtent) / viewportSize[1];\n\n if (showFullExtent) {\n return Math.min(resolution, Math.max(xResolution, yResolution));\n }\n\n return Math.min(resolution, Math.min(xResolution, yResolution));\n}\n/**\n * Returns a modified resolution to be between maxResolution and minResolution while\n * still allowing the value to be slightly out of bounds.\n * Note: the computation is based on the logarithm function (ln):\n * - at 1, ln(x) is 0\n * - above 1, ln(x) keeps increasing but at a much slower pace than x\n * The final result is clamped to prevent getting too far away from bounds.\n * @param {number} resolution Resolution.\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @return {number} Smoothed resolution.\n */\n\n\nfunction getSmoothClampedResolution(resolution, maxResolution, minResolution) {\n var result = Math.min(resolution, maxResolution);\n var ratio = 50;\n result *= Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio + 1;\n\n if (minResolution) {\n result = Math.max(result, minResolution);\n result /= Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) / ratio + 1;\n }\n\n return math_clamp(result, minResolution / 2, maxResolution * 2);\n}\n/**\n * @param {Array<number>} resolutions Resolutions.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\n\nfunction createSnapToResolutions(resolutions, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var maxResolution = resolutions[0];\n var minResolution = resolutions[resolutions.length - 1];\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution; // during interacting or animating, allow intermediary values\n\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n\n var capped = Math.min(cappedMaxRes, resolution);\n var z = Math.floor(linearFindNearest(resolutions, capped, direction));\n\n if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {\n return resolutions[z + 1];\n }\n\n return resolutions[z];\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number} power Power.\n * @param {number} maxResolution Maximum resolution.\n * @param {number=} opt_minResolution Minimum resolution.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\nfunction createSnapToPower(power, maxResolution, opt_minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution;\n var minResolution = opt_minResolution !== undefined ? opt_minResolution : 0; // during interacting or animating, allow intermediary values\n\n if (opt_isMoving) {\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n }\n\n var tolerance = 1e-9;\n var minZoomLevel = Math.ceil(Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance);\n var offset = -direction * (0.5 - tolerance) + 0.5;\n var capped = Math.min(cappedMaxRes, resolution);\n var cappedZoomLevel = Math.floor(Math.log(maxResolution / capped) / Math.log(power) + offset);\n var zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);\n var newResolution = maxResolution / Math.pow(power, zoomLevel);\n return math_clamp(newResolution, minResolution, cappedMaxRes);\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @param {boolean=} opt_smooth If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import("./extent.js").Extent=} opt_maxExtent Maximum allowed extent.\n * @param {boolean=} opt_showFullExtent If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\n\nfunction createMinMaxResolution(maxResolution, minResolution, opt_smooth, opt_maxExtent, opt_showFullExtent) {\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import("./size.js").Size} size Viewport size.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, opt_isMoving) {\n if (resolution !== undefined) {\n var cappedMaxRes = opt_maxExtent ? getViewportClampedResolution(maxResolution, opt_maxExtent, size, opt_showFullExtent) : maxResolution;\n var smooth = opt_smooth !== undefined ? opt_smooth : true;\n\n if (!smooth || !opt_isMoving) {\n return math_clamp(resolution, minResolution, cappedMaxRes);\n }\n\n return getSmoothClampedResolution(resolution, cappedMaxRes, minResolution);\n } else {\n return undefined;\n }\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/rotationconstraint.js\n/**\n * @module ol/rotationconstraint\n */\n\n/**\n * @typedef {function((number|undefined), boolean=): (number|undefined)} Type\n */\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\n\nfunction disable(rotation) {\n if (rotation !== undefined) {\n return 0;\n } else {\n return undefined;\n }\n}\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\n\nfunction rotationconstraint_none(rotation) {\n if (rotation !== undefined) {\n return rotation;\n } else {\n return undefined;\n }\n}\n/**\n * @param {number} n N.\n * @return {Type} Rotation constraint.\n */\n\nfunction createSnapToN(n) {\n var theta = 2 * Math.PI / n;\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n\n if (rotation !== undefined) {\n rotation = Math.floor(rotation / theta + 0.5) * theta;\n return rotation;\n } else {\n return undefined;\n }\n }\n );\n}\n/**\n * @param {number=} opt_tolerance Tolerance.\n * @return {Type} Rotation constraint.\n */\n\nfunction createSnapToZero(opt_tolerance) {\n var tolerance = opt_tolerance || math_toRadians(5);\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean=} opt_isMoving True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, opt_isMoving) {\n if (opt_isMoving) {\n return rotation;\n }\n\n if (rotation !== undefined) {\n if (Math.abs(rotation) <= tolerance) {\n return 0;\n } else {\n return rotation;\n }\n } else {\n return undefined;\n }\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/easing.js\n/**\n * @module ol/easing\n */\n\n/**\n * Start slow and speed up.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\nfunction easeIn(t) {\n return Math.pow(t, 3);\n}\n/**\n * Start fast and slow down.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction easeOut(t) {\n return 1 - easeIn(1 - t);\n}\n/**\n * Start slow, speed up, and then slow down again.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction inAndOut(t) {\n return 3 * t * t - 2 * t * t * t;\n}\n/**\n * Maintain a constant speed over time.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction linear(t) {\n return t;\n}\n/**\n * Start slow, speed up, and at the very end slow down again. This has the\n * same general behavior as {@link module:ol/easing~inAndOut}, but the final\n * slowdown is delayed.\n * @param {number} t Input between 0 and 1.\n * @return {number} Output between 0 and 1.\n * @api\n */\n\nfunction upAndDown(t) {\n if (t < 0.5) {\n return inAndOut(2 * t);\n } else {\n return 1 - inAndOut(2 * (t - 0.5));\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryLayout.js\n/**\n * @module ol/geom/GeometryLayout\n */\n\n/**\n * The coordinate layout for geometries, indicating whether a 3rd or 4th z (\'Z\')\n * or measure (\'M\') coordinate is available. Supported values are `\'XY\'`,\n * `\'XYZ\'`, `\'XYM\'`, `\'XYZM\'`.\n * @enum {string}\n */\n/* harmony default export */ var geom_GeometryLayout = ({\n XY: \'XY\',\n XYZ: \'XYZ\',\n XYM: \'XYM\',\n XYZM: \'XYZM\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/transform.js\n/**\n * @module ol/geom/flat/transform\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\nfunction transform2D(flatCoordinates, offset, end, stride, transform, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var x = flatCoordinates[j];\n var y = flatCoordinates[j + 1];\n dest[i++] = transform[0] * x + transform[2] * y + transform[4];\n dest[i++] = transform[1] * x + transform[3] * y + transform[5];\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} angle Angle.\n * @param {Array<number>} anchor Rotation anchor point.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_rotate(flatCoordinates, offset, end, stride, angle, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var cos = Math.cos(angle);\n var sin = Math.sin(angle);\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + deltaX * cos - deltaY * sin;\n dest[i++] = anchorY + deltaX * sin + deltaY * cos;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * Scale the coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} sx Scale factor in the x-direction.\n * @param {number} sy Scale factor in the y-direction.\n * @param {Array<number>} anchor Scale anchor point.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_scale(flatCoordinates, offset, end, stride, sx, sy, anchor, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var anchorX = anchor[0];\n var anchorY = anchor[1];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n var deltaX = flatCoordinates[j] - anchorX;\n var deltaY = flatCoordinates[j + 1] - anchorY;\n dest[i++] = anchorX + sx * deltaX;\n dest[i++] = anchorY + sy * deltaY;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed coordinates.\n */\n\nfunction transform_translate(flatCoordinates, offset, end, stride, deltaX, deltaY, opt_dest) {\n var dest = opt_dest ? opt_dest : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n dest[i++] = flatCoordinates[j] + deltaX;\n dest[i++] = flatCoordinates[j + 1] + deltaY;\n\n for (var k = j + 2; k < j + stride; ++k) {\n dest[i++] = flatCoordinates[k];\n }\n }\n\n if (opt_dest && dest.length != i) {\n dest.length = i;\n }\n\n return dest;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Geometry.js\nvar Geometry_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Geometry\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @type {import("../transform.js").Transform}\n */\n\nvar tmpTransform = create();\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for vector geometries.\n *\n * To get notified of changes to the geometry, register a listener for the\n * generic `change` event on your geometry instance.\n *\n * @abstract\n * @api\n */\n\nvar Geometry =\n/** @class */\nfunction (_super) {\n Geometry_extends(Geometry, _super);\n\n function Geometry() {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n\n _this.extent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n\n _this.extentRevision_ = -1;\n /**\n * @protected\n * @type {number}\n */\n\n _this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n /**\n * @protected\n * @type {number}\n */\n\n _this.simplifiedGeometryRevision = 0;\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} revision The geometry revision.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n\n _this.simplifyTransformedInternal = memoizeOne(function (revision, squaredTolerance, opt_transform) {\n if (!opt_transform) {\n return this.getSimplifiedGeometry(squaredTolerance);\n }\n\n var clone = this.clone();\n clone.applyTransform(opt_transform);\n return clone.getSimplifiedGeometry(squaredTolerance);\n });\n return _this;\n }\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {Geometry} Simplified geometry.\n */\n\n\n Geometry.prototype.simplifyTransformed = function (squaredTolerance, opt_transform) {\n return this.simplifyTransformedInternal(this.getRevision(), squaredTolerance, opt_transform);\n };\n /**\n * Make a complete copy of the geometry.\n * @abstract\n * @return {!Geometry} Clone.\n */\n\n\n Geometry.prototype.clone = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Geometry.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n return util_abstract();\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n Geometry.prototype.containsXY = function (x, y) {\n var coord = this.getClosestPoint([x, y]);\n return coord[0] === x && coord[1] === y;\n };\n /**\n * Return the closest point of the geometry to the passed point as\n * {@link module:ol/coordinate~Coordinate coordinate}.\n * @param {import("../coordinate.js").Coordinate} point Point.\n * @param {import("../coordinate.js").Coordinate=} opt_closestPoint Closest point.\n * @return {import("../coordinate.js").Coordinate} Closest point.\n * @api\n */\n\n\n Geometry.prototype.getClosestPoint = function (point, opt_closestPoint) {\n var closestPoint = opt_closestPoint ? opt_closestPoint : [NaN, NaN];\n this.closestPointXY(point[0], point[1], closestPoint, Infinity);\n return closestPoint;\n };\n /**\n * Returns true if this geometry includes the specified coordinate. If the\n * coordinate is on the boundary of the geometry, returns false.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains coordinate.\n * @api\n */\n\n\n Geometry.prototype.intersectsCoordinate = function (coordinate) {\n return this.containsXY(coordinate[0], coordinate[1]);\n };\n /**\n * @abstract\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n Geometry.prototype.computeExtent = function (extent) {\n return util_abstract();\n };\n /**\n * Get the extent of the geometry.\n * @param {import("../extent.js").Extent=} opt_extent Extent.\n * @return {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n Geometry.prototype.getExtent = function (opt_extent) {\n if (this.extentRevision_ != this.getRevision()) {\n var extent = this.computeExtent(this.extent_);\n\n if (isNaN(extent[0]) || isNaN(extent[1])) {\n createOrUpdateEmpty(extent);\n }\n\n this.extentRevision_ = this.getRevision();\n }\n\n return returnOrUpdate(this.extent_, opt_extent);\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} angle Rotation angle in radians.\n * @param {import("../coordinate.js").Coordinate} anchor The rotation center.\n * @api\n */\n\n\n Geometry.prototype.rotate = function (angle, anchor) {\n util_abstract();\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number=} opt_sy The scaling factor in the y-direction (defaults to sx).\n * @param {import("../coordinate.js").Coordinate=} opt_anchor The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n\n\n Geometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n util_abstract();\n };\n /**\n * Create a simplified version of this geometry. For linestrings, this uses\n * the [Douglas Peucker](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm)\n * algorithm. For polygons, a quantization-based\n * simplification is used to preserve topology.\n * @param {number} tolerance The tolerance distance for simplification.\n * @return {Geometry} A new, simplified version of the original geometry.\n * @api\n */\n\n\n Geometry.prototype.simplify = function (tolerance) {\n return this.getSimplifiedGeometry(tolerance * tolerance);\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker\n * algorithm.\n * See https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Geometry} Simplified geometry.\n */\n\n\n Geometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n return util_abstract();\n };\n /**\n * Get the type of this geometry.\n * @abstract\n * @return {import("./GeometryType.js").default} Geometry type.\n */\n\n\n Geometry.prototype.getType = function () {\n return util_abstract();\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @abstract\n * @param {import("../proj.js").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n */\n\n\n Geometry.prototype.applyTransform = function (transformFn) {\n util_abstract();\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @abstract\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n */\n\n\n Geometry.prototype.intersectsExtent = function (extent) {\n return util_abstract();\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @abstract\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n\n\n Geometry.prototype.translate = function (deltaX, deltaY) {\n util_abstract();\n };\n /**\n * Transform each coordinate of the geometry from one coordinate reference\n * system to another. The geometry is modified in place.\n * For example, a line will be transformed to a line and a circle to a circle.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n *\n * @param {import("../proj.js").ProjectionLike} source The current projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @param {import("../proj.js").ProjectionLike} destination The desired projection. Can be a\n * string identifier or a {@link module:ol/proj/Projection~Projection} object.\n * @return {Geometry} This geometry. Note that original geometry is\n * modified in place.\n * @api\n */\n\n\n Geometry.prototype.transform = function (source, destination) {\n /** @type {import("../proj/Projection.js").default} */\n var sourceProj = proj_get(source);\n var transformFn = sourceProj.getUnits() == proj_Units.TILE_PIXELS ? function (inCoordinates, outCoordinates, stride) {\n var pixelExtent = sourceProj.getExtent();\n var projectedExtent = sourceProj.getWorldExtent();\n var scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n compose(tmpTransform, projectedExtent[0], projectedExtent[3], scale, -scale, 0, 0, 0);\n transform2D(inCoordinates, 0, inCoordinates.length, stride, tmpTransform, outCoordinates);\n return getTransform(sourceProj, destination)(inCoordinates, outCoordinates, stride);\n } : getTransform(sourceProj, destination);\n this.applyTransform(transformFn);\n return this;\n };\n\n return Geometry;\n}(ol_Object);\n\n/* harmony default export */ var geom_Geometry = (Geometry);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/SimpleGeometry.js\nvar SimpleGeometry_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/SimpleGeometry\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Abstract base class; only used for creating subclasses; do not instantiate\n * in apps, as cannot be rendered.\n *\n * @abstract\n * @api\n */\n\nvar SimpleGeometry =\n/** @class */\nfunction (_super) {\n SimpleGeometry_extends(SimpleGeometry, _super);\n\n function SimpleGeometry() {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import("./GeometryLayout.js").default}\n */\n\n\n _this.layout = geom_GeometryLayout.XY;\n /**\n * @protected\n * @type {number}\n */\n\n _this.stride = 2;\n /**\n * @protected\n * @type {Array<number>}\n */\n\n _this.flatCoordinates = null;\n return _this;\n }\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n SimpleGeometry.prototype.computeExtent = function (extent) {\n return createOrUpdateFromFlatCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * @abstract\n * @return {Array<*>} Coordinates.\n */\n\n\n SimpleGeometry.prototype.getCoordinates = function () {\n return util_abstract();\n };\n /**\n * Return the first coordinate of the geometry.\n * @return {import("../coordinate.js").Coordinate} First coordinate.\n * @api\n */\n\n\n SimpleGeometry.prototype.getFirstCoordinate = function () {\n return this.flatCoordinates.slice(0, this.stride);\n };\n /**\n * @return {Array<number>} Flat coordinates.\n */\n\n\n SimpleGeometry.prototype.getFlatCoordinates = function () {\n return this.flatCoordinates;\n };\n /**\n * Return the last coordinate of the geometry.\n * @return {import("../coordinate.js").Coordinate} Last point.\n * @api\n */\n\n\n SimpleGeometry.prototype.getLastCoordinate = function () {\n return this.flatCoordinates.slice(this.flatCoordinates.length - this.stride);\n };\n /**\n * Return the {@link module:ol/geom/GeometryLayout layout} of the geometry.\n * @return {import("./GeometryLayout.js").default} Layout.\n * @api\n */\n\n\n SimpleGeometry.prototype.getLayout = function () {\n return this.layout;\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker algorithm.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n */\n\n\n SimpleGeometry.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n if (this.simplifiedGeometryRevision !== this.getRevision()) {\n this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n this.simplifiedGeometryRevision = this.getRevision();\n } // If squaredTolerance is negative or if we know that simplification will not\n // have any effect then just return this.\n\n\n if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance <= this.simplifiedGeometryMaxMinSquaredTolerance) {\n return this;\n }\n\n var simplifiedGeometry = this.getSimplifiedGeometryInternal(squaredTolerance);\n var simplifiedFlatCoordinates = simplifiedGeometry.getFlatCoordinates();\n\n if (simplifiedFlatCoordinates.length < this.flatCoordinates.length) {\n return simplifiedGeometry;\n } else {\n // Simplification did not actually remove any coordinates. We now know\n // that any calls to getSimplifiedGeometry with a squaredTolerance less\n // than or equal to the current squaredTolerance will also not have any\n // effect. This allows us to short circuit simplification (saving CPU\n // cycles) and prevents the cache of simplified geometries from filling\n // up with useless identical copies of this geometry (saving memory).\n this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n return this;\n }\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {SimpleGeometry} Simplified geometry.\n * @protected\n */\n\n\n SimpleGeometry.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n return this;\n };\n /**\n * @return {number} Stride.\n */\n\n\n SimpleGeometry.prototype.getStride = function () {\n return this.stride;\n };\n /**\n * @param {import("./GeometryLayout.js").default} layout Layout.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n */\n\n\n SimpleGeometry.prototype.setFlatCoordinates = function (layout, flatCoordinates) {\n this.stride = getStrideForLayout(layout);\n this.layout = layout;\n this.flatCoordinates = flatCoordinates;\n };\n /**\n * @abstract\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n SimpleGeometry.prototype.setCoordinates = function (coordinates, opt_layout) {\n util_abstract();\n };\n /**\n * @param {import("./GeometryLayout.js").default|undefined} layout Layout.\n * @param {Array<*>} coordinates Coordinates.\n * @param {number} nesting Nesting.\n * @protected\n */\n\n\n SimpleGeometry.prototype.setLayout = function (layout, coordinates, nesting) {\n /** @type {number} */\n var stride;\n\n if (layout) {\n stride = getStrideForLayout(layout);\n } else {\n for (var i = 0; i < nesting; ++i) {\n if (coordinates.length === 0) {\n this.layout = geom_GeometryLayout.XY;\n this.stride = 2;\n return;\n } else {\n coordinates =\n /** @type {Array} */\n coordinates[0];\n }\n }\n\n stride = coordinates.length;\n layout = getLayoutForStride(stride);\n }\n\n this.layout = layout;\n this.stride = stride;\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @param {import("../proj.js").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n * @api\n */\n\n\n SimpleGeometry.prototype.applyTransform = function (transformFn) {\n if (this.flatCoordinates) {\n transformFn(this.flatCoordinates, this.flatCoordinates, this.stride);\n this.changed();\n }\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @param {number} angle Rotation angle in counter-clockwise radians.\n * @param {import("../coordinate.js").Coordinate} anchor The rotation center.\n * @api\n */\n\n\n SimpleGeometry.prototype.rotate = function (angle, anchor) {\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_rotate(flatCoordinates, 0, flatCoordinates.length, stride, angle, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number=} opt_sy The scaling factor in the y-direction (defaults to sx).\n * @param {import("../coordinate.js").Coordinate=} opt_anchor The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n\n\n SimpleGeometry.prototype.scale = function (sx, opt_sy, opt_anchor) {\n var sy = opt_sy;\n\n if (sy === undefined) {\n sy = sx;\n }\n\n var anchor = opt_anchor;\n\n if (!anchor) {\n anchor = getCenter(this.getExtent());\n }\n\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_scale(flatCoordinates, 0, flatCoordinates.length, stride, sx, sy, anchor, flatCoordinates);\n this.changed();\n }\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n\n\n SimpleGeometry.prototype.translate = function (deltaX, deltaY) {\n var flatCoordinates = this.getFlatCoordinates();\n\n if (flatCoordinates) {\n var stride = this.getStride();\n transform_translate(flatCoordinates, 0, flatCoordinates.length, stride, deltaX, deltaY, flatCoordinates);\n this.changed();\n }\n };\n\n return SimpleGeometry;\n}(geom_Geometry);\n/**\n * @param {number} stride Stride.\n * @return {import("./GeometryLayout.js").default} layout Layout.\n */\n\n\nfunction getLayoutForStride(stride) {\n var layout;\n\n if (stride == 2) {\n layout = geom_GeometryLayout.XY;\n } else if (stride == 3) {\n layout = geom_GeometryLayout.XYZ;\n } else if (stride == 4) {\n layout = geom_GeometryLayout.XYZM;\n }\n\n return (\n /** @type {import("./GeometryLayout.js").default} */\n layout\n );\n}\n/**\n * @param {import("./GeometryLayout.js").default} layout Layout.\n * @return {number} Stride.\n */\n\n\nfunction getStrideForLayout(layout) {\n var stride;\n\n if (layout == geom_GeometryLayout.XY) {\n stride = 2;\n } else if (layout == geom_GeometryLayout.XYZ || layout == geom_GeometryLayout.XYM) {\n stride = 3;\n } else if (layout == geom_GeometryLayout.XYZM) {\n stride = 4;\n }\n\n return (\n /** @type {number} */\n stride\n );\n}\n/**\n * @param {SimpleGeometry} simpleGeometry Simple geometry.\n * @param {import("../transform.js").Transform} transform Transform.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Transformed flat coordinates.\n */\n\nfunction transformGeom2D(simpleGeometry, transform, opt_dest) {\n var flatCoordinates = simpleGeometry.getFlatCoordinates();\n\n if (!flatCoordinates) {\n return null;\n } else {\n var stride = simpleGeometry.getStride();\n return transform2D(flatCoordinates, 0, flatCoordinates.length, stride, transform, opt_dest);\n }\n}\n/* harmony default export */ var geom_SimpleGeometry = (SimpleGeometry);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/closest.js\n/**\n * @module ol/geom/flat/closest\n */\n\n/**\n * Returns the point on the 2D line segment flatCoordinates[offset1] to\n * flatCoordinates[offset2] that is closest to the point (x, y). Extra\n * dimensions are linearly interpolated.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset1 Offset 1.\n * @param {number} offset2 Offset 2.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n */\n\nfunction assignClosest(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) {\n var x1 = flatCoordinates[offset1];\n var y1 = flatCoordinates[offset1 + 1];\n var dx = flatCoordinates[offset2] - x1;\n var dy = flatCoordinates[offset2 + 1] - y1;\n var offset;\n\n if (dx === 0 && dy === 0) {\n offset = offset1;\n } else {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n offset = offset2;\n } else if (t > 0) {\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = lerp(flatCoordinates[offset1 + i], flatCoordinates[offset2 + i], t);\n }\n\n closestPoint.length = stride;\n return;\n } else {\n offset = offset1;\n }\n }\n\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n\n closestPoint.length = stride;\n}\n/**\n * Return the squared of the largest distance between any pair of consecutive\n * coordinates.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\n\nfunction maxSquaredDelta(flatCoordinates, offset, end, stride, max) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n\n for (offset += stride; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var squaredDelta = math_squaredDistance(x1, y1, x2, y2);\n\n if (squaredDelta > max) {\n max = squaredDelta;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\nfunction arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n max = maxSquaredDelta(flatCoordinates, offset, end, stride, max);\n offset = end;\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} max Max squared delta.\n * @return {number} Max squared delta.\n */\n\nfunction multiArrayMaxSquaredDelta(flatCoordinates, offset, endss, stride, max) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n max = arrayMaxSquaredDelta(flatCoordinates, offset, ends, stride, max);\n offset = ends[ends.length - 1];\n }\n\n return max;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n if (offset == end) {\n return minSquaredDistance;\n }\n\n var i, squaredDistance;\n\n if (maxDelta === 0) {\n // All points are identical, so just test the first point.\n squaredDistance = math_squaredDistance(x, y, flatCoordinates[offset], flatCoordinates[offset + 1]);\n\n if (squaredDistance < minSquaredDistance) {\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[offset + i];\n }\n\n closestPoint.length = stride;\n return squaredDistance;\n } else {\n return minSquaredDistance;\n }\n }\n\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n var index = offset + stride;\n\n while (index < end) {\n assignClosest(flatCoordinates, index - stride, index, stride, x, y, tmpPoint);\n squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n\n closestPoint.length = stride;\n index += stride;\n } else {\n // Skip ahead multiple points, because we know that all the skipped\n // points cannot be any closer than the closest point we have found so\n // far. We know this because we know how close the current point is, how\n // close the closest point we have found so far is, and the maximum\n // distance between consecutive points. For example, if we\'re currently\n // at distance 10, the best we\'ve found so far is 3, and that the maximum\n // distance between consecutive points is 2, then we\'ll need to skip at\n // least (10 - 3) / 2 == 3 (rounded down) points to have any chance of\n // finding a closer point. We use Math.max(..., 1) to ensure that we\n // always advance at least one point, to avoid an infinite loop.\n index += stride * Math.max((Math.sqrt(squaredDistance) - Math.sqrt(minSquaredDistance)) / maxDelta | 0, 1);\n }\n }\n\n if (isRing) {\n // Check the closing segment.\n assignClosest(flatCoordinates, end - stride, offset, stride, x, y, tmpPoint);\n squaredDistance = math_squaredDistance(x, y, tmpPoint[0], tmpPoint[1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (i = 0; i < stride; ++i) {\n closestPoint[i] = tmpPoint[i];\n }\n\n closestPoint.length = stride;\n }\n }\n\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n minSquaredDistance = assignClosestPoint(flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = end;\n }\n\n return minSquaredDistance;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} maxDelta Max delta.\n * @param {boolean} isRing Is ring.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {Array<number>} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @param {Array<number>=} opt_tmpPoint Temporary point object.\n * @return {number} Minimum squared distance.\n */\n\nfunction assignClosestMultiArrayPoint(flatCoordinates, offset, endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) {\n var tmpPoint = opt_tmpPoint ? opt_tmpPoint : [NaN, NaN];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n minSquaredDistance = assignClosestArrayPoint(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint);\n offset = ends[ends.length - 1];\n }\n\n return minSquaredDistance;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/deflate.js\n/**\n * @module ol/geom/flat/deflate\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\nfunction deflateCoordinate(flatCoordinates, offset, coordinate, stride) {\n for (var i = 0, ii = coordinate.length; i < ii; ++i) {\n flatCoordinates[offset++] = coordinate[i];\n }\n\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<import("../../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {number} stride Stride.\n * @return {number} offset Offset.\n */\n\nfunction deflateCoordinates(flatCoordinates, offset, coordinates, stride) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n var coordinate = coordinates[i];\n\n for (var j = 0; j < stride; ++j) {\n flatCoordinates[offset++] = coordinate[j];\n }\n }\n\n return offset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<import("../../coordinate.js").Coordinate>>} coordinatess Coordinatess.\n * @param {number} stride Stride.\n * @param {Array<number>=} opt_ends Ends.\n * @return {Array<number>} Ends.\n */\n\nfunction deflateCoordinatesArray(flatCoordinates, offset, coordinatess, stride, opt_ends) {\n var ends = opt_ends ? opt_ends : [];\n var i = 0;\n\n for (var j = 0, jj = coordinatess.length; j < jj; ++j) {\n var end = deflateCoordinates(flatCoordinates, offset, coordinatess[j], stride);\n ends[i++] = end;\n offset = end;\n }\n\n ends.length = i;\n return ends;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} coordinatesss Coordinatesss.\n * @param {number} stride Stride.\n * @param {Array<Array<number>>=} opt_endss Endss.\n * @return {Array<Array<number>>} Endss.\n */\n\nfunction deflateMultiCoordinatesArray(flatCoordinates, offset, coordinatesss, stride, opt_endss) {\n var endss = opt_endss ? opt_endss : [];\n var i = 0;\n\n for (var j = 0, jj = coordinatesss.length; j < jj; ++j) {\n var ends = deflateCoordinatesArray(flatCoordinates, offset, coordinatesss[j], stride, endss[i]);\n endss[i++] = ends;\n offset = ends[ends.length - 1];\n }\n\n endss.length = i;\n return endss;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/simplify.js\n/**\n * @module ol/geom/flat/simplify\n */\n// Based on simplify-js https://github.com/mourner/simplify-js\n// Copyright (c) 2012, Vladimir Agafonkin\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice,\n// this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright\n// notice, this list of conditions and the following disclaimer in the\n// documentation and/or other materials provided with the distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\n// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n// POSSIBILITY OF SUCH DAMAGE.\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {boolean} highQuality Highest quality.\n * @param {Array<number>=} opt_simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @return {Array<number>} Simplified line string.\n */\n\nfunction simplifyLineString(flatCoordinates, offset, end, stride, squaredTolerance, highQuality, opt_simplifiedFlatCoordinates) {\n var simplifiedFlatCoordinates = opt_simplifiedFlatCoordinates !== undefined ? opt_simplifiedFlatCoordinates : [];\n\n if (!highQuality) {\n end = radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n flatCoordinates = simplifiedFlatCoordinates;\n offset = 0;\n stride = 2;\n }\n\n simplifiedFlatCoordinates.length = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return simplifiedFlatCoordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n var n = (end - offset) / stride;\n\n if (n < 3) {\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];\n }\n\n return simplifiedOffset;\n }\n /** @type {Array<number>} */\n\n\n var markers = new Array(n);\n markers[0] = 1;\n markers[n - 1] = 1;\n /** @type {Array<number>} */\n\n var stack = [offset, end - stride];\n var index = 0;\n\n while (stack.length > 0) {\n var last = stack.pop();\n var first = stack.pop();\n var maxSquaredDistance = 0;\n var x1 = flatCoordinates[first];\n var y1 = flatCoordinates[first + 1];\n var x2 = flatCoordinates[last];\n var y2 = flatCoordinates[last + 1];\n\n for (var i = first + stride; i < last; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n var squaredDistance_1 = squaredSegmentDistance(x, y, x1, y1, x2, y2);\n\n if (squaredDistance_1 > maxSquaredDistance) {\n index = i;\n maxSquaredDistance = squaredDistance_1;\n }\n }\n\n if (maxSquaredDistance > squaredTolerance) {\n markers[(index - offset) / stride] = 1;\n\n if (first + stride < index) {\n stack.push(first, index);\n }\n\n if (index + stride < last) {\n stack.push(index, last);\n }\n }\n }\n\n for (var i = 0; i < n; ++i) {\n if (markers[i]) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + i * stride + 1];\n }\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = douglasPeucker(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\n\nfunction douglasPeuckerMultiArray(flatCoordinates, offset, endss, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = douglasPeuckerArray(flatCoordinates, offset, ends, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction radialDistance(flatCoordinates, offset, end, stride, squaredTolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n if (end <= offset + stride) {\n // zero or one point, no simplification possible, so copy and return\n for (; offset < end; offset += stride) {\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset];\n simplifiedFlatCoordinates[simplifiedOffset++] = flatCoordinates[offset + 1];\n }\n\n return simplifiedOffset;\n }\n\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1]; // copy first point\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1;\n var x2 = x1;\n var y2 = y1;\n\n for (offset += stride; offset < end; offset += stride) {\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n\n if (squaredDistance(x1, y1, x2, y2) > squaredTolerance) {\n // copy point at offset\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n }\n }\n\n if (x2 != x1 || y2 != y1) {\n // copy last point\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {number} value Value.\n * @param {number} tolerance Tolerance.\n * @return {number} Rounded value.\n */\n\nfunction snap(value, tolerance) {\n return tolerance * Math.round(value / tolerance);\n}\n/**\n * Simplifies a line string using an algorithm designed by Tim Schaub.\n * Coordinates are snapped to the nearest value in a virtual grid and\n * consecutive duplicate coordinates are discarded. This effectively preserves\n * topology as the simplification of any subsection of a line string is\n * independent of the rest of the line string. This means that, for examples,\n * the common edge between two polygons will be simplified to the same line\n * string independently in both polygons. This implementation uses a single\n * pass over the coordinates and eliminates intermediate collinear points.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @return {number} Simplified offset.\n */\n\nfunction quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset) {\n // do nothing if the line is empty\n if (offset == end) {\n return simplifiedOffset;\n } // snap the first coordinate (P1)\n\n\n var x1 = snap(flatCoordinates[offset], tolerance);\n var y1 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride; // add the first coordinate to the output\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x1;\n simplifiedFlatCoordinates[simplifiedOffset++] = y1; // find the next coordinate that does not snap to the same value as the first\n // coordinate (P2)\n\n var x2, y2;\n\n do {\n x2 = snap(flatCoordinates[offset], tolerance);\n y2 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride;\n\n if (offset == end) {\n // all coordinates snap to the same value, the line collapses to a point\n // push the last snapped value anyway to ensure that the output contains\n // at least two points\n // FIXME should we really return at least two points anyway?\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n }\n } while (x2 == x1 && y2 == y1);\n\n while (offset < end) {\n // snap the next coordinate (P3)\n var x3 = snap(flatCoordinates[offset], tolerance);\n var y3 = snap(flatCoordinates[offset + 1], tolerance);\n offset += stride; // skip P3 if it is equal to P2\n\n if (x3 == x2 && y3 == y2) {\n continue;\n } // calculate the delta between P1 and P2\n\n\n var dx1 = x2 - x1;\n var dy1 = y2 - y1; // calculate the delta between P3 and P1\n\n var dx2 = x3 - x1;\n var dy2 = y3 - y1; // if P1, P2, and P3 are colinear and P3 is further from P1 than P2 is from\n // P1 in the same direction then P2 is on the straight line between P1 and\n // P3\n\n if (dx1 * dy2 == dy1 * dx2 && (dx1 < 0 && dx2 < dx1 || dx1 == dx2 || dx1 > 0 && dx2 > dx1) && (dy1 < 0 && dy2 < dy1 || dy1 == dy2 || dy1 > 0 && dy2 > dy1)) {\n // discard P2 and set P2 = P3\n x2 = x3;\n y2 = y3;\n continue;\n } // either P1, P2, and P3 are not colinear, or they are colinear but P3 is\n // between P3 and P1 or on the opposite half of the line to P2. add P2,\n // and continue with P1 = P2 and P2 = P3\n\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n x1 = x2;\n y1 = y2;\n x2 = x3;\n y2 = y3;\n } // add the last point (P2)\n\n\n simplifiedFlatCoordinates[simplifiedOffset++] = x2;\n simplifiedFlatCoordinates[simplifiedOffset++] = y2;\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<number>} simplifiedEnds Simplified ends.\n * @return {number} Simplified offset.\n */\n\nfunction quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n simplifiedOffset = quantize(flatCoordinates, offset, end, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset);\n simplifiedEnds.push(simplifiedOffset);\n offset = end;\n }\n\n return simplifiedOffset;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} tolerance Tolerance.\n * @param {Array<number>} simplifiedFlatCoordinates Simplified flat\n * coordinates.\n * @param {number} simplifiedOffset Simplified offset.\n * @param {Array<Array<number>>} simplifiedEndss Simplified endss.\n * @return {number} Simplified offset.\n */\n\nfunction quantizeMultiArray(flatCoordinates, offset, endss, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEndss) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n var simplifiedEnds = [];\n simplifiedOffset = quantizeArray(flatCoordinates, offset, ends, stride, tolerance, simplifiedFlatCoordinates, simplifiedOffset, simplifiedEnds);\n simplifiedEndss.push(simplifiedEnds);\n offset = ends[ends.length - 1];\n }\n\n return simplifiedOffset;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/inflate.js\n/**\n * @module ol/geom/flat/inflate\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Array<import("../../coordinate.js").Coordinate>=} opt_coordinates Coordinates.\n * @return {Array<import("../../coordinate.js").Coordinate>} Coordinates.\n */\nfunction inflateCoordinates(flatCoordinates, offset, end, stride, opt_coordinates) {\n var coordinates = opt_coordinates !== undefined ? opt_coordinates : [];\n var i = 0;\n\n for (var j = offset; j < end; j += stride) {\n coordinates[i++] = flatCoordinates.slice(j, j + stride);\n }\n\n coordinates.length = i;\n return coordinates;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<Array<import("../../coordinate.js").Coordinate>>=} opt_coordinatess Coordinatess.\n * @return {Array<Array<import("../../coordinate.js").Coordinate>>} Coordinatess.\n */\n\nfunction inflateCoordinatesArray(flatCoordinates, offset, ends, stride, opt_coordinatess) {\n var coordinatess = opt_coordinatess !== undefined ? opt_coordinatess : [];\n var i = 0;\n\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n var end = ends[j];\n coordinatess[i++] = inflateCoordinates(flatCoordinates, offset, end, stride, coordinatess[i]);\n offset = end;\n }\n\n coordinatess.length = i;\n return coordinatess;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<Array<Array<import("../../coordinate.js").Coordinate>>>=} opt_coordinatesss\n * Coordinatesss.\n * @return {Array<Array<Array<import("../../coordinate.js").Coordinate>>>} Coordinatesss.\n */\n\nfunction inflateMultiCoordinatesArray(flatCoordinates, offset, endss, stride, opt_coordinatesss) {\n var coordinatesss = opt_coordinatesss !== undefined ? opt_coordinatesss : [];\n var i = 0;\n\n for (var j = 0, jj = endss.length; j < jj; ++j) {\n var ends = endss[j];\n coordinatesss[i++] = inflateCoordinatesArray(flatCoordinates, offset, ends, stride, coordinatesss[i]);\n offset = ends[ends.length - 1];\n }\n\n coordinatesss.length = i;\n return coordinatesss;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/area.js\n/**\n * @module ol/geom/flat/area\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\nfunction linearRing(flatCoordinates, offset, end, stride) {\n var twiceArea = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n twiceArea += y1 * x2 - x1 * y2;\n x1 = x2;\n y1 = y2;\n }\n\n return twiceArea / 2;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\n\nfunction linearRings(flatCoordinates, offset, ends, stride) {\n var area = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n area += linearRing(flatCoordinates, offset, end, stride);\n offset = end;\n }\n\n return area;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {number} Area.\n */\n\nfunction linearRingss(flatCoordinates, offset, endss, stride) {\n var area = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n area += linearRings(flatCoordinates, offset, ends, stride);\n offset = ends[ends.length - 1];\n }\n\n return area;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/LinearRing.js\nvar LinearRing_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/LinearRing\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Linear ring geometry. Only used as part of polygon; cannot be rendered\n * on its own.\n *\n * @api\n */\n\nvar LinearRing =\n/** @class */\nfunction (_super) {\n LinearRing_extends(LinearRing, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function LinearRing(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number}\n */\n\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!LinearRing} Clone.\n * @api\n */\n\n\n LinearRing.prototype.clone = function () {\n return new LinearRing(this.flatCoordinates.slice(), this.layout);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n LinearRing.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Return the area of the linear ring on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n LinearRing.prototype.getArea = function () {\n return linearRing(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinates of the linear ring.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n LinearRing.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LinearRing} Simplified LinearRing.\n * @protected\n */\n\n\n LinearRing.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LinearRing(simplifiedFlatCoordinates, geom_GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n LinearRing.prototype.getType = function () {\n return geom_GeometryType.LINEAR_RING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n LinearRing.prototype.intersectsExtent = function (extent) {\n return false;\n };\n /**\n * Set the coordinates of the linear ring.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n LinearRing.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return LinearRing;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_LinearRing = (LinearRing);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Point.js\nvar Point_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Point\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Point geometry.\n *\n * @api\n */\n\nvar Point =\n/** @class */\nfunction (_super) {\n Point_extends(Point, _super);\n /**\n * @param {import("../coordinate.js").Coordinate} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function Point(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n\n _this.setCoordinates(coordinates, opt_layout);\n\n return _this;\n }\n /**\n * Make a complete copy of the geometry.\n * @return {!Point} Clone.\n * @api\n */\n\n\n Point.prototype.clone = function () {\n var point = new Point(this.flatCoordinates.slice(), this.layout);\n point.applyProperties(this);\n return point;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Point.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n var flatCoordinates = this.flatCoordinates;\n var squaredDistance = math_squaredDistance(x, y, flatCoordinates[0], flatCoordinates[1]);\n\n if (squaredDistance < minSquaredDistance) {\n var stride = this.stride;\n\n for (var i = 0; i < stride; ++i) {\n closestPoint[i] = flatCoordinates[i];\n }\n\n closestPoint.length = stride;\n return squaredDistance;\n } else {\n return minSquaredDistance;\n }\n };\n /**\n * Return the coordinate of the point.\n * @return {import("../coordinate.js").Coordinate} Coordinates.\n * @api\n */\n\n\n Point.prototype.getCoordinates = function () {\n return !this.flatCoordinates ? [] : this.flatCoordinates.slice();\n };\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n Point.prototype.computeExtent = function (extent) {\n return createOrUpdateFromCoordinate(this.flatCoordinates, extent);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n Point.prototype.getType = function () {\n return geom_GeometryType.POINT;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n Point.prototype.intersectsExtent = function (extent) {\n return containsXY(extent, this.flatCoordinates[0], this.flatCoordinates[1]);\n };\n /**\n * @param {!Array<*>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n Point.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 0);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinate(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return Point;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_Point = (Point);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/contains.js\n/**\n * @module ol/geom/flat/contains\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} Contains extent.\n */\n\nfunction linearRingContainsExtent(flatCoordinates, offset, end, stride, extent) {\n var outside = forEachCorner(extent,\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} Contains (x, y).\n */\n function (coordinate) {\n return !linearRingContainsXY(flatCoordinates, offset, end, stride, coordinate[0], coordinate[1]);\n });\n return !outside;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingContainsXY(flatCoordinates, offset, end, stride, x, y) {\n // http://geomalgorithms.com/a03-_inclusion.html\n // Copyright 2000 softSurfer, 2012 Dan Sunday\n // This code may be freely used and modified for any purpose\n // providing that this copyright notice is included with it.\n // SoftSurfer makes no warranty for this code, and cannot be held\n // liable for any real or imagined damage resulting from its use.\n // Users of this code must verify correctness for their application.\n var wn = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n\n if (y1 <= y) {\n if (y2 > y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) > 0) {\n wn++;\n }\n } else if (y2 <= y && (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1) < 0) {\n wn--;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n return wn !== 0;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y) {\n if (ends.length === 0) {\n return false;\n }\n\n if (!linearRingContainsXY(flatCoordinates, offset, ends[0], stride, x, y)) {\n return false;\n }\n\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsXY(flatCoordinates, ends[i - 1], ends[i], stride, x, y)) {\n return false;\n }\n }\n\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\nfunction linearRingssContainsXY(flatCoordinates, offset, endss, stride, x, y) {\n if (endss.length === 0) {\n return false;\n }\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n return true;\n }\n\n offset = ends[ends.length - 1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interiorpoint.js\n/**\n * @module ol/geom/flat/interiorpoint\n */\n\n\n/**\n * Calculates a point that is likely to lie in the interior of the linear rings.\n * Inspired by JTS\'s com.vividsolutions.jts.geom.Geometry#getInteriorPoint.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @param {number} flatCentersOffset Flat center offset.\n * @param {Array<number>=} opt_dest Destination.\n * @return {Array<number>} Destination point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\n\nfunction getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, flatCentersOffset, opt_dest) {\n var i, ii, x, x1, x2, y1, y2;\n var y = flatCenters[flatCentersOffset + 1];\n /** @type {Array<number>} */\n\n var intersections = []; // Calculate intersections with the horizontal line\n\n for (var r = 0, rr = ends.length; r < rr; ++r) {\n var end = ends[r];\n x1 = flatCoordinates[end - stride];\n y1 = flatCoordinates[end - stride + 1];\n\n for (i = offset; i < end; i += stride) {\n x2 = flatCoordinates[i];\n y2 = flatCoordinates[i + 1];\n\n if (y <= y1 && y2 <= y || y1 <= y && y <= y2) {\n x = (y - y1) / (y2 - y1) * (x2 - x1) + x1;\n intersections.push(x);\n }\n\n x1 = x2;\n y1 = y2;\n }\n } // Find the longest segment of the horizontal line that has its center point\n // inside the linear ring.\n\n\n var pointX = NaN;\n var maxSegmentLength = -Infinity;\n intersections.sort(numberSafeCompareFunction);\n x1 = intersections[0];\n\n for (i = 1, ii = intersections.length; i < ii; ++i) {\n x2 = intersections[i];\n var segmentLength = Math.abs(x2 - x1);\n\n if (segmentLength > maxSegmentLength) {\n x = (x1 + x2) / 2;\n\n if (linearRingsContainsXY(flatCoordinates, offset, ends, stride, x, y)) {\n pointX = x;\n maxSegmentLength = segmentLength;\n }\n }\n\n x1 = x2;\n }\n\n if (isNaN(pointX)) {\n // There is no horizontal line that has its center point inside the linear\n // ring. Use the center of the the linear ring\'s extent.\n pointX = flatCenters[flatCentersOffset];\n }\n\n if (opt_dest) {\n opt_dest.push(pointX, y, maxSegmentLength);\n return opt_dest;\n } else {\n return [pointX, y, maxSegmentLength];\n }\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {Array<number>} flatCenters Flat centers.\n * @return {Array<number>} Interior points as XYM coordinates, where M is the\n * length of the horizontal intersection that the point belongs to.\n */\n\nfunction getInteriorPointsOfMultiArray(flatCoordinates, offset, endss, stride, flatCenters) {\n var interiorPoints = [];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n interiorPoints = getInteriorPointOfArray(flatCoordinates, offset, ends, stride, flatCenters, 2 * i, interiorPoints);\n offset = ends[ends.length - 1];\n }\n\n return interiorPoints;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/segments.js\n/**\n * @module ol/geom/flat/segments\n */\n\n/**\n * This function calls `callback` for each segment of the flat coordinates\n * array. If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {function(import("../../coordinate.js").Coordinate, import("../../coordinate.js").Coordinate): T} callback Function\n * called for each segment.\n * @return {T|boolean} Value.\n * @template T\n */\nfunction forEach(flatCoordinates, offset, end, stride, callback) {\n var point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];\n var point2 = [];\n var ret;\n\n for (; offset + stride < end; offset += stride) {\n point2[0] = flatCoordinates[offset + stride];\n point2[1] = flatCoordinates[offset + stride + 1];\n ret = callback(point1, point2);\n\n if (ret) {\n return ret;\n }\n\n point1[0] = point2[0];\n point1[1] = point2[1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/intersectsextent.js\n/**\n * @module ol/geom/flat/intersectsextent\n */\n\n\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLineString(flatCoordinates, offset, end, stride, extent) {\n var coordinatesExtent = extendFlatCoordinates(createEmpty(), flatCoordinates, offset, end, stride);\n\n if (!intersects(extent, coordinatesExtent)) {\n return false;\n }\n\n if (containsExtent(extent, coordinatesExtent)) {\n return true;\n }\n\n if (coordinatesExtent[0] >= extent[0] && coordinatesExtent[2] <= extent[2]) {\n return true;\n }\n\n if (coordinatesExtent[1] >= extent[1] && coordinatesExtent[3] <= extent[3]) {\n return true;\n }\n\n return forEach(flatCoordinates, offset, end, stride,\n /**\n * @param {import("../../coordinate.js").Coordinate} point1 Start point.\n * @param {import("../../coordinate.js").Coordinate} point2 End point.\n * @return {boolean} `true` if the segment and the extent intersect,\n * `false` otherwise.\n */\n function (point1, point2) {\n return intersectsSegment(extent, point1, point2);\n });\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLineStringArray(flatCoordinates, offset, ends, stride, extent) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n if (intersectsLineString(flatCoordinates, offset, ends[i], stride, extent)) {\n return true;\n }\n\n offset = ends[i];\n }\n\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRing(flatCoordinates, offset, end, stride, extent) {\n if (intersectsLineString(flatCoordinates, offset, end, stride, extent)) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[1])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[0], extent[3])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[1])) {\n return true;\n }\n\n if (linearRingContainsXY(flatCoordinates, offset, end, stride, extent[2], extent[3])) {\n return true;\n }\n\n return false;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent) {\n if (!intersectsLinearRing(flatCoordinates, offset, ends[0], stride, extent)) {\n return false;\n }\n\n if (ends.length === 1) {\n return true;\n }\n\n for (var i = 1, ii = ends.length; i < ii; ++i) {\n if (linearRingContainsExtent(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n if (!intersectsLineString(flatCoordinates, ends[i - 1], ends[i], stride, extent)) {\n return false;\n }\n }\n }\n\n return true;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @return {boolean} True if the geometry and the extent intersect.\n */\n\nfunction intersectsLinearRingMultiArray(flatCoordinates, offset, endss, stride, extent) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (intersectsLinearRingArray(flatCoordinates, offset, ends, stride, extent)) {\n return true;\n }\n\n offset = ends[ends.length - 1];\n }\n\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/reverse.js\n/**\n * @module ol/geom/flat/reverse\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n */\nfunction coordinates(flatCoordinates, offset, end, stride) {\n while (offset < end - stride) {\n for (var i = 0; i < stride; ++i) {\n var tmp = flatCoordinates[offset + i];\n flatCoordinates[offset + i] = flatCoordinates[end - stride + i];\n flatCoordinates[end - stride + i] = tmp;\n }\n\n offset += stride;\n end -= stride;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/orient.js\n/**\n * @module ol/geom/flat/orient\n */\n\n/**\n * Is the linear ring oriented clockwise in a coordinate system with a bottom-left\n * coordinate origin? For a coordinate system with a top-left coordinate origin,\n * the ring\'s orientation is clockwise when this function returns false.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {boolean} Is clockwise.\n */\n\nfunction linearRingIsClockwise(flatCoordinates, offset, end, stride) {\n // http://tinyurl.com/clockwise-method\n // https://github.com/OSGeo/gdal/blob/trunk/gdal/ogr/ogrlinearring.cpp\n var edge = 0;\n var x1 = flatCoordinates[end - stride];\n var y1 = flatCoordinates[end - stride + 1];\n\n for (; offset < end; offset += stride) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n edge += (x2 - x1) * (y2 + y1);\n x1 = x2;\n y1 = y2;\n }\n\n return edge === 0 ? undefined : edge > 0;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\n\nfunction linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n\n if (i === 0) {\n if (right && isClockwise || !right && !isClockwise) {\n return false;\n }\n } else {\n if (right && !isClockwise || !right && isClockwise) {\n return false;\n }\n }\n\n offset = end;\n }\n\n return true;\n}\n/**\n * Determines if linear rings are oriented. By default, left-hand orientation\n * is tested (first ring must be clockwise, remaining rings counter-clockwise).\n * To test for right-hand orientation, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Test for right-hand orientation\n * (counter-clockwise exterior ring and clockwise interior rings).\n * @return {boolean} Rings are correctly oriented.\n */\n\nfunction linearRingssAreOriented(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n\n if (!linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right)) {\n return false;\n }\n\n if (ends.length) {\n offset = ends[ends.length - 1];\n }\n }\n\n return true;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\n\nfunction orientLinearRings(flatCoordinates, offset, ends, stride, opt_right) {\n var right = opt_right !== undefined ? opt_right : false;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var isClockwise = linearRingIsClockwise(flatCoordinates, offset, end, stride);\n var reverse = i === 0 ? right && isClockwise || !right && !isClockwise : right && !isClockwise || !right && isClockwise;\n\n if (reverse) {\n coordinates(flatCoordinates, offset, end, stride);\n }\n\n offset = end;\n }\n\n return offset;\n}\n/**\n * Orient coordinates in a flat array of linear rings. By default, rings\n * are oriented following the left-hand rule (clockwise for exterior and\n * counter-clockwise for interior rings). To orient according to the\n * right-hand rule, use the `opt_right` argument.\n *\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Array of array of end indexes.\n * @param {number} stride Stride.\n * @param {boolean=} opt_right Follow the right-hand rule for orientation.\n * @return {number} End.\n */\n\nfunction orientLinearRingsArray(flatCoordinates, offset, endss, stride, opt_right) {\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = orientLinearRings(flatCoordinates, offset, endss[i], stride, opt_right);\n }\n\n return offset;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/Polygon.js\nvar Polygon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/Polygon\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Polygon geometry.\n *\n * @api\n */\n\nvar Polygon =\n/** @class */\nfunction (_super) {\n Polygon_extends(Polygon, _super);\n /**\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>|!Array<number>} coordinates\n * Array of linear rings that define the polygon. The first linear ring of the\n * array defines the outer-boundary or surface of the polygon. Each subsequent\n * linear ring defines a hole in the surface of the polygon. A linear ring is\n * an array of vertices\' coordinates where the first coordinate and the last are\n * equivalent. (For internal use, flat coordinates in combination with\n * `opt_layout` and `opt_ends` are also accepted.)\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<number>=} opt_ends Ends (for internal use with flat coordinates).\n */\n\n\n function Polygon(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n\n\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.flatInteriorPointRevision_ = -1;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.flatInteriorPoint_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.orientedFlatCoordinates_ = null;\n\n if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.ends_ = opt_ends;\n } else {\n _this.setCoordinates(\n /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed linear ring to this polygon.\n * @param {LinearRing} linearRing Linear ring.\n * @api\n */\n\n\n Polygon.prototype.appendLinearRing = function (linearRing) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = linearRing.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, linearRing.getFlatCoordinates());\n }\n\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!Polygon} Clone.\n * @api\n */\n\n\n Polygon.prototype.clone = function () {\n var polygon = new Polygon(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n polygon.applyProperties(this);\n return polygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n Polygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n Polygon.prototype.containsXY = function (x, y) {\n return linearRingsContainsXY(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, x, y);\n };\n /**\n * Return the area of the polygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n Polygon.prototype.getArea = function () {\n return linearRings(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for polygons.\n *\n * @param {boolean=} opt_right Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.\n * @api\n */\n\n\n Polygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRings(flatCoordinates, 0, this.ends_, this.stride, opt_right);\n } else {\n flatCoordinates = this.flatCoordinates;\n }\n\n return inflateCoordinatesArray(flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n\n\n Polygon.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * @return {Array<number>} Interior point.\n */\n\n\n Polygon.prototype.getFlatInteriorPoint = function () {\n if (this.flatInteriorPointRevision_ != this.getRevision()) {\n var flatCenter = getCenter(this.getExtent());\n this.flatInteriorPoint_ = getInteriorPointOfArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, flatCenter, 0);\n this.flatInteriorPointRevision_ = this.getRevision();\n }\n\n return this.flatInteriorPoint_;\n };\n /**\n * Return an interior point of the polygon.\n * @return {Point} Interior point as XYM coordinate, where M is the\n * length of the horizontal intersection that the point belongs to.\n * @api\n */\n\n\n Polygon.prototype.getInteriorPoint = function () {\n return new geom_Point(this.getFlatInteriorPoint(), geom_GeometryLayout.XYM);\n };\n /**\n * Return the number of rings of the polygon, this includes the exterior\n * ring and any interior rings.\n *\n * @return {number} Number of rings.\n * @api\n */\n\n\n Polygon.prototype.getLinearRingCount = function () {\n return this.ends_.length;\n };\n /**\n * Return the Nth linear ring of the polygon geometry. Return `null` if the\n * given index is out of range.\n * The exterior linear ring is available at index `0` and the interior rings\n * at index `1` and beyond.\n *\n * @param {number} index Index.\n * @return {LinearRing} Linear ring.\n * @api\n */\n\n\n Polygon.prototype.getLinearRing = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n\n return new geom_LinearRing(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linear rings of the polygon.\n * @return {Array<LinearRing>} Linear rings.\n * @api\n */\n\n\n Polygon.prototype.getLinearRings = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var linearRings = [];\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var linearRing = new geom_LinearRing(flatCoordinates.slice(offset, end), layout);\n linearRings.push(linearRing);\n offset = end;\n }\n\n return linearRings;\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n\n\n Polygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n\n if (linearRingsAreOriented(flatCoordinates, 0, this.ends_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n } else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRings(this.orientedFlatCoordinates_, 0, this.ends_, this.stride);\n }\n\n this.orientedRevision_ = this.getRevision();\n }\n\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Polygon} Simplified Polygon.\n * @protected\n */\n\n\n Polygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = quantizeArray(this.flatCoordinates, 0, this.ends_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new Polygon(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n Polygon.prototype.getType = function () {\n return geom_GeometryType.POLYGON;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n Polygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingArray(this.getOrientedFlatCoordinates(), 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the polygon.\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n Polygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n\n return Polygon;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_Polygon = (Polygon);\n/**\n * Create an approximation of a circle on the surface of a sphere.\n * @param {import("../coordinate.js").Coordinate} center Center (`[lon, lat]` in degrees).\n * @param {number} radius The great-circle distance from the center to\n * the polygon vertices.\n * @param {number=} opt_n Optional number of vertices for the resulting\n * polygon. Default is `32`.\n * @param {number=} opt_sphereRadius Optional radius for the sphere (defaults to\n * the Earth\'s mean radius using the WGS84 ellipsoid).\n * @return {Polygon} The "circular" polygon.\n * @api\n */\n\nfunction circular(center, radius, opt_n, opt_sphereRadius) {\n var n = opt_n ? opt_n : 32;\n /** @type {Array<number>} */\n\n var flatCoordinates = [];\n\n for (var i = 0; i < n; ++i) {\n extend(flatCoordinates, sphereOffset(center, radius, 2 * Math.PI * i / n, opt_sphereRadius));\n }\n\n flatCoordinates.push(flatCoordinates[0], flatCoordinates[1]);\n return new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);\n}\n/**\n * Create a polygon from an extent. The layout used is `XY`.\n * @param {import("../extent.js").Extent} extent The extent.\n * @return {Polygon} The polygon.\n * @api\n */\n\nfunction fromExtent(extent) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var flatCoordinates = [minX, minY, minX, maxY, maxX, maxY, maxX, minY, minX, minY];\n return new Polygon(flatCoordinates, geom_GeometryLayout.XY, [flatCoordinates.length]);\n}\n/**\n * Create a regular polygon from a circle.\n * @param {import("./Circle.js").default} circle Circle geometry.\n * @param {number=} opt_sides Number of sides of the polygon. Default is 32.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n * @return {Polygon} Polygon geometry.\n * @api\n */\n\nfunction fromCircle(circle, opt_sides, opt_angle) {\n var sides = opt_sides ? opt_sides : 32;\n var stride = circle.getStride();\n var layout = circle.getLayout();\n var center = circle.getCenter();\n var arrayLength = stride * (sides + 1);\n var flatCoordinates = new Array(arrayLength);\n\n for (var i = 0; i < arrayLength; i += stride) {\n flatCoordinates[i] = 0;\n flatCoordinates[i + 1] = 0;\n\n for (var j = 2; j < stride; j++) {\n flatCoordinates[i + j] = center[j];\n }\n }\n\n var ends = [flatCoordinates.length];\n var polygon = new Polygon(flatCoordinates, layout, ends);\n makeRegular(polygon, center, circle.getRadius(), opt_angle);\n return polygon;\n}\n/**\n * Modify the coordinates of a polygon to make it a regular polygon.\n * @param {Polygon} polygon Polygon geometry.\n * @param {import("../coordinate.js").Coordinate} center Center of the regular polygon.\n * @param {number} radius Radius of the regular polygon.\n * @param {number=} opt_angle Start angle for the first vertex of the polygon in\n * counter-clockwise radians. 0 means East. Default is 0.\n */\n\nfunction makeRegular(polygon, center, radius, opt_angle) {\n var flatCoordinates = polygon.getFlatCoordinates();\n var stride = polygon.getStride();\n var sides = flatCoordinates.length / stride - 1;\n var startAngle = opt_angle ? opt_angle : 0;\n\n for (var i = 0; i <= sides; ++i) {\n var offset = i * stride;\n var angle = startAngle + modulo(i, sides) * 2 * Math.PI / sides;\n flatCoordinates[offset] = center[0] + radius * Math.cos(angle);\n flatCoordinates[offset + 1] = center[1] + radius * Math.sin(angle);\n }\n\n polygon.changed();\n}\n;// CONCATENATED MODULE: ./node_modules/ol/View.js\nvar View_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/View\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 * An animation configuration\n *\n * @typedef {Object} Animation\n * @property {import("./coordinate.js").Coordinate} [sourceCenter]\n * @property {import("./coordinate.js").Coordinate} [targetCenter]\n * @property {number} [sourceResolution]\n * @property {number} [targetResolution]\n * @property {number} [sourceRotation]\n * @property {number} [targetRotation]\n * @property {import("./coordinate.js").Coordinate} [anchor]\n * @property {number} start\n * @property {number} duration\n * @property {boolean} complete\n * @property {function(number):number} easing\n * @property {function(boolean):void} callback\n */\n\n/**\n * @typedef {Object} Constraints\n * @property {import("./centerconstraint.js").Type} center\n * @property {import("./resolutionconstraint.js").Type} resolution\n * @property {import("./rotationconstraint.js").Type} rotation\n */\n\n/**\n * @typedef {Object} FitOptions\n * @property {import("./size.js").Size} [size] The size in pixels of the box to fit\n * the extent into. Default is the current size of the first map in the DOM that\n * uses this view, or `[100, 100]` if no such map is found.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in pixels) to be\n * cleared inside the view. Values in the array are top, right, bottom and left\n * padding.\n * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,\n * get the nearest extent instead of the closest that actually fits the view.\n * @property {number} [minResolution=0] Minimum resolution that we zoom to.\n * @property {number} [maxZoom] Maximum zoom level that we zoom to. If\n * `minResolution` is given, this property is ignored.\n * @property {number} [duration] The duration of the animation in milliseconds.\n * By default, there is no animation to the target extent.\n * @property {function(number):number} [easing] The easing function used during\n * the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation\'s duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n * @property {function(boolean):void} [callback] Function called when the view is in\n * its final position. The callback will be called with `true` if the animation\n * series completed on its own or `false` if it was cancelled.\n */\n\n/**\n * @typedef {Object} ViewOptions\n * @property {import("./coordinate.js").Coordinate} [center] The initial center for\n * the view. If a user projection is not set, the coordinate system for the center is\n * specified with the `projection` option. Layer sources will not be fetched if this\n * is not set, but the center can be set later with {@link #setCenter}.\n * @property {boolean|number} [constrainRotation=true] Rotation constraint.\n * `false` means no constraint. `true` means no constraint, but snap to zero\n * near zero. A number constrains the rotation to that number of values. For\n * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.\n * @property {boolean} [enableRotation=true] Enable rotation.\n * If `false`, a rotation constraint that always sets the rotation to zero is\n * used. The `constrainRotation` option has no effect if `enableRotation` is\n * `false`.\n * @property {import("./extent.js").Extent} [extent] The extent that constrains the\n * view, in other words, nothing outside of this extent can be visible on the map.\n * @property {boolean} [constrainOnlyCenter=false] If true, the extent\n * constraint will only apply to the view center and not the whole extent.\n * @property {boolean} [smoothExtentConstraint=true] If true, the extent\n * constraint will be applied smoothly, i.e. allow the view to go slightly outside\n * of the given `extent`.\n * @property {number} [maxResolution] The maximum resolution used to determine\n * the resolution constraint. It is used together with `minResolution` (or\n * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way\n * that the projection\'s validity extent fits in a 256x256 px tile. If the\n * projection is Spherical Mercator (the default) then `maxResolution` defaults\n * to `40075016.68557849 / 256 = 156543.03392804097`.\n * @property {number} [minResolution] The minimum resolution used to determine\n * the resolution constraint. It is used together with `maxResolution` (or\n * `minZoom`) and `zoomFactor`. If unspecified it is calculated assuming 29\n * zoom levels (with a factor of 2). If the projection is Spherical Mercator\n * (the default) then `minResolution` defaults to\n * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.\n * @property {number} [maxZoom=28] The maximum zoom level used to determine the\n * resolution constraint. It is used together with `minZoom` (or\n * `maxResolution`) and `zoomFactor`. Note that if `minResolution` is also\n * provided, it is given precedence over `maxZoom`.\n * @property {number} [minZoom=0] The minimum zoom level used to determine the\n * resolution constraint. It is used together with `maxZoom` (or\n * `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also\n * provided, it is given precedence over `minZoom`.\n * @property {boolean} [multiWorld=false] If `false` the view is constrained so\n * only one world is visible, and you cannot pan off the edge. If `true` the map\n * may show multiple worlds at low zoom levels. Only used if the `projection` is\n * global. Note that if `extent` is also provided it is given precedence.\n * @property {boolean} [constrainResolution=false] If true, the view will always\n * animate to the closest zoom level after an interaction; false means\n * intermediary zoom levels are allowed.\n * @property {boolean} [smoothResolutionConstraint=true] If true, the resolution\n * min/max values will be applied smoothly, i. e. allow the view to exceed slightly\n * the given resolution or zoom bounds.\n * @property {boolean} [showFullExtent=false] Allow the view to be zoomed out to\n * show the full configured extent. By default, when a view is configured with an\n * extent, users will not be able to zoom out so the viewport exceeds the extent in\n * either dimension. This means the full extent may not be visible if the viewport\n * is taller or wider than the aspect ratio of the configured extent. If\n * showFullExtent is true, the user will be able to zoom out so that the viewport\n * exceeds the height or width of the configured extent, but not both, allowing the\n * full extent to be shown.\n * @property {import("./proj.js").ProjectionLike} [projection=\'EPSG:3857\'] The\n * projection. The default is Spherical Mercator.\n * @property {number} [resolution] The initial resolution for the view. The\n * units are `projection` units per pixel (e.g. meters per pixel). An\n * alternative to setting this is to set `zoom`. Layer sources will not be\n * fetched if neither this nor `zoom` are defined, but they can be set later\n * with {@link #setZoom} or {@link #setResolution}.\n * @property {Array<number>} [resolutions] Resolutions to determine the\n * resolution constraint. If set the `maxResolution`, `minResolution`,\n * `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.\n * @property {number} [rotation=0] The initial rotation for the view in radians\n * (positive rotation clockwise, 0 means North).\n * @property {number} [zoom] Only used if `resolution` is not defined. Zoom\n * level used to calculate the initial resolution for the view.\n * @property {number} [zoomFactor=2] The zoom factor used to compute the\n * corresponding resolution.\n * @property {!Array<number>} [padding=[0, 0, 0, 0]] Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from\n * that content. The order of the values is top, right, bottom, left.\n */\n\n/**\n * @typedef {Object} AnimationOptions\n * @property {import("./coordinate.js").Coordinate} [center] The center of the view at the end of\n * the animation.\n * @property {number} [zoom] The zoom level of the view at the end of the\n * animation. This takes precedence over `resolution`.\n * @property {number} [resolution] The resolution of the view at the end\n * of the animation. If `zoom` is also provided, this option will be ignored.\n * @property {number} [rotation] The rotation of the view at the end of\n * the animation.\n * @property {import("./coordinate.js").Coordinate} [anchor] Optional anchor to remain fixed\n * during a rotation or resolution animation.\n * @property {number} [duration=1000] The duration of the animation in milliseconds.\n * @property {function(number):number} [easing] The easing function used\n * during the animation (defaults to {@link module:ol/easing~inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation\'s duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n */\n\n/**\n * @typedef {Object} State\n * @property {import("./coordinate.js").Coordinate} center\n * @property {import("./proj/Projection.js").default} projection\n * @property {number} resolution\n * @property {number} rotation\n * @property {number} zoom\n */\n\n/**\n * Default min zoom level for the map view.\n * @type {number}\n */\n\nvar DEFAULT_MIN_ZOOM = 0;\n/**\n * @classdesc\n * A View object represents a simple 2D view of the map.\n *\n * This is the object to act upon to change the center, resolution,\n * and rotation of the map.\n *\n * A View has a `projection`. The projection determines the\n * coordinate system of the center, and its units determine the units of the\n * resolution (projection units per pixel). The default projection is\n * Spherical Mercator (EPSG:3857).\n *\n * ### The view states\n *\n * A View is determined by three states: `center`, `resolution`,\n * and `rotation`. Each state has a corresponding getter and setter, e.g.\n * `getCenter` and `setCenter` for the `center` state.\n *\n * The `zoom` state is actually not saved on the view: all computations\n * internally use the `resolution` state. Still, the `setZoom` and `getZoom`\n * methods are available, as well as `getResolutionForZoom` and\n * `getZoomForResolution` to switch from one system to the other.\n *\n * ### The constraints\n *\n * `setCenter`, `setResolution` and `setRotation` can be used to change the\n * states of the view, but any constraint defined in the constructor will\n * be applied along the way.\n *\n * A View object can have a *resolution constraint*, a *rotation constraint*\n * and a *center constraint*.\n *\n * The *resolution constraint* typically restricts min/max values and\n * snaps to specific resolutions. It is determined by the following\n * options: `resolutions`, `maxResolution`, `maxZoom` and `zoomFactor`.\n * If `resolutions` is set, the other three options are ignored. See\n * documentation for each option for more information. By default, the view\n * only has a min/max restriction and allow intermediary zoom levels when\n * pinch-zooming for example.\n *\n * The *rotation constraint* snaps to specific angles. It is determined\n * by the following options: `enableRotation` and `constrainRotation`.\n * By default rotation is allowed and its value is snapped to zero when approaching the\n * horizontal.\n *\n * The *center constraint* is determined by the `extent` option. By\n * default the view center is not constrained at all.\n *\n * ### Changing the view state\n *\n * It is important to note that `setZoom`, `setResolution`, `setCenter` and\n * `setRotation` are subject to the above mentioned constraints. As such, it\n * may sometimes not be possible to know in advance the resulting state of the\n * View. For example, calling `setResolution(10)` does not guarantee that\n * `getResolution()` will return `10`.\n *\n * A consequence of this is that, when applying a delta on the view state, one\n * should use `adjustCenter`, `adjustRotation`, `adjustZoom` and `adjustResolution`\n * rather than the corresponding setters. This will let view do its internal\n * computations. Besides, the `adjust*` methods also take an `opt_anchor`\n * argument which allows specifying an origin for the transformation.\n *\n * ### Interacting with the view\n *\n * View constraints are usually only applied when the view is *at rest*, meaning that\n * no interaction or animation is ongoing. As such, if the user puts the view in a\n * state that is not equivalent to a constrained one (e.g. rotating the view when\n * the snap angle is 0), an animation will be triggered at the interaction end to\n * put back the view to a stable state;\n *\n * @api\n */\n\nvar View =\n/** @class */\nfunction (_super) {\n View_extends(View, _super);\n /**\n * @param {ViewOptions=} opt_options View options.\n */\n\n\n function View(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = obj_assign({}, opt_options);\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.hints_ = [0, 0];\n /**\n * @private\n * @type {Array<Array<Animation>>}\n */\n\n _this.animations_ = [];\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.updateAnimationKey_;\n /**\n * @private\n * @const\n * @type {import("./proj/Projection.js").default}\n */\n\n _this.projection_ = createProjection(options.projection, \'EPSG:3857\');\n /**\n * @private\n * @type {import("./size.js").Size}\n */\n\n _this.viewportSize_ = [100, 100];\n /**\n * @private\n * @type {import("./coordinate.js").Coordinate|undefined}\n */\n\n _this.targetCenter_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.targetResolution_;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.targetRotation_;\n /**\n * @private\n * @type {import("./coordinate.js").Coordinate|undefined}\n */\n\n _this.cancelAnchor_ = undefined;\n\n if (options.center) {\n options.center = fromUserCoordinate(options.center, _this.projection_);\n }\n\n if (options.extent) {\n options.extent = fromUserExtent(options.extent, _this.projection_);\n }\n\n _this.applyOptions_(options);\n\n return _this;\n }\n /**\n * Set up the view with the given options.\n * @param {ViewOptions} options View options.\n */\n\n\n View.prototype.applyOptions_ = function (options) {\n /**\n * @type {Object<string, *>}\n */\n var properties = {};\n var resolutionConstraintInfo = createResolutionConstraint(options);\n /**\n * @private\n * @type {number}\n */\n\n this.maxResolution_ = resolutionConstraintInfo.maxResolution;\n /**\n * @private\n * @type {number}\n */\n\n this.minResolution_ = resolutionConstraintInfo.minResolution;\n /**\n * @private\n * @type {number}\n */\n\n this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;\n /**\n * @private\n * @type {Array<number>|undefined}\n */\n\n this.resolutions_ = options.resolutions;\n /**\n * Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from that\n * content. The order of the values in the array is top, right, bottom, left.\n * The default is no padding, which is equivalent to `[0, 0, 0, 0]`.\n * @type {Array<number>|undefined}\n * @api\n */\n\n this.padding = options.padding;\n /**\n * @private\n * @type {number}\n */\n\n this.minZoom_ = resolutionConstraintInfo.minZoom;\n var centerConstraint = createCenterConstraint(options);\n var resolutionConstraint = resolutionConstraintInfo.constraint;\n var rotationConstraint = createRotationConstraint(options);\n /**\n * @private\n * @type {Constraints}\n */\n\n this.constraints_ = {\n center: centerConstraint,\n resolution: resolutionConstraint,\n rotation: rotationConstraint\n };\n this.setRotation(options.rotation !== undefined ? options.rotation : 0);\n this.setCenterInternal(options.center !== undefined ? options.center : null);\n\n if (options.resolution !== undefined) {\n this.setResolution(options.resolution);\n } else if (options.zoom !== undefined) {\n this.setZoom(options.zoom);\n }\n\n this.setProperties(properties);\n /**\n * @private\n * @type {ViewOptions}\n */\n\n this.options_ = options;\n };\n /**\n * Get an updated version of the view options used to construct the view. The\n * current resolution (or zoom), center, and rotation are applied to any stored\n * options. The provided options can be used to apply new min/max zoom or\n * resolution limits.\n * @param {ViewOptions} newOptions New options to be applied.\n * @return {ViewOptions} New options updated with the current view state.\n */\n\n\n View.prototype.getUpdatedOptions_ = function (newOptions) {\n var options = obj_assign({}, this.options_); // preserve resolution (or zoom)\n\n if (options.resolution !== undefined) {\n options.resolution = this.getResolution();\n } else {\n options.zoom = this.getZoom();\n } // preserve center\n\n\n options.center = this.getCenterInternal(); // preserve rotation\n\n options.rotation = this.getRotation();\n return obj_assign({}, options, newOptions);\n };\n /**\n * Animate the view. The view\'s center, zoom (or resolution), and rotation\n * can be animated for smooth transitions between view states. For example,\n * to animate the view to a new zoom level:\n *\n * view.animate({zoom: view.getZoom() + 1});\n *\n * By default, the animation lasts one second and uses in-and-out easing. You\n * can customize this behavior by including `duration` (in milliseconds) and\n * `easing` options (see {@link module:ol/easing}).\n *\n * To chain together multiple animations, call the method with multiple\n * animation objects. For example, to first zoom and then pan:\n *\n * view.animate({zoom: 10}, {center: [0, 0]});\n *\n * If you provide a function as the last argument to the animate method, it\n * will get called at the end of an animation series. The callback will be\n * called with `true` if the animation series completed on its own or `false`\n * if it was cancelled.\n *\n * Animations are cancelled by user interactions (e.g. dragging the map) or by\n * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`\n * (or another method that calls one of these).\n *\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation\n * options. Multiple animations can be run in series by passing multiple\n * options objects. To run multiple animations in parallel, call the method\n * multiple times. An optional callback can be provided as a final\n * argument. The callback will be called with a boolean indicating whether\n * the animation completed without being cancelled.\n * @api\n */\n\n\n View.prototype.animate = function (var_args) {\n if (this.isDef() && !this.getAnimating()) {\n this.resolveConstraints(0);\n }\n\n var args = new Array(arguments.length);\n\n for (var i = 0; i < args.length; ++i) {\n var options = arguments[i];\n\n if (options.center) {\n options = obj_assign({}, options);\n options.center = fromUserCoordinate(options.center, this.getProjection());\n }\n\n if (options.anchor) {\n options = obj_assign({}, options);\n options.anchor = fromUserCoordinate(options.anchor, this.getProjection());\n }\n\n args[i] = options;\n }\n\n this.animateInternal.apply(this, args);\n };\n /**\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.\n */\n\n\n View.prototype.animateInternal = function (var_args) {\n var animationCount = arguments.length;\n var callback;\n\n if (animationCount > 1 && typeof arguments[animationCount - 1] === \'function\') {\n callback = arguments[animationCount - 1];\n --animationCount;\n }\n\n if (!this.isDef()) {\n // if view properties are not yet set, shortcut to the final state\n var state = arguments[animationCount - 1];\n\n if (state.center) {\n this.setCenterInternal(state.center);\n }\n\n if (state.zoom !== undefined) {\n this.setZoom(state.zoom);\n }\n\n if (state.rotation !== undefined) {\n this.setRotation(state.rotation);\n }\n\n if (callback) {\n animationCallback(callback, true);\n }\n\n return;\n }\n\n var start = Date.now();\n var center = this.targetCenter_.slice();\n var resolution = this.targetResolution_;\n var rotation = this.targetRotation_;\n var series = [];\n\n for (var i = 0; i < animationCount; ++i) {\n var options =\n /** @type {AnimationOptions} */\n arguments[i];\n var animation = {\n start: start,\n complete: false,\n anchor: options.anchor,\n duration: options.duration !== undefined ? options.duration : 1000,\n easing: options.easing || inAndOut,\n callback: callback\n };\n\n if (options.center) {\n animation.sourceCenter = center;\n animation.targetCenter = options.center.slice();\n center = animation.targetCenter;\n }\n\n if (options.zoom !== undefined) {\n animation.sourceResolution = resolution;\n animation.targetResolution = this.getResolutionForZoom(options.zoom);\n resolution = animation.targetResolution;\n } else if (options.resolution) {\n animation.sourceResolution = resolution;\n animation.targetResolution = options.resolution;\n resolution = animation.targetResolution;\n }\n\n if (options.rotation !== undefined) {\n animation.sourceRotation = rotation;\n var delta = math_modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;\n animation.targetRotation = rotation + delta;\n rotation = animation.targetRotation;\n } // check if animation is a no-op\n\n\n if (isNoopAnimation(animation)) {\n animation.complete = true; // we still push it onto the series for callback handling\n } else {\n start += animation.duration;\n }\n\n series.push(animation);\n }\n\n this.animations_.push(series);\n this.setHint(ViewHint.ANIMATING, 1);\n this.updateAnimations_();\n };\n /**\n * Determine if the view is being animated.\n * @return {boolean} The view is being animated.\n * @api\n */\n\n\n View.prototype.getAnimating = function () {\n return this.hints_[ViewHint.ANIMATING] > 0;\n };\n /**\n * Determine if the user is interacting with the view, such as panning or zooming.\n * @return {boolean} The view is being interacted with.\n * @api\n */\n\n\n View.prototype.getInteracting = function () {\n return this.hints_[ViewHint.INTERACTING] > 0;\n };\n /**\n * Cancel any ongoing animations.\n * @api\n */\n\n\n View.prototype.cancelAnimations = function () {\n this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);\n var anchor;\n\n for (var i = 0, ii = this.animations_.length; i < ii; ++i) {\n var series = this.animations_[i];\n\n if (series[0].callback) {\n animationCallback(series[0].callback, false);\n }\n\n if (!anchor) {\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n\n if (!animation.complete) {\n anchor = animation.anchor;\n break;\n }\n }\n }\n }\n\n this.animations_.length = 0;\n this.cancelAnchor_ = anchor;\n };\n /**\n * Update all animations.\n */\n\n\n View.prototype.updateAnimations_ = function () {\n if (this.updateAnimationKey_ !== undefined) {\n cancelAnimationFrame(this.updateAnimationKey_);\n this.updateAnimationKey_ = undefined;\n }\n\n if (!this.getAnimating()) {\n return;\n }\n\n var now = Date.now();\n var more = false;\n\n for (var i = this.animations_.length - 1; i >= 0; --i) {\n var series = this.animations_[i];\n var seriesComplete = true;\n\n for (var j = 0, jj = series.length; j < jj; ++j) {\n var animation = series[j];\n\n if (animation.complete) {\n continue;\n }\n\n var elapsed = now - animation.start;\n var fraction = animation.duration > 0 ? elapsed / animation.duration : 1;\n\n if (fraction >= 1) {\n animation.complete = true;\n fraction = 1;\n } else {\n seriesComplete = false;\n }\n\n var progress = animation.easing(fraction);\n\n if (animation.sourceCenter) {\n var x0 = animation.sourceCenter[0];\n var y0 = animation.sourceCenter[1];\n var x1 = animation.targetCenter[0];\n var y1 = animation.targetCenter[1];\n var x = x0 + progress * (x1 - x0);\n var y = y0 + progress * (y1 - y0);\n this.targetCenter_ = [x, y];\n }\n\n if (animation.sourceResolution && animation.targetResolution) {\n var resolution = progress === 1 ? animation.targetResolution : animation.sourceResolution + progress * (animation.targetResolution - animation.sourceResolution);\n\n if (animation.anchor) {\n var size = this.getViewportSize_(this.getRotation());\n var constrainedResolution = this.constraints_.resolution(resolution, 0, size, true);\n this.targetCenter_ = this.calculateCenterZoom(constrainedResolution, animation.anchor);\n }\n\n this.targetResolution_ = resolution;\n this.applyTargetState_(true);\n }\n\n if (animation.sourceRotation !== undefined && animation.targetRotation !== undefined) {\n var rotation = progress === 1 ? math_modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI : animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);\n\n if (animation.anchor) {\n var constrainedRotation = this.constraints_.rotation(rotation, true);\n this.targetCenter_ = this.calculateCenterRotate(constrainedRotation, animation.anchor);\n }\n\n this.targetRotation_ = rotation;\n }\n\n this.applyTargetState_(true);\n more = true;\n\n if (!animation.complete) {\n break;\n }\n }\n\n if (seriesComplete) {\n this.animations_[i] = null;\n this.setHint(ViewHint.ANIMATING, -1);\n var callback = series[0].callback;\n\n if (callback) {\n animationCallback(callback, true);\n }\n }\n } // prune completed series\n\n\n this.animations_ = this.animations_.filter(Boolean);\n\n if (more && this.updateAnimationKey_ === undefined) {\n this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_.bind(this));\n }\n };\n /**\n * @param {number} rotation Target rotation.\n * @param {import("./coordinate.js").Coordinate} anchor Rotation anchor.\n * @return {import("./coordinate.js").Coordinate|undefined} Center for rotation and anchor.\n */\n\n\n View.prototype.calculateCenterRotate = function (rotation, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n\n if (currentCenter !== undefined) {\n center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];\n coordinate_rotate(center, rotation - this.getRotation());\n add(center, anchor);\n }\n\n return center;\n };\n /**\n * @param {number} resolution Target resolution.\n * @param {import("./coordinate.js").Coordinate} anchor Zoom anchor.\n * @return {import("./coordinate.js").Coordinate|undefined} Center for resolution and anchor.\n */\n\n\n View.prototype.calculateCenterZoom = function (resolution, anchor) {\n var center;\n var currentCenter = this.getCenterInternal();\n var currentResolution = this.getResolution();\n\n if (currentCenter !== undefined && currentResolution !== undefined) {\n var x = anchor[0] - resolution * (anchor[0] - currentCenter[0]) / currentResolution;\n var y = anchor[1] - resolution * (anchor[1] - currentCenter[1]) / currentResolution;\n center = [x, y];\n }\n\n return center;\n };\n /**\n * Returns the current viewport size.\n * @private\n * @param {number=} opt_rotation Take into account the rotation of the viewport when giving the size\n * @return {import("./size.js").Size} Viewport size or `[100, 100]` when no viewport is found.\n */\n\n\n View.prototype.getViewportSize_ = function (opt_rotation) {\n var size = this.viewportSize_;\n\n if (opt_rotation) {\n var w = size[0];\n var h = size[1];\n return [Math.abs(w * Math.cos(opt_rotation)) + Math.abs(h * Math.sin(opt_rotation)), Math.abs(w * Math.sin(opt_rotation)) + Math.abs(h * Math.cos(opt_rotation))];\n } else {\n return size;\n }\n };\n /**\n * Stores the viewport size on the view. The viewport size is not read every time from the DOM\n * to avoid performance hit and layout reflow.\n * This should be done on map size change.\n * Note: the constraints are not resolved during an animation to avoid stopping it\n * @param {import("./size.js").Size=} opt_size Viewport size; if undefined, [100, 100] is assumed\n */\n\n\n View.prototype.setViewportSize = function (opt_size) {\n this.viewportSize_ = Array.isArray(opt_size) ? opt_size.slice() : [100, 100];\n\n if (!this.getAnimating()) {\n this.resolveConstraints(0);\n }\n };\n /**\n * Get the view center.\n * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.getCenter = function () {\n var center = this.getCenterInternal();\n\n if (!center) {\n return center;\n }\n\n return toUserCoordinate(center, this.getProjection());\n };\n /**\n * Get the view center without transforming to user projection.\n * @return {import("./coordinate.js").Coordinate|undefined} The center of the view.\n */\n\n\n View.prototype.getCenterInternal = function () {\n return (\n /** @type {import("./coordinate.js").Coordinate|undefined} */\n this.get(ViewProperty.CENTER)\n );\n };\n /**\n * @return {Constraints} Constraints.\n */\n\n\n View.prototype.getConstraints = function () {\n return this.constraints_;\n };\n /**\n * @return {boolean} Resolution constraint is set\n */\n\n\n View.prototype.getConstrainResolution = function () {\n return this.options_.constrainResolution;\n };\n /**\n * @param {Array<number>=} opt_hints Destination array.\n * @return {Array<number>} Hint.\n */\n\n\n View.prototype.getHints = function (opt_hints) {\n if (opt_hints !== undefined) {\n opt_hints[0] = this.hints_[0];\n opt_hints[1] = this.hints_[1];\n return opt_hints;\n } else {\n return this.hints_.slice();\n }\n };\n /**\n * Calculate the extent for the current view state and the passed size.\n * The size is the pixel dimensions of the box into which the calculated extent\n * should fit. In most cases you want to get the extent of the entire map,\n * that is `map.getSize()`.\n * @param {import("./size.js").Size=} opt_size Box pixel size. If not provided, the size\n * of the map that uses this view will be used.\n * @return {import("./extent.js").Extent} Extent.\n * @api\n */\n\n\n View.prototype.calculateExtent = function (opt_size) {\n var extent = this.calculateExtentInternal(opt_size);\n return toUserExtent(extent, this.getProjection());\n };\n /**\n * @param {import("./size.js").Size=} opt_size Box pixel size. If not provided,\n * the map\'s last known viewport size will be used.\n * @return {import("./extent.js").Extent} Extent.\n */\n\n\n View.prototype.calculateExtentInternal = function (opt_size) {\n var size = opt_size || this.getViewportSize_();\n var center =\n /** @type {!import("./coordinate.js").Coordinate} */\n this.getCenterInternal();\n asserts_assert(center, 1); // The view center is not defined\n\n var resolution =\n /** @type {!number} */\n this.getResolution();\n asserts_assert(resolution !== undefined, 2); // The view resolution is not defined\n\n var rotation =\n /** @type {!number} */\n this.getRotation();\n asserts_assert(rotation !== undefined, 3); // The view rotation is not defined\n\n return getForViewAndSize(center, resolution, rotation, size);\n };\n /**\n * Get the maximum resolution of the view.\n * @return {number} The maximum resolution of the view.\n * @api\n */\n\n\n View.prototype.getMaxResolution = function () {\n return this.maxResolution_;\n };\n /**\n * Get the minimum resolution of the view.\n * @return {number} The minimum resolution of the view.\n * @api\n */\n\n\n View.prototype.getMinResolution = function () {\n return this.minResolution_;\n };\n /**\n * Get the maximum zoom level for the view.\n * @return {number} The maximum zoom level.\n * @api\n */\n\n\n View.prototype.getMaxZoom = function () {\n return (\n /** @type {number} */\n this.getZoomForResolution(this.minResolution_)\n );\n };\n /**\n * Set a new maximum zoom level for the view.\n * @param {number} zoom The maximum zoom level.\n * @api\n */\n\n\n View.prototype.setMaxZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({\n maxZoom: zoom\n }));\n };\n /**\n * Get the minimum zoom level for the view.\n * @return {number} The minimum zoom level.\n * @api\n */\n\n\n View.prototype.getMinZoom = function () {\n return (\n /** @type {number} */\n this.getZoomForResolution(this.maxResolution_)\n );\n };\n /**\n * Set a new minimum zoom level for the view.\n * @param {number} zoom The minimum zoom level.\n * @api\n */\n\n\n View.prototype.setMinZoom = function (zoom) {\n this.applyOptions_(this.getUpdatedOptions_({\n minZoom: zoom\n }));\n };\n /**\n * Set whether the view shoud allow intermediary zoom levels.\n * @param {boolean} enabled Whether the resolution is constrained.\n * @api\n */\n\n\n View.prototype.setConstrainResolution = function (enabled) {\n this.applyOptions_(this.getUpdatedOptions_({\n constrainResolution: enabled\n }));\n };\n /**\n * Get the view projection.\n * @return {import("./proj/Projection.js").default} The projection of the view.\n * @api\n */\n\n\n View.prototype.getProjection = function () {\n return this.projection_;\n };\n /**\n * Get the view resolution.\n * @return {number|undefined} The resolution of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.getResolution = function () {\n return (\n /** @type {number|undefined} */\n this.get(ViewProperty.RESOLUTION)\n );\n };\n /**\n * Get the resolutions for the view. This returns the array of resolutions\n * passed to the constructor of the View, or undefined if none were given.\n * @return {Array<number>|undefined} The resolutions of the view.\n * @api\n */\n\n\n View.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {import("./size.js").Size=} opt_size Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n * @api\n */\n\n\n View.prototype.getResolutionForExtent = function (extent, opt_size) {\n return this.getResolutionForExtentInternal(fromUserExtent(extent, this.getProjection()), opt_size);\n };\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {import("./size.js").Size=} opt_size Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n */\n\n\n View.prototype.getResolutionForExtentInternal = function (extent, opt_size) {\n var size = opt_size || this.getViewportSize_();\n var xResolution = extent_getWidth(extent) / size[0];\n var yResolution = getHeight(extent) / size[1];\n return Math.max(xResolution, yResolution);\n };\n /**\n * Return a function that returns a value between 0 and 1 for a\n * resolution. Exponential scaling is assumed.\n * @param {number=} opt_power Power.\n * @return {function(number): number} Resolution for value function.\n */\n\n\n View.prototype.getResolutionForValueFunction = function (opt_power) {\n var power = opt_power || 2;\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / Math.log(power);\n return (\n /**\n * @param {number} value Value.\n * @return {number} Resolution.\n */\n function (value) {\n var resolution = maxResolution / Math.pow(power, value * max);\n return resolution;\n }\n );\n };\n /**\n * Get the view rotation.\n * @return {number} The rotation of the view in radians.\n * @observable\n * @api\n */\n\n\n View.prototype.getRotation = function () {\n return (\n /** @type {number} */\n this.get(ViewProperty.ROTATION)\n );\n };\n /**\n * Return a function that returns a resolution for a value between\n * 0 and 1. Exponential scaling is assumed.\n * @param {number=} opt_power Power.\n * @return {function(number): number} Value for resolution function.\n */\n\n\n View.prototype.getValueForResolutionFunction = function (opt_power) {\n var logPower = Math.log(opt_power || 2);\n var maxResolution = this.getConstrainedResolution(this.maxResolution_);\n var minResolution = this.minResolution_;\n var max = Math.log(maxResolution / minResolution) / logPower;\n return (\n /**\n * @param {number} resolution Resolution.\n * @return {number} Value.\n */\n function (resolution) {\n var value = Math.log(maxResolution / resolution) / logPower / max;\n return value;\n }\n );\n };\n /**\n * Returns the size of the viewport minus padding.\n * @private\n * @param {number=} opt_rotation Take into account the rotation of the viewport when giving the size\n * @return {import("./size.js").Size} Viewport size reduced by the padding.\n */\n\n\n View.prototype.getViewportSizeMinusPadding_ = function (opt_rotation) {\n var size = this.getViewportSize_(opt_rotation);\n var padding = this.padding;\n\n if (padding) {\n size = [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]];\n }\n\n return size;\n };\n /**\n * @return {State} View state.\n */\n\n\n View.prototype.getState = function () {\n var projection = this.getProjection();\n var resolution =\n /** @type {number} */\n this.getResolution();\n var rotation = this.getRotation();\n var center =\n /** @type {import("./coordinate.js").Coordinate} */\n this.getCenterInternal();\n var padding = this.padding;\n\n if (padding) {\n var reducedSize = this.getViewportSizeMinusPadding_();\n center = calculateCenterOn(center, this.getViewportSize_(), [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n }\n\n return {\n center: center.slice(0),\n projection: projection !== undefined ? projection : null,\n resolution: resolution,\n rotation: rotation,\n zoom: this.getZoom()\n };\n };\n /**\n * Get the current zoom level. This method may return non-integer zoom levels\n * if the view does not constrain the resolution, or if an interaction or\n * animation is underway.\n * @return {number|undefined} Zoom.\n * @api\n */\n\n\n View.prototype.getZoom = function () {\n var zoom;\n var resolution = this.getResolution();\n\n if (resolution !== undefined) {\n zoom = this.getZoomForResolution(resolution);\n }\n\n return zoom;\n };\n /**\n * Get the zoom level for a resolution.\n * @param {number} resolution The resolution.\n * @return {number|undefined} The zoom level for the provided resolution.\n * @api\n */\n\n\n View.prototype.getZoomForResolution = function (resolution) {\n var offset = this.minZoom_ || 0;\n var max, zoomFactor;\n\n if (this.resolutions_) {\n var nearest = linearFindNearest(this.resolutions_, resolution, 1);\n offset = nearest;\n max = this.resolutions_[nearest];\n\n if (nearest == this.resolutions_.length - 1) {\n zoomFactor = 2;\n } else {\n zoomFactor = max / this.resolutions_[nearest + 1];\n }\n } else {\n max = this.maxResolution_;\n zoomFactor = this.zoomFactor_;\n }\n\n return offset + Math.log(max / resolution) / Math.log(zoomFactor);\n };\n /**\n * Get the resolution for a zoom level.\n * @param {number} zoom Zoom level.\n * @return {number} The view resolution for the provided zoom level.\n * @api\n */\n\n\n View.prototype.getResolutionForZoom = function (zoom) {\n if (this.resolutions_) {\n if (this.resolutions_.length <= 1) {\n return 0;\n }\n\n var baseLevel = math_clamp(Math.floor(zoom), 0, this.resolutions_.length - 2);\n var zoomFactor = this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];\n return this.resolutions_[baseLevel] / Math.pow(zoomFactor, math_clamp(zoom - baseLevel, 0, 1));\n } else {\n return this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_);\n }\n };\n /**\n * Fit the given geometry or extent based on the given map size and border.\n * The size is pixel dimensions of the box to fit the extent into.\n * In most cases you will want to use the map size, that is `map.getSize()`.\n * Takes care of the map angle.\n * @param {import("./geom/SimpleGeometry.js").default|import("./extent.js").Extent} geometryOrExtent The geometry or\n * extent to fit the view to.\n * @param {FitOptions=} opt_options Options.\n * @api\n */\n\n\n View.prototype.fit = function (geometryOrExtent, opt_options) {\n /** @type {import("./geom/SimpleGeometry.js").default} */\n var geometry;\n asserts_assert(Array.isArray(geometryOrExtent) || typeof\n /** @type {?} */\n geometryOrExtent.getSimplifiedGeometry === \'function\', 24); // Invalid extent or geometry provided as `geometry`\n\n if (Array.isArray(geometryOrExtent)) {\n asserts_assert(!extent_isEmpty(geometryOrExtent), 25); // Cannot fit empty extent provided as `geometry`\n\n var extent = fromUserExtent(geometryOrExtent, this.getProjection());\n geometry = fromExtent(extent);\n } else if (geometryOrExtent.getType() === geom_GeometryType.CIRCLE) {\n var extent = fromUserExtent(geometryOrExtent.getExtent(), this.getProjection());\n geometry = fromExtent(extent);\n geometry.rotate(this.getRotation(), getCenter(extent));\n } else {\n var userProjection = getUserProjection();\n\n if (userProjection) {\n geometry =\n /** @type {import("./geom/SimpleGeometry.js").default} */\n geometryOrExtent.clone().transform(userProjection, this.getProjection());\n } else {\n geometry = geometryOrExtent;\n }\n }\n\n this.fitInternal(geometry, opt_options);\n };\n /**\n * @param {import("./geom/SimpleGeometry.js").default} geometry The geometry.\n * @param {FitOptions=} opt_options Options.\n */\n\n\n View.prototype.fitInternal = function (geometry, opt_options) {\n var options = opt_options || {};\n var size = options.size;\n\n if (!size) {\n size = this.getViewportSizeMinusPadding_();\n }\n\n var padding = options.padding !== undefined ? options.padding : [0, 0, 0, 0];\n var nearest = options.nearest !== undefined ? options.nearest : false;\n var minResolution;\n\n if (options.minResolution !== undefined) {\n minResolution = options.minResolution;\n } else if (options.maxZoom !== undefined) {\n minResolution = this.getResolutionForZoom(options.maxZoom);\n } else {\n minResolution = 0;\n }\n\n var coords = geometry.getFlatCoordinates(); // calculate rotated extent\n\n var rotation = this.getRotation();\n var cosAngle = Math.cos(-rotation);\n var sinAngle = Math.sin(-rotation);\n var minRotX = +Infinity;\n var minRotY = +Infinity;\n var maxRotX = -Infinity;\n var maxRotY = -Infinity;\n var stride = geometry.getStride();\n\n for (var i = 0, ii = coords.length; i < ii; i += stride) {\n var rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;\n var rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;\n minRotX = Math.min(minRotX, rotX);\n minRotY = Math.min(minRotY, rotY);\n maxRotX = Math.max(maxRotX, rotX);\n maxRotY = Math.max(maxRotY, rotY);\n } // calculate resolution\n\n\n var resolution = this.getResolutionForExtentInternal([minRotX, minRotY, maxRotX, maxRotY], [size[0] - padding[1] - padding[3], size[1] - padding[0] - padding[2]]);\n resolution = isNaN(resolution) ? minResolution : Math.max(resolution, minResolution);\n resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1); // calculate center\n\n sinAngle = -sinAngle; // go back to original rotation\n\n var centerRotX = (minRotX + maxRotX) / 2;\n var centerRotY = (minRotY + maxRotY) / 2;\n centerRotX += (padding[1] - padding[3]) / 2 * resolution;\n centerRotY += (padding[0] - padding[2]) / 2 * resolution;\n var centerX = centerRotX * cosAngle - centerRotY * sinAngle;\n var centerY = centerRotY * cosAngle + centerRotX * sinAngle;\n var center = this.getConstrainedCenter([centerX, centerY], resolution);\n var callback = options.callback ? options.callback : VOID;\n\n if (options.duration !== undefined) {\n this.animateInternal({\n resolution: resolution,\n center: center,\n duration: options.duration,\n easing: options.easing\n }, callback);\n } else {\n this.targetResolution_ = resolution;\n this.targetCenter_ = center;\n this.applyTargetState_(false, true);\n animationCallback(callback, true);\n }\n };\n /**\n * Center on coordinate and view position.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n * @api\n */\n\n\n View.prototype.centerOn = function (coordinate, size, position) {\n this.centerOnInternal(fromUserCoordinate(coordinate, this.getProjection()), size, position);\n };\n /**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n */\n\n\n View.prototype.centerOnInternal = function (coordinate, size, position) {\n this.setCenterInternal(calculateCenterOn(coordinate, size, position, this.getResolution(), this.getRotation()));\n };\n /**\n * Calculates the shift between map and viewport center.\n * @param {import("./coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import("./size.js").Size} size Size.\n * @return {Array<number>|undefined} Center shift.\n */\n\n\n View.prototype.calculateCenterShift = function (center, resolution, rotation, size) {\n var centerShift;\n var padding = this.padding;\n\n if (padding && center) {\n var reducedSize = this.getViewportSizeMinusPadding_(-rotation);\n var shiftedCenter = calculateCenterOn(center, size, [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]], resolution, rotation);\n centerShift = [center[0] - shiftedCenter[0], center[1] - shiftedCenter[1]];\n }\n\n return centerShift;\n };\n /**\n * @return {boolean} Is defined.\n */\n\n\n View.prototype.isDef = function () {\n return !!this.getCenterInternal() && this.getResolution() !== undefined;\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.\n * @api\n */\n\n\n View.prototype.adjustCenter = function (deltaCoordinates) {\n var center = toUserCoordinate(this.targetCenter_, this.getProjection());\n this.setCenter([center[0] + deltaCoordinates[0], center[1] + deltaCoordinates[1]]);\n };\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate} deltaCoordinates Relative value to add.\n */\n\n\n View.prototype.adjustCenterInternal = function (deltaCoordinates) {\n var center = this.targetCenter_;\n this.setCenterInternal([center[0] + deltaCoordinates[0], center[1] + deltaCoordinates[1]]);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.adjustResolution = function (ratio, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.adjustResolutionInternal(ratio, anchor);\n };\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.adjustResolutionInternal = function (ratio, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var size = this.getViewportSize_(this.getRotation());\n var newResolution = this.constraints_.resolution(this.targetResolution_ * ratio, 0, size, isMoving);\n\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterZoom(newResolution, opt_anchor);\n }\n\n this.targetResolution_ *= ratio;\n this.applyTargetState_();\n };\n /**\n * Adds a value to the view zoom level, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom level.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.adjustZoom = function (delta, opt_anchor) {\n this.adjustResolution(Math.pow(this.zoomFactor_, -delta), opt_anchor);\n };\n /**\n * Adds a value to the view rotation, optionally using an anchor. Any rotation\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The rotation center.\n * @api\n */\n\n\n View.prototype.adjustRotation = function (delta, opt_anchor) {\n if (opt_anchor) {\n opt_anchor = fromUserCoordinate(opt_anchor, this.getProjection());\n }\n\n this.adjustRotationInternal(delta, opt_anchor);\n };\n /**\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The rotation center.\n */\n\n\n View.prototype.adjustRotationInternal = function (delta, opt_anchor) {\n var isMoving = this.getAnimating() || this.getInteracting();\n var newRotation = this.constraints_.rotation(this.targetRotation_ + delta, isMoving);\n\n if (opt_anchor) {\n this.targetCenter_ = this.calculateCenterRotate(newRotation, opt_anchor);\n }\n\n this.targetRotation_ += delta;\n this.applyTargetState_();\n };\n /**\n * Set the center of the current view. Any extent constraint will apply.\n * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.setCenter = function (center) {\n this.setCenterInternal(fromUserCoordinate(center, this.getProjection()));\n };\n /**\n * Set the center using the view projection (not the user projection).\n * @param {import("./coordinate.js").Coordinate|undefined} center The center of the view.\n */\n\n\n View.prototype.setCenterInternal = function (center) {\n this.targetCenter_ = center;\n this.applyTargetState_();\n };\n /**\n * @param {import("./ViewHint.js").default} hint Hint.\n * @param {number} delta Delta.\n * @return {number} New value.\n */\n\n\n View.prototype.setHint = function (hint, delta) {\n this.hints_[hint] += delta;\n this.changed();\n return this.hints_[hint];\n };\n /**\n * Set the resolution for this view. Any resolution constraint will apply.\n * @param {number|undefined} resolution The resolution of the view.\n * @observable\n * @api\n */\n\n\n View.prototype.setResolution = function (resolution) {\n this.targetResolution_ = resolution;\n this.applyTargetState_();\n };\n /**\n * Set the rotation for this view. Any rotation constraint will apply.\n * @param {number} rotation The rotation of the view in radians.\n * @observable\n * @api\n */\n\n\n View.prototype.setRotation = function (rotation) {\n this.targetRotation_ = rotation;\n this.applyTargetState_();\n };\n /**\n * Zoom to a specific zoom level. Any resolution constrain will apply.\n * @param {number} zoom Zoom level.\n * @api\n */\n\n\n View.prototype.setZoom = function (zoom) {\n this.setResolution(this.getResolutionForZoom(zoom));\n };\n /**\n * Recompute rotation/resolution/center based on target values.\n * Note: we have to compute rotation first, then resolution and center considering that\n * parameters can influence one another in case a view extent constraint is present.\n * @param {boolean=} opt_doNotCancelAnims Do not cancel animations.\n * @param {boolean=} opt_forceMoving Apply constraints as if the view is moving.\n * @private\n */\n\n\n View.prototype.applyTargetState_ = function (opt_doNotCancelAnims, opt_forceMoving) {\n var isMoving = this.getAnimating() || this.getInteracting() || opt_forceMoving; // compute rotation\n\n var newRotation = this.constraints_.rotation(this.targetRotation_, isMoving);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, 0, size, isMoving);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, isMoving, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n\n if (this.get(ViewProperty.ROTATION) !== newRotation) {\n this.set(ViewProperty.ROTATION, newRotation);\n }\n\n if (this.get(ViewProperty.RESOLUTION) !== newResolution) {\n this.set(ViewProperty.RESOLUTION, newResolution);\n }\n\n if (!this.get(ViewProperty.CENTER) || !coordinate_equals(this.get(ViewProperty.CENTER), newCenter)) {\n this.set(ViewProperty.CENTER, newCenter);\n }\n\n if (this.getAnimating() && !opt_doNotCancelAnims) {\n this.cancelAnimations();\n }\n\n this.cancelAnchor_ = undefined;\n };\n /**\n * If any constraints need to be applied, an animation will be triggered.\n * This is typically done on interaction end.\n * Note: calling this with a duration of 0 will apply the constrained values straight away,\n * without animation.\n * @param {number=} opt_duration The animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.resolveConstraints = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var duration = opt_duration !== undefined ? opt_duration : 200;\n var direction = opt_resolutionDirection || 0;\n var newRotation = this.constraints_.rotation(this.targetRotation_);\n var size = this.getViewportSize_(newRotation);\n var newResolution = this.constraints_.resolution(this.targetResolution_, direction, size);\n var newCenter = this.constraints_.center(this.targetCenter_, newResolution, size, false, this.calculateCenterShift(this.targetCenter_, newResolution, newRotation, size));\n\n if (duration === 0 && !this.cancelAnchor_) {\n this.targetResolution_ = newResolution;\n this.targetRotation_ = newRotation;\n this.targetCenter_ = newCenter;\n this.applyTargetState_();\n return;\n }\n\n var anchor = opt_anchor || (duration === 0 ? this.cancelAnchor_ : undefined);\n this.cancelAnchor_ = undefined;\n\n if (this.getResolution() !== newResolution || this.getRotation() !== newRotation || !this.getCenterInternal() || !coordinate_equals(this.getCenterInternal(), newCenter)) {\n if (this.getAnimating()) {\n this.cancelAnimations();\n }\n\n this.animateInternal({\n rotation: newRotation,\n center: newCenter,\n resolution: newResolution,\n duration: duration,\n easing: easeOut,\n anchor: anchor\n });\n }\n };\n /**\n * Notify the View that an interaction has started.\n * The view state will be resolved to a stable one if needed\n * (depending on its constraints).\n * @api\n */\n\n\n View.prototype.beginInteraction = function () {\n this.resolveConstraints(0);\n this.setHint(ViewHint.INTERACTING, 1);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number=} opt_duration Animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n * @api\n */\n\n\n View.prototype.endInteraction = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n var anchor = opt_anchor && fromUserCoordinate(opt_anchor, this.getProjection());\n this.endInteractionInternal(opt_duration, opt_resolutionDirection, anchor);\n };\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number=} opt_duration Animation duration in ms.\n * @param {number=} opt_resolutionDirection Which direction to zoom.\n * @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.\n */\n\n\n View.prototype.endInteractionInternal = function (opt_duration, opt_resolutionDirection, opt_anchor) {\n this.setHint(ViewHint.INTERACTING, -1);\n this.resolveConstraints(opt_duration, opt_resolutionDirection, opt_anchor);\n };\n /**\n * Get a valid position for the view center according to the current constraints.\n * @param {import("./coordinate.js").Coordinate|undefined} targetCenter Target center position.\n * @param {number=} opt_targetResolution Target resolution. If not supplied, the current one will be used.\n * This is useful to guess a valid center position at a different zoom level.\n * @return {import("./coordinate.js").Coordinate|undefined} Valid center position.\n */\n\n\n View.prototype.getConstrainedCenter = function (targetCenter, opt_targetResolution) {\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.center(targetCenter, opt_targetResolution || this.getResolution(), size);\n };\n /**\n * Get a valid zoom level according to the current view constraints.\n * @param {number|undefined} targetZoom Target zoom.\n * @param {number=} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid zoom level.\n */\n\n\n View.prototype.getConstrainedZoom = function (targetZoom, opt_direction) {\n var targetRes = this.getResolutionForZoom(targetZoom);\n return this.getZoomForResolution(this.getConstrainedResolution(targetRes, opt_direction));\n };\n /**\n * Get a valid resolution according to the current view constraints.\n * @param {number|undefined} targetResolution Target resolution.\n * @param {number=} [opt_direction=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid resolution.\n */\n\n\n View.prototype.getConstrainedResolution = function (targetResolution, opt_direction) {\n var direction = opt_direction || 0;\n var size = this.getViewportSize_(this.getRotation());\n return this.constraints_.resolution(targetResolution, direction, size);\n };\n\n return View;\n}(ol_Object);\n/**\n * @param {Function} callback Callback.\n * @param {*} returnValue Return value.\n */\n\n\nfunction animationCallback(callback, returnValue) {\n setTimeout(function () {\n callback(returnValue);\n }, 0);\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import("./centerconstraint.js").Type} The constraint.\n */\n\n\nfunction createCenterConstraint(options) {\n if (options.extent !== undefined) {\n var smooth = options.smoothExtentConstraint !== undefined ? options.smoothExtentConstraint : true;\n return createExtent(options.extent, options.constrainOnlyCenter, smooth);\n }\n\n var projection = createProjection(options.projection, \'EPSG:3857\');\n\n if (options.multiWorld !== true && projection.isGlobal()) {\n var extent = projection.getExtent().slice();\n extent[0] = -Infinity;\n extent[2] = Infinity;\n return createExtent(extent, false, false);\n }\n\n return none;\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {{constraint: import("./resolutionconstraint.js").Type, maxResolution: number,\n * minResolution: number, minZoom: number, zoomFactor: number}} The constraint.\n */\n\nfunction createResolutionConstraint(options) {\n var resolutionConstraint;\n var maxResolution;\n var minResolution; // TODO: move these to be ol constants\n // see https://github.com/openlayers/openlayers/issues/2076\n\n var defaultMaxZoom = 28;\n var defaultZoomFactor = 2;\n var minZoom = options.minZoom !== undefined ? options.minZoom : DEFAULT_MIN_ZOOM;\n var maxZoom = options.maxZoom !== undefined ? options.maxZoom : defaultMaxZoom;\n var zoomFactor = options.zoomFactor !== undefined ? options.zoomFactor : defaultZoomFactor;\n var multiWorld = options.multiWorld !== undefined ? options.multiWorld : false;\n var smooth = options.smoothResolutionConstraint !== undefined ? options.smoothResolutionConstraint : true;\n var showFullExtent = options.showFullExtent !== undefined ? options.showFullExtent : false;\n var projection = createProjection(options.projection, \'EPSG:3857\');\n var projExtent = projection.getExtent();\n var constrainOnlyCenter = options.constrainOnlyCenter;\n var extent = options.extent;\n\n if (!multiWorld && !extent && projection.isGlobal()) {\n constrainOnlyCenter = false;\n extent = projExtent;\n }\n\n if (options.resolutions !== undefined) {\n var resolutions = options.resolutions;\n maxResolution = resolutions[minZoom];\n minResolution = resolutions[maxZoom] !== undefined ? resolutions[maxZoom] : resolutions[resolutions.length - 1];\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToResolutions(resolutions, smooth, !constrainOnlyCenter && extent, showFullExtent);\n } else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n } else {\n // calculate the default min and max resolution\n var size = !projExtent ? // use an extent that can fit the whole world if need be\n 360 * Units_METERS_PER_UNIT[proj_Units.DEGREES] / projection.getMetersPerUnit() : Math.max(extent_getWidth(projExtent), getHeight(projExtent));\n var defaultMaxResolution = size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);\n var defaultMinResolution = defaultMaxResolution / Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM); // user provided maxResolution takes precedence\n\n maxResolution = options.maxResolution;\n\n if (maxResolution !== undefined) {\n minZoom = 0;\n } else {\n maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);\n } // user provided minResolution takes precedence\n\n\n minResolution = options.minResolution;\n\n if (minResolution === undefined) {\n if (options.maxZoom !== undefined) {\n if (options.maxResolution !== undefined) {\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);\n } else {\n minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);\n }\n } else {\n minResolution = defaultMinResolution;\n }\n } // given discrete zoom levels, minResolution may be different than provided\n\n\n maxZoom = minZoom + Math.floor(Math.log(maxResolution / minResolution) / Math.log(zoomFactor));\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToPower(zoomFactor, maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n } else {\n resolutionConstraint = createMinMaxResolution(maxResolution, minResolution, smooth, !constrainOnlyCenter && extent, showFullExtent);\n }\n }\n\n return {\n constraint: resolutionConstraint,\n maxResolution: maxResolution,\n minResolution: minResolution,\n minZoom: minZoom,\n zoomFactor: zoomFactor\n };\n}\n/**\n * @param {ViewOptions} options View options.\n * @return {import("./rotationconstraint.js").Type} Rotation constraint.\n */\n\nfunction createRotationConstraint(options) {\n var enableRotation = options.enableRotation !== undefined ? options.enableRotation : true;\n\n if (enableRotation) {\n var constrainRotation = options.constrainRotation;\n\n if (constrainRotation === undefined || constrainRotation === true) {\n return createSnapToZero();\n } else if (constrainRotation === false) {\n return rotationconstraint_none;\n } else if (typeof constrainRotation === \'number\') {\n return createSnapToN(constrainRotation);\n } else {\n return rotationconstraint_none;\n }\n } else {\n return disable;\n }\n}\n/**\n * Determine if an animation involves no view change.\n * @param {Animation} animation The animation.\n * @return {boolean} The animation involves no view change.\n */\n\nfunction isNoopAnimation(animation) {\n if (animation.sourceCenter && animation.targetCenter) {\n if (!coordinate_equals(animation.sourceCenter, animation.targetCenter)) {\n return false;\n }\n }\n\n if (animation.sourceResolution !== animation.targetResolution) {\n return false;\n }\n\n if (animation.sourceRotation !== animation.targetRotation) {\n return false;\n }\n\n return true;\n}\n/**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("./size.js").Size} size Box pixel size.\n * @param {import("./pixel.js").Pixel} position Position on the view to center on.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {import("./coordinate.js").Coordinate} Shifted center.\n */\n\nfunction calculateCenterOn(coordinate, size, position, resolution, rotation) {\n // calculate rotated position\n var cosAngle = Math.cos(-rotation);\n var sinAngle = Math.sin(-rotation);\n var rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n var rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n rotX += (size[0] / 2 - position[0]) * resolution;\n rotY += (position[1] - size[1] / 2) * resolution; // go back to original angle\n\n sinAngle = -sinAngle; // go back to original rotation\n\n var centerX = rotX * cosAngle - rotY * sinAngle;\n var centerY = rotY * cosAngle + rotX * sinAngle;\n return [centerX, centerY];\n}\n\n/* harmony default export */ var ol_View = (View);\n;// CONCATENATED MODULE: ./node_modules/ol/size.js\n/**\n * @module ol/size\n */\n\n/**\n * An array of numbers representing a size: `[width, height]`.\n * @typedef {Array<number>} Size\n * @api\n */\n\n/**\n * Returns a buffered size.\n * @param {Size} size Size.\n * @param {number} num The amount by which to buffer.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} The buffered size.\n */\nfunction size_buffer(size, num, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n\n opt_size[0] = size[0] + 2 * num;\n opt_size[1] = size[1] + 2 * num;\n return opt_size;\n}\n/**\n * Determines if a size has a positive area.\n * @param {Size} size The size to test.\n * @return {boolean} The size has a positive area.\n */\n\nfunction hasArea(size) {\n return size[0] > 0 && size[1] > 0;\n}\n/**\n * Returns a size scaled by a ratio. The result will be an array of integers.\n * @param {Size} size Size.\n * @param {number} ratio Ratio.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} The scaled size.\n */\n\nfunction size_scale(size, ratio, opt_size) {\n if (opt_size === undefined) {\n opt_size = [0, 0];\n }\n\n opt_size[0] = size[0] * ratio + 0.5 | 0;\n opt_size[1] = size[1] * ratio + 0.5 | 0;\n return opt_size;\n}\n/**\n * Returns an `Size` array for the passed in number (meaning: square) or\n * `Size` array.\n * (meaning: non-square),\n * @param {number|Size} size Width and height.\n * @param {Size=} opt_size Optional reusable size array.\n * @return {Size} Size.\n * @api\n */\n\nfunction toSize(size, opt_size) {\n if (Array.isArray(size)) {\n return size;\n } else {\n if (opt_size === undefined) {\n opt_size = [size, size];\n } else {\n opt_size[0] = size;\n opt_size[1] = size;\n }\n\n return opt_size;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/PluggableMap.js\nvar PluggableMap_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/PluggableMap\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 * State of the current frame. Only `pixelRatio`, `time` and `viewState` should\n * be used in applications.\n * @typedef {Object} FrameState\n * @property {number} pixelRatio The pixel ratio of the frame.\n * @property {number} time The time when rendering of the frame was requested.\n * @property {import("./View.js").State} viewState The state of the current view.\n * @property {boolean} animate\n * @property {import("./transform.js").Transform} coordinateToPixelTransform\n * @property {import("rbush").default} declutterTree\n * @property {null|import("./extent.js").Extent} extent\n * @property {number} index\n * @property {Array<import("./layer/Layer.js").State>} layerStatesArray\n * @property {number} layerIndex\n * @property {import("./transform.js").Transform} pixelToCoordinateTransform\n * @property {Array<PostRenderFunction>} postRenderFunctions\n * @property {import("./size.js").Size} size\n * @property {TileQueue} tileQueue\n * @property {!Object<string, Object<string, boolean>>} usedTiles\n * @property {Array<number>} viewHints\n * @property {!Object<string, Object<string, boolean>>} wantedTiles\n */\n\n/**\n * @typedef {function(PluggableMap, ?FrameState): any} PostRenderFunction\n */\n\n/**\n * @typedef {Object} AtPixelOptions\n * @property {undefined|function(import("./layer/Layer.js").default): boolean} [layerFilter] Layer filter\n * function. The filter function will receive one argument, the\n * {@link module:ol/layer/Layer layer-candidate} and it should return a boolean value.\n * Only layers which are visible and for which this function returns `true`\n * will be tested for features. By default, all visible layers will be tested.\n * @property {number} [hitTolerance=0] Hit-detection tolerance in css pixels. Pixels\n * inside the radius around the given position will be checked for features.\n * @property {boolean} [checkWrapped=true] Check-Wrapped Will check for for wrapped geometries inside the range of\n * +/- 1 world width. Works only if a projection is used that can be wrapped.\n */\n\n/**\n * @typedef {Object} MapOptionsInternal\n * @property {Collection<import("./control/Control.js").default>} [controls]\n * @property {Collection<import("./interaction/Interaction.js").default>} [interactions]\n * @property {HTMLElement|Document} keyboardEventTarget\n * @property {Collection<import("./Overlay.js").default>} overlays\n * @property {Object<string, *>} values\n */\n\n/**\n * Object literal with config options for the map.\n * @typedef {Object} MapOptions\n * @property {Collection<import("./control/Control.js").default>|Array<import("./control/Control.js").default>} [controls]\n * Controls initially added to the map. If not specified,\n * {@link module:ol/control~defaults} is used.\n * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between\n * physical pixels and device-independent pixels (dips) on the device.\n * @property {Collection<import("./interaction/Interaction.js").default>|Array<import("./interaction/Interaction.js").default>} [interactions]\n * Interactions that are initially added to the map. If not specified,\n * {@link module:ol/interaction~defaults} is used.\n * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to\n * listen to keyboard events on. This determines when the `KeyboardPan` and\n * `KeyboardZoom` interactions trigger. For example, if this option is set to\n * `document` the keyboard interactions will always trigger. If this option is\n * not specified, the element the library listens to keyboard events on is the\n * map target (i.e. the user-provided div for the map). If this is not\n * `document`, the target element needs to be focused for key events to be\n * emitted, requiring that the target element has a `tabindex` attribute.\n * @property {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>|LayerGroup} [layers]\n * Layers. If this is not defined, a map with no layers will be rendered. Note\n * that layers are rendered in the order supplied, so if you want, for example,\n * a vector layer to appear on top of a tile layer, it must come after the tile\n * layer.\n * @property {number} [maxTilesLoading=16] Maximum number tiles to load\n * simultaneously.\n * @property {number} [moveTolerance=1] The minimum distance in pixels the\n * cursor must move to be detected as a map move event instead of a click.\n * Increasing this value can make it easier to click on the map.\n * @property {Collection<import("./Overlay.js").default>|Array<import("./Overlay.js").default>} [overlays]\n * Overlays initially added to the map. By default, no overlays are added.\n * @property {HTMLElement|string} [target] The container for the map, either the\n * element itself or the `id` of the element. If not specified at construction\n * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be\n * rendered. If passed by element, the container can be in a secondary document.\n * @property {View} [view] The map\'s view. No layer sources will be\n * fetched unless this is specified at construction time or through\n * {@link module:ol/Map~Map#setView}.\n */\n\n/**\n * @fires import("./MapBrowserEvent.js").MapBrowserEvent\n * @fires import("./MapEvent.js").MapEvent\n * @fires import("./render/Event.js").default#precompose\n * @fires import("./render/Event.js").default#postcompose\n * @fires import("./render/Event.js").default#rendercomplete\n * @api\n */\n\nvar PluggableMap =\n/** @class */\nfunction (_super) {\n PluggableMap_extends(PluggableMap, _super);\n /**\n * @param {MapOptions} options Map options.\n */\n\n\n function PluggableMap(options) {\n var _this = _super.call(this) || this;\n\n var optionsInternal = createOptionsInternal(options);\n /** @private */\n\n _this.boundHandleBrowserEvent_ = _this.handleBrowserEvent.bind(_this);\n /**\n * @type {number}\n * @private\n */\n\n _this.maxTilesLoading_ = options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = options.pixelRatio !== undefined ? options.pixelRatio : DEVICE_PIXEL_RATIO;\n /**\n * @private\n * @type {*}\n */\n\n _this.postRenderTimeoutHandle_;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.animationDelayKey_;\n /**\n * @private\n */\n\n _this.animationDelay_ =\n /** @this {PluggableMap} */\n function () {\n this.animationDelayKey_ = undefined;\n this.renderFrame_(Date.now());\n }.bind(_this);\n /**\n * @private\n * @type {import("./transform.js").Transform}\n */\n\n\n _this.coordinateToPixelTransform_ = create();\n /**\n * @private\n * @type {import("./transform.js").Transform}\n */\n\n _this.pixelToCoordinateTransform_ = create();\n /**\n * @private\n * @type {number}\n */\n\n _this.frameIndex_ = 0;\n /**\n * @private\n * @type {?FrameState}\n */\n\n _this.frameState_ = null;\n /**\n * The extent at the previous \'moveend\' event.\n * @private\n * @type {import("./extent.js").Extent}\n */\n\n _this.previousExtent_ = null;\n /**\n * @private\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.viewPropertyListenerKey_ = null;\n /**\n * @private\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.viewChangeListenerKey_ = null;\n /**\n * @private\n * @type {?Array<import("./events.js").EventsKey>}\n */\n\n _this.layerGroupPropertyListenerKeys_ = null;\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n _this.viewport_ = document.createElement(\'div\');\n _this.viewport_.className = \'ol-viewport\' + (\'ontouchstart\' in window ? \' ol-touch\' : \'\');\n _this.viewport_.style.position = \'relative\';\n _this.viewport_.style.overflow = \'hidden\';\n _this.viewport_.style.width = \'100%\';\n _this.viewport_.style.height = \'100%\';\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n _this.overlayContainer_ = document.createElement(\'div\');\n _this.overlayContainer_.style.position = \'absolute\';\n _this.overlayContainer_.style.zIndex = \'0\';\n _this.overlayContainer_.style.width = \'100%\';\n _this.overlayContainer_.style.height = \'100%\';\n _this.overlayContainer_.style.pointerEvents = \'none\';\n _this.overlayContainer_.className = \'ol-overlaycontainer\';\n\n _this.viewport_.appendChild(_this.overlayContainer_);\n /**\n * @private\n * @type {!HTMLElement}\n */\n\n\n _this.overlayContainerStopEvent_ = document.createElement(\'div\');\n _this.overlayContainerStopEvent_.style.position = \'absolute\';\n _this.overlayContainerStopEvent_.style.zIndex = \'0\';\n _this.overlayContainerStopEvent_.style.width = \'100%\';\n _this.overlayContainerStopEvent_.style.height = \'100%\';\n _this.overlayContainerStopEvent_.style.pointerEvents = \'none\';\n _this.overlayContainerStopEvent_.className = \'ol-overlaycontainer-stopevent\';\n\n _this.viewport_.appendChild(_this.overlayContainerStopEvent_);\n /**\n * @private\n * @type {MapBrowserEventHandler}\n */\n\n\n _this.mapBrowserEventHandler_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.moveTolerance_ = options.moveTolerance;\n /**\n * @private\n * @type {HTMLElement|Document}\n */\n\n _this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;\n /**\n * @private\n * @type {?Array<import("./events.js").EventsKey>}\n */\n\n _this.keyHandlerKeys_ = null;\n /**\n * @type {Collection<import("./control/Control.js").default>}\n * @protected\n */\n\n _this.controls = optionsInternal.controls || new ol_Collection();\n /**\n * @type {Collection<import("./interaction/Interaction.js").default>}\n * @protected\n */\n\n _this.interactions = optionsInternal.interactions || new ol_Collection();\n /**\n * @type {Collection<import("./Overlay.js").default>}\n * @private\n */\n\n _this.overlays_ = optionsInternal.overlays;\n /**\n * A lookup of overlays by id.\n * @private\n * @type {Object<string, import("./Overlay.js").default>}\n */\n\n _this.overlayIdIndex_ = {};\n /**\n * @type {import("./renderer/Map.js").default}\n * @private\n */\n\n _this.renderer_ = null;\n /**\n * @type {undefined|function(Event): void}\n * @private\n */\n\n _this.handleResize_;\n /**\n * @private\n * @type {!Array<PostRenderFunction>}\n */\n\n _this.postRenderFunctions_ = [];\n /**\n * @private\n * @type {TileQueue}\n */\n\n _this.tileQueue_ = new ol_TileQueue(_this.getTilePriority.bind(_this), _this.handleTileChange_.bind(_this));\n\n _this.addEventListener(getChangeEventType(MapProperty.LAYERGROUP), _this.handleLayerGroupChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.VIEW), _this.handleViewChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.SIZE), _this.handleSizeChanged_);\n\n _this.addEventListener(getChangeEventType(MapProperty.TARGET), _this.handleTargetChanged_); // setProperties will trigger the rendering of the map if the map\n // is "defined" already.\n\n\n _this.setProperties(optionsInternal.values);\n\n _this.controls.forEach(\n /**\n * @param {import("./control/Control.js").default} control Control.\n * @this {PluggableMap}\n */\n function (control) {\n control.setMap(this);\n }.bind(_this));\n\n _this.controls.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n\n _this.controls.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n\n _this.interactions.forEach(\n /**\n * @param {import("./interaction/Interaction.js").default} interaction Interaction.\n * @this {PluggableMap}\n */\n function (interaction) {\n interaction.setMap(this);\n }.bind(_this));\n\n _this.interactions.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(this);\n }.bind(_this));\n\n _this.interactions.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n event.element.setMap(null);\n }.bind(_this));\n\n _this.overlays_.forEach(_this.addOverlayInternal_.bind(_this));\n\n _this.overlays_.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n this.addOverlayInternal_(\n /** @type {import("./Overlay.js").default} */\n event.element);\n }.bind(_this));\n\n _this.overlays_.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("./Collection.js").CollectionEvent} event CollectionEvent.\n */\n function (event) {\n var overlay =\n /** @type {import("./Overlay.js").default} */\n event.element;\n var id = overlay.getId();\n\n if (id !== undefined) {\n delete this.overlayIdIndex_[id.toString()];\n }\n\n event.element.setMap(null);\n }.bind(_this));\n\n return _this;\n }\n /**\n * @abstract\n * @return {import("./renderer/Map.js").default} The map renderer\n */\n\n\n PluggableMap.prototype.createRenderer = function () {\n throw new Error(\'Use a map type that has a createRenderer method\');\n };\n /**\n * Add the given control to the map.\n * @param {import("./control/Control.js").default} control Control.\n * @api\n */\n\n\n PluggableMap.prototype.addControl = function (control) {\n this.getControls().push(control);\n };\n /**\n * Add the given interaction to the map. If you want to add an interaction\n * at another point of the collection use `getInteraction()` and the methods\n * available on {@link module:ol/Collection~Collection}. This can be used to\n * stop the event propagation from the handleEvent function. The interactions\n * get to handle the events in the reverse order of this collection.\n * @param {import("./interaction/Interaction.js").default} interaction Interaction to add.\n * @api\n */\n\n\n PluggableMap.prototype.addInteraction = function (interaction) {\n this.getInteractions().push(interaction);\n };\n /**\n * Adds the given layer to the top of this map. If you want to add a layer\n * elsewhere in the stack, use `getLayers()` and the methods available on\n * {@link module:ol/Collection~Collection}.\n * @param {import("./layer/Base.js").default} layer Layer.\n * @api\n */\n\n\n PluggableMap.prototype.addLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n layers.push(layer);\n };\n /**\n * Add the given overlay to the map.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @api\n */\n\n\n PluggableMap.prototype.addOverlay = function (overlay) {\n this.getOverlays().push(overlay);\n };\n /**\n * This deals with map\'s overlay collection changes.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @private\n */\n\n\n PluggableMap.prototype.addOverlayInternal_ = function (overlay) {\n var id = overlay.getId();\n\n if (id !== undefined) {\n this.overlayIdIndex_[id.toString()] = overlay;\n }\n\n overlay.setMap(this);\n };\n /**\n *\n * Clean up.\n */\n\n\n PluggableMap.prototype.disposeInternal = function () {\n this.setTarget(null);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Detect features that intersect a pixel on the viewport, and execute a\n * callback with each intersecting feature. Layers included in the detection can\n * be configured through the `layerFilter` option in `opt_options`.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be\n * called with two arguments. The first argument is one\n * {@link module:ol/Feature feature} or\n * {@link module:ol/render/Feature render feature} at the pixel, the second is\n * the {@link module:ol/layer/Layer layer} of the feature and will be null for\n * unmanaged layers. To stop detection, callback functions can return a\n * truthy value.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template S,T\n * @api\n */\n\n\n PluggableMap.prototype.forEachFeatureAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_) {\n return;\n }\n\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.forEachFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, callback, null, layerFilter, null);\n };\n /**\n * Get all features that intersect a pixel on the viewport.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {Array<import("./Feature.js").FeatureLike>} The detected features or\n * an empty array if none were found.\n * @api\n */\n\n\n PluggableMap.prototype.getFeaturesAtPixel = function (pixel, opt_options) {\n var features = [];\n this.forEachFeatureAtPixel(pixel, function (feature) {\n features.push(feature);\n }, opt_options);\n return features;\n };\n /**\n * Detect layers that have a color value at a pixel on the viewport, and\n * execute a callback with each matching layer. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n *\n * Note: this may give false positives unless the map layers have had different `className`\n * properties assigned to them.\n *\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {function(this: S, import("./layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback\n * Layer callback. This callback will receive two arguments: first is the\n * {@link module:ol/layer/Layer layer}, second argument is an array representing\n * [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types\n * that do not currently support this argument. To stop detection, callback\n * functions can return a truthy value.\n * @param {AtPixelOptions=} opt_options Configuration options.\n * @return {T|undefined} Callback result, i.e. the return value of last\n * callback execution, or the first truthy callback return value.\n * @template S,T\n * @api\n */\n\n\n PluggableMap.prototype.forEachLayerAtPixel = function (pixel, callback, opt_options) {\n if (!this.frameState_) {\n return;\n }\n\n var options = opt_options || {};\n var hitTolerance = options.hitTolerance !== undefined ? options.hitTolerance : 0;\n var layerFilter = options.layerFilter || TRUE;\n return this.renderer_.forEachLayerAtPixel(pixel, this.frameState_, hitTolerance, callback, layerFilter);\n };\n /**\n * Detect if features intersect a pixel on the viewport. Layers included in the\n * detection can be configured through `opt_layerFilter`.\n * @param {import("./pixel.js").Pixel} pixel Pixel.\n * @param {AtPixelOptions=} opt_options Optional options.\n * @return {boolean} Is there a feature at the given pixel?\n * @api\n */\n\n\n PluggableMap.prototype.hasFeatureAtPixel = function (pixel, opt_options) {\n if (!this.frameState_) {\n return false;\n }\n\n var coordinate = this.getCoordinateFromPixelInternal(pixel);\n opt_options = opt_options !== undefined ? opt_options : {};\n var layerFilter = opt_options.layerFilter !== undefined ? opt_options.layerFilter : TRUE;\n var hitTolerance = opt_options.hitTolerance !== undefined ? opt_options.hitTolerance : 0;\n var checkWrapped = opt_options.checkWrapped !== false;\n return this.renderer_.hasFeatureAtCoordinate(coordinate, this.frameState_, hitTolerance, checkWrapped, layerFilter, null);\n };\n /**\n * Returns the coordinate in user projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n PluggableMap.prototype.getEventCoordinate = function (event) {\n return this.getCoordinateFromPixel(this.getEventPixel(event));\n };\n /**\n * Returns the coordinate in view projection for a browser event.\n * @param {MouseEvent} event Event.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n */\n\n\n PluggableMap.prototype.getEventCoordinateInternal = function (event) {\n return this.getCoordinateFromPixelInternal(this.getEventPixel(event));\n };\n /**\n * Returns the map pixel position for a browser event relative to the viewport.\n * @param {UIEvent} event Event.\n * @return {import("./pixel.js").Pixel} Pixel.\n * @api\n */\n\n\n PluggableMap.prototype.getEventPixel = function (event) {\n var viewportPosition = this.viewport_.getBoundingClientRect();\n var eventPosition = //FIXME Are we really calling this with a TouchEvent anywhere?\n \'changedTouches\' in event ?\n /** @type {TouchEvent} */\n event.changedTouches[0] :\n /** @type {MouseEvent} */\n event;\n return [eventPosition.clientX - viewportPosition.left, eventPosition.clientY - viewportPosition.top];\n };\n /**\n * Get the target in which this map is rendered.\n * Note that this returns what is entered as an option or in setTarget:\n * if that was an element, it returns an element; if a string, it returns that.\n * @return {HTMLElement|string|undefined} The Element or id of the Element that the\n * map is rendered in.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getTarget = function () {\n return (\n /** @type {HTMLElement|string|undefined} */\n this.get(MapProperty.TARGET)\n );\n };\n /**\n * Get the DOM element into which this map is rendered. In contrast to\n * `getTarget` this method always return an `Element`, or `null` if the\n * map has no target.\n * @return {HTMLElement} The element that the map is rendered in.\n * @api\n */\n\n\n PluggableMap.prototype.getTargetElement = function () {\n var target = this.getTarget();\n\n if (target !== undefined) {\n return typeof target === \'string\' ? document.getElementById(target) : target;\n } else {\n return null;\n }\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * user projection.\n * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.\n * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.\n * @api\n */\n\n\n PluggableMap.prototype.getCoordinateFromPixel = function (pixel) {\n return toUserCoordinate(this.getCoordinateFromPixelInternal(pixel), this.getView().getProjection());\n };\n /**\n * Get the coordinate for a given pixel. This returns a coordinate in the\n * map view projection.\n * @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.\n * @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.\n */\n\n\n PluggableMap.prototype.getCoordinateFromPixelInternal = function (pixel) {\n var frameState = this.frameState_;\n\n if (!frameState) {\n return null;\n } else {\n return apply(frameState.pixelToCoordinateTransform, pixel.slice());\n }\n };\n /**\n * Get the map controls. Modifying this collection changes the controls\n * associated with the map.\n * @return {Collection<import("./control/Control.js").default>} Controls.\n * @api\n */\n\n\n PluggableMap.prototype.getControls = function () {\n return this.controls;\n };\n /**\n * Get the map overlays. Modifying this collection changes the overlays\n * associated with the map.\n * @return {Collection<import("./Overlay.js").default>} Overlays.\n * @api\n */\n\n\n PluggableMap.prototype.getOverlays = function () {\n return this.overlays_;\n };\n /**\n * Get an overlay by its identifier (the value returned by overlay.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `map.getOverlayById(2)` will return an overlay with id `\'2\'` or `2`.\n * @param {string|number} id Overlay identifier.\n * @return {import("./Overlay.js").default} Overlay.\n * @api\n */\n\n\n PluggableMap.prototype.getOverlayById = function (id) {\n var overlay = this.overlayIdIndex_[id.toString()];\n return overlay !== undefined ? overlay : null;\n };\n /**\n * Get the map interactions. Modifying this collection changes the interactions\n * associated with the map.\n *\n * Interactions are used for e.g. pan, zoom and rotate.\n * @return {Collection<import("./interaction/Interaction.js").default>} Interactions.\n * @api\n */\n\n\n PluggableMap.prototype.getInteractions = function () {\n return this.interactions;\n };\n /**\n * Get the layergroup associated with this map.\n * @return {LayerGroup} A layer group containing the layers in this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getLayerGroup = function () {\n return (\n /** @type {LayerGroup} */\n this.get(MapProperty.LAYERGROUP)\n );\n };\n /**\n * Get the collection of layers associated with this map.\n * @return {!Collection<import("./layer/Base.js").default>} Layers.\n * @api\n */\n\n\n PluggableMap.prototype.getLayers = function () {\n var layers = this.getLayerGroup().getLayers();\n return layers;\n };\n /**\n * @return {boolean} Layers have sources that are still loading.\n */\n\n\n PluggableMap.prototype.getLoading = function () {\n var layerStatesArray = this.getLayerGroup().getLayerStatesArray();\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layer = layerStatesArray[i].layer;\n var source =\n /** @type {import("./layer/Layer.js").default} */\n layer.getSource();\n\n if (source && source.loading) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the user\n * projection and returns the corresponding pixel.\n * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.\n * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.\n * @api\n */\n\n\n PluggableMap.prototype.getPixelFromCoordinate = function (coordinate) {\n var viewCoordinate = fromUserCoordinate(coordinate, this.getView().getProjection());\n return this.getPixelFromCoordinateInternal(viewCoordinate);\n };\n /**\n * Get the pixel for a coordinate. This takes a coordinate in the map view\n * projection and returns the corresponding pixel.\n * @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.\n * @return {import("./pixel.js").Pixel} A pixel position in the map viewport.\n */\n\n\n PluggableMap.prototype.getPixelFromCoordinateInternal = function (coordinate) {\n var frameState = this.frameState_;\n\n if (!frameState) {\n return null;\n } else {\n return apply(frameState.coordinateToPixelTransform, coordinate.slice(0, 2));\n }\n };\n /**\n * Get the map renderer.\n * @return {import("./renderer/Map.js").default} Renderer\n */\n\n\n PluggableMap.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Get the size of this map.\n * @return {import("./size.js").Size|undefined} The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getSize = function () {\n return (\n /** @type {import("./size.js").Size|undefined} */\n this.get(MapProperty.SIZE)\n );\n };\n /**\n * Get the view associated with this map. A view manages properties such as\n * center and resolution.\n * @return {View} The view that controls this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.getView = function () {\n return (\n /** @type {View} */\n this.get(MapProperty.VIEW)\n );\n };\n /**\n * Get the element that serves as the map viewport.\n * @return {HTMLElement} Viewport.\n * @api\n */\n\n\n PluggableMap.prototype.getViewport = function () {\n return this.viewport_;\n };\n /**\n * Get the element that serves as the container for overlays. Elements added to\n * this container will let mousedown and touchstart events through to the map,\n * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}\n * events.\n * @return {!HTMLElement} The map\'s overlay container.\n */\n\n\n PluggableMap.prototype.getOverlayContainer = function () {\n return this.overlayContainer_;\n };\n /**\n * Get the element that serves as a container for overlays that don\'t allow\n * event propagation. Elements added to this container won\'t let mousedown and\n * touchstart events through to the map, so clicks and gestures on an overlay\n * don\'t trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.\n * @return {!HTMLElement} The map\'s overlay container that stops events.\n */\n\n\n PluggableMap.prototype.getOverlayContainerStopEvent = function () {\n return this.overlayContainerStopEvent_;\n };\n /**\n * @return {!Document} The document where the map is displayed.\n */\n\n\n PluggableMap.prototype.getOwnerDocument = function () {\n return this.getTargetElement() ? this.getTargetElement().ownerDocument : document;\n };\n /**\n * @param {import("./Tile.js").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import("./coordinate.js").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\n\n\n PluggableMap.prototype.getTilePriority = function (tile, tileSourceKey, tileCenter, tileResolution) {\n return getTilePriority(this.frameState_, tile, tileSourceKey, tileCenter, tileResolution);\n };\n /**\n * @param {UIEvent} browserEvent Browser event.\n * @param {string=} opt_type Type.\n */\n\n\n PluggableMap.prototype.handleBrowserEvent = function (browserEvent, opt_type) {\n var type = opt_type || browserEvent.type;\n var mapBrowserEvent = new ol_MapBrowserEvent(type, this, browserEvent);\n this.handleMapBrowserEvent(mapBrowserEvent);\n };\n /**\n * @param {MapBrowserEvent} mapBrowserEvent The event to handle.\n */\n\n\n PluggableMap.prototype.handleMapBrowserEvent = function (mapBrowserEvent) {\n if (!this.frameState_) {\n // With no view defined, we cannot translate pixels into geographical\n // coordinates so interactions cannot be used.\n return;\n }\n\n var originalEvent =\n /** @type {PointerEvent} */\n mapBrowserEvent.originalEvent;\n var eventType = originalEvent.type;\n\n if (eventType === pointer_EventType.POINTERDOWN || eventType === EventType.WHEEL || eventType === EventType.KEYDOWN) {\n var doc = this.getOwnerDocument();\n var rootNode = this.viewport_.getRootNode ? this.viewport_.getRootNode() : doc;\n var target = \'host\' in rootNode // ShadowRoot\n ?\n /** @type {ShadowRoot} */\n rootNode.elementFromPoint(originalEvent.clientX, originalEvent.clientY) :\n /** @type {Node} */\n originalEvent.target;\n\n if ( // Abort if the target is a child of the container for elements whose events are not meant\n // to be handled by map interactions.\n this.overlayContainerStopEvent_.contains(target) || // Abort if the event target is a child of the container that is no longer in the page.\n // It\'s possible for the target to no longer be in the page if it has been removed in an\n // event listener, this might happen in a Control that recreates it\'s content based on\n // user interaction either manually or via a render in something like https://reactjs.org/\n !(rootNode === doc ? doc.documentElement : rootNode).contains(target)) {\n return;\n }\n }\n\n mapBrowserEvent.frameState = this.frameState_;\n\n if (this.dispatchEvent(mapBrowserEvent) !== false) {\n var interactionsArray = this.getInteractions().getArray().slice();\n\n for (var i = interactionsArray.length - 1; i >= 0; i--) {\n var interaction = interactionsArray[i];\n\n if (interaction.getMap() !== this || !interaction.getActive() || !this.getTargetElement()) {\n continue;\n }\n\n var cont = interaction.handleEvent(mapBrowserEvent);\n\n if (!cont || mapBrowserEvent.propagationStopped) {\n break;\n }\n }\n }\n };\n /**\n * @protected\n */\n\n\n PluggableMap.prototype.handlePostRender = function () {\n var frameState = this.frameState_; // Manage the tile queue\n // Image loads are expensive and a limited resource, so try to use them\n // efficiently:\n // * When the view is static we allow a large number of parallel tile loads\n // to complete the frame as quickly as possible.\n // * When animating or interacting, image loads can cause janks, so we reduce\n // the maximum number of loads per frame and limit the number of parallel\n // tile loads to remain reactive to view changes and to reduce the chance of\n // loading tiles that will quickly disappear from view.\n\n var tileQueue = this.tileQueue_;\n\n if (!tileQueue.isEmpty()) {\n var maxTotalLoading = this.maxTilesLoading_;\n var maxNewLoads = maxTotalLoading;\n\n if (frameState) {\n var hints = frameState.viewHints;\n\n if (hints[ViewHint.ANIMATING] || hints[ViewHint.INTERACTING]) {\n var lowOnFrameBudget = !IMAGE_DECODE && Date.now() - frameState.time > 8;\n maxTotalLoading = lowOnFrameBudget ? 0 : 8;\n maxNewLoads = lowOnFrameBudget ? 0 : 2;\n }\n }\n\n if (tileQueue.getTilesLoading() < maxTotalLoading) {\n tileQueue.reprioritize(); // FIXME only call if view has changed\n\n tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);\n }\n }\n\n if (frameState && this.hasListener(render_EventType.RENDERCOMPLETE) && !frameState.animate && !this.tileQueue_.getTilesLoading() && !this.getLoading()) {\n this.renderer_.dispatchRenderEvent(render_EventType.RENDERCOMPLETE, frameState);\n }\n\n var postRenderFunctions = this.postRenderFunctions_;\n\n for (var i = 0, ii = postRenderFunctions.length; i < ii; ++i) {\n postRenderFunctions[i](this, frameState);\n }\n\n postRenderFunctions.length = 0;\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleSizeChanged_ = function () {\n if (this.getView() && !this.getView().getAnimating()) {\n this.getView().resolveConstraints(0);\n }\n\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleTargetChanged_ = function () {\n // target may be undefined, null, a string or an Element.\n // If it\'s a string we convert it to an Element before proceeding.\n // If it\'s not now an Element we remove the viewport from the DOM.\n // If it\'s an Element we append the viewport element to it.\n var targetElement;\n\n if (this.getTarget()) {\n targetElement = this.getTargetElement();\n }\n\n if (this.mapBrowserEventHandler_) {\n for (var i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) {\n unlistenByKey(this.keyHandlerKeys_[i]);\n }\n\n this.keyHandlerKeys_ = null;\n this.viewport_.removeEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_);\n this.viewport_.removeEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_);\n\n if (this.handleResize_ !== undefined) {\n removeEventListener(EventType.RESIZE, this.handleResize_, false);\n this.handleResize_ = undefined;\n }\n\n this.mapBrowserEventHandler_.dispose();\n this.mapBrowserEventHandler_ = null;\n removeNode(this.viewport_);\n }\n\n if (!targetElement) {\n if (this.renderer_) {\n clearTimeout(this.postRenderTimeoutHandle_);\n this.postRenderTimeoutHandle_ = undefined;\n this.postRenderFunctions_.length = 0;\n this.renderer_.dispose();\n this.renderer_ = null;\n }\n\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n this.animationDelayKey_ = undefined;\n }\n } else {\n targetElement.appendChild(this.viewport_);\n\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n\n this.mapBrowserEventHandler_ = new ol_MapBrowserEventHandler(this, this.moveTolerance_);\n\n for (var key in ol_MapBrowserEventType) {\n this.mapBrowserEventHandler_.addEventListener(ol_MapBrowserEventType[key], this.handleMapBrowserEvent.bind(this));\n }\n\n this.viewport_.addEventListener(EventType.CONTEXTMENU, this.boundHandleBrowserEvent_, false);\n this.viewport_.addEventListener(EventType.WHEEL, this.boundHandleBrowserEvent_, PASSIVE_EVENT_LISTENERS ? {\n passive: false\n } : false);\n var keyboardEventTarget = !this.keyboardEventTarget_ ? targetElement : this.keyboardEventTarget_;\n this.keyHandlerKeys_ = [listen(keyboardEventTarget, EventType.KEYDOWN, this.handleBrowserEvent, this), listen(keyboardEventTarget, EventType.KEYPRESS, this.handleBrowserEvent, this)];\n\n if (!this.handleResize_) {\n this.handleResize_ = this.updateSize.bind(this);\n window.addEventListener(EventType.RESIZE, this.handleResize_, false);\n }\n }\n\n this.updateSize(); // updateSize calls setSize, so no need to call this.render\n // ourselves here.\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleTileChange_ = function () {\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleViewPropertyChanged_ = function () {\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleViewChanged_ = function () {\n if (this.viewPropertyListenerKey_) {\n unlistenByKey(this.viewPropertyListenerKey_);\n this.viewPropertyListenerKey_ = null;\n }\n\n if (this.viewChangeListenerKey_) {\n unlistenByKey(this.viewChangeListenerKey_);\n this.viewChangeListenerKey_ = null;\n }\n\n var view = this.getView();\n\n if (view) {\n this.updateViewportSize_();\n this.viewPropertyListenerKey_ = listen(view, ObjectEventType.PROPERTYCHANGE, this.handleViewPropertyChanged_, this);\n this.viewChangeListenerKey_ = listen(view, EventType.CHANGE, this.handleViewPropertyChanged_, this);\n view.resolveConstraints(0);\n }\n\n this.render();\n };\n /**\n * @private\n */\n\n\n PluggableMap.prototype.handleLayerGroupChanged_ = function () {\n if (this.layerGroupPropertyListenerKeys_) {\n this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);\n this.layerGroupPropertyListenerKeys_ = null;\n }\n\n var layerGroup = this.getLayerGroup();\n\n if (layerGroup) {\n this.layerGroupPropertyListenerKeys_ = [listen(layerGroup, ObjectEventType.PROPERTYCHANGE, this.render, this), listen(layerGroup, EventType.CHANGE, this.render, this)];\n }\n\n this.render();\n };\n /**\n * @return {boolean} Is rendered.\n */\n\n\n PluggableMap.prototype.isRendered = function () {\n return !!this.frameState_;\n };\n /**\n * Requests an immediate render in a synchronous manner.\n * @api\n */\n\n\n PluggableMap.prototype.renderSync = function () {\n if (this.animationDelayKey_) {\n cancelAnimationFrame(this.animationDelayKey_);\n }\n\n this.animationDelay_();\n };\n /**\n * Redraws all text after new fonts have loaded\n */\n\n\n PluggableMap.prototype.redrawText = function () {\n var layerStates = this.getLayerGroup().getLayerStatesArray();\n\n for (var i = 0, ii = layerStates.length; i < ii; ++i) {\n var layer = layerStates[i].layer;\n\n if (layer.hasRenderer()) {\n layer.getRenderer().handleFontsChanged();\n }\n }\n };\n /**\n * Request a map rendering (at the next animation frame).\n * @api\n */\n\n\n PluggableMap.prototype.render = function () {\n if (this.renderer_ && this.animationDelayKey_ === undefined) {\n this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);\n }\n };\n /**\n * Remove the given control from the map.\n * @param {import("./control/Control.js").default} control Control.\n * @return {import("./control/Control.js").default|undefined} The removed control (or undefined\n * if the control was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeControl = function (control) {\n return this.getControls().remove(control);\n };\n /**\n * Remove the given interaction from the map.\n * @param {import("./interaction/Interaction.js").default} interaction Interaction to remove.\n * @return {import("./interaction/Interaction.js").default|undefined} The removed interaction (or\n * undefined if the interaction was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeInteraction = function (interaction) {\n return this.getInteractions().remove(interaction);\n };\n /**\n * Removes the given layer from the map.\n * @param {import("./layer/Base.js").default} layer Layer.\n * @return {import("./layer/Base.js").default|undefined} The removed layer (or undefined if the\n * layer was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeLayer = function (layer) {\n var layers = this.getLayerGroup().getLayers();\n return layers.remove(layer);\n };\n /**\n * Remove the given overlay from the map.\n * @param {import("./Overlay.js").default} overlay Overlay.\n * @return {import("./Overlay.js").default|undefined} The removed overlay (or undefined\n * if the overlay was not found).\n * @api\n */\n\n\n PluggableMap.prototype.removeOverlay = function (overlay) {\n return this.getOverlays().remove(overlay);\n };\n /**\n * @param {number} time Time.\n * @private\n */\n\n\n PluggableMap.prototype.renderFrame_ = function (time) {\n var _this = this;\n\n var size = this.getSize();\n var view = this.getView();\n var previousFrameState = this.frameState_;\n /** @type {?FrameState} */\n\n var frameState = null;\n\n if (size !== undefined && hasArea(size) && view && view.isDef()) {\n var viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);\n var viewState = view.getState();\n frameState = {\n animate: false,\n coordinateToPixelTransform: this.coordinateToPixelTransform_,\n declutterTree: null,\n extent: getForViewAndSize(viewState.center, viewState.resolution, viewState.rotation, size),\n index: this.frameIndex_++,\n layerIndex: 0,\n layerStatesArray: this.getLayerGroup().getLayerStatesArray(),\n pixelRatio: this.pixelRatio_,\n pixelToCoordinateTransform: this.pixelToCoordinateTransform_,\n postRenderFunctions: [],\n size: size,\n tileQueue: this.tileQueue_,\n time: time,\n usedTiles: {},\n viewState: viewState,\n viewHints: viewHints,\n wantedTiles: {}\n };\n }\n\n this.frameState_ = frameState;\n this.renderer_.renderFrame(frameState);\n\n if (frameState) {\n if (frameState.animate) {\n this.render();\n }\n\n Array.prototype.push.apply(this.postRenderFunctions_, frameState.postRenderFunctions);\n\n if (previousFrameState) {\n var moveStart = !this.previousExtent_ || !extent_isEmpty(this.previousExtent_) && !extent_equals(frameState.extent, this.previousExtent_);\n\n if (moveStart) {\n this.dispatchEvent(new ol_MapEvent(MapEventType.MOVESTART, this, previousFrameState));\n this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);\n }\n }\n\n var idle = this.previousExtent_ && !frameState.viewHints[ViewHint.ANIMATING] && !frameState.viewHints[ViewHint.INTERACTING] && !extent_equals(frameState.extent, this.previousExtent_);\n\n if (idle) {\n this.dispatchEvent(new ol_MapEvent(MapEventType.MOVEEND, this, frameState));\n clone(frameState.extent, this.previousExtent_);\n }\n }\n\n this.dispatchEvent(new ol_MapEvent(MapEventType.POSTRENDER, this, frameState));\n\n if (!this.postRenderTimeoutHandle_) {\n this.postRenderTimeoutHandle_ = setTimeout(function () {\n _this.postRenderTimeoutHandle_ = undefined;\n\n _this.handlePostRender();\n }, 0);\n }\n };\n /**\n * Sets the layergroup of this map.\n * @param {LayerGroup} layerGroup A layer group containing the layers in this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setLayerGroup = function (layerGroup) {\n this.set(MapProperty.LAYERGROUP, layerGroup);\n };\n /**\n * Set the size of this map.\n * @param {import("./size.js").Size|undefined} size The size in pixels of the map in the DOM.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setSize = function (size) {\n this.set(MapProperty.SIZE, size);\n };\n /**\n * Set the target element to render this map into.\n * @param {HTMLElement|string|undefined} target The Element or id of the Element\n * that the map is rendered in.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setTarget = function (target) {\n this.set(MapProperty.TARGET, target);\n };\n /**\n * Set the view for this map.\n * @param {View} view The view that controls this map.\n * @observable\n * @api\n */\n\n\n PluggableMap.prototype.setView = function (view) {\n this.set(MapProperty.VIEW, view);\n };\n /**\n * Force a recalculation of the map viewport size. This should be called when\n * third-party code changes the size of the map viewport.\n * @api\n */\n\n\n PluggableMap.prototype.updateSize = function () {\n var targetElement = this.getTargetElement();\n\n if (!targetElement) {\n this.setSize(undefined);\n } else {\n var computedStyle = getComputedStyle(targetElement);\n this.setSize([targetElement.offsetWidth - parseFloat(computedStyle[\'borderLeftWidth\']) - parseFloat(computedStyle[\'paddingLeft\']) - parseFloat(computedStyle[\'paddingRight\']) - parseFloat(computedStyle[\'borderRightWidth\']), targetElement.offsetHeight - parseFloat(computedStyle[\'borderTopWidth\']) - parseFloat(computedStyle[\'paddingTop\']) - parseFloat(computedStyle[\'paddingBottom\']) - parseFloat(computedStyle[\'borderBottomWidth\'])]);\n }\n\n this.updateViewportSize_();\n };\n /**\n * Recomputes the viewport size and save it on the view object (if any)\n * @private\n */\n\n\n PluggableMap.prototype.updateViewportSize_ = function () {\n var view = this.getView();\n\n if (view) {\n var size = undefined;\n var computedStyle = getComputedStyle(this.viewport_);\n\n if (computedStyle.width && computedStyle.height) {\n size = [parseInt(computedStyle.width, 10), parseInt(computedStyle.height, 10)];\n }\n\n view.setViewportSize(size);\n }\n };\n\n return PluggableMap;\n}(ol_Object);\n/**\n * @param {MapOptions} options Map options.\n * @return {MapOptionsInternal} Internal map options.\n */\n\n\nfunction createOptionsInternal(options) {\n /**\n * @type {HTMLElement|Document}\n */\n var keyboardEventTarget = null;\n\n if (options.keyboardEventTarget !== undefined) {\n keyboardEventTarget = typeof options.keyboardEventTarget === \'string\' ? document.getElementById(options.keyboardEventTarget) : options.keyboardEventTarget;\n }\n /**\n * @type {Object<string, *>}\n */\n\n\n var values = {};\n var layerGroup = options.layers && typeof\n /** @type {?} */\n options.layers.getLayers === \'function\' ?\n /** @type {LayerGroup} */\n options.layers : new Group({\n layers:\n /** @type {Collection} */\n options.layers\n });\n values[MapProperty.LAYERGROUP] = layerGroup;\n values[MapProperty.TARGET] = options.target;\n values[MapProperty.VIEW] = options.view !== undefined ? options.view : new ol_View();\n var controls;\n\n if (options.controls !== undefined) {\n if (Array.isArray(options.controls)) {\n controls = new ol_Collection(options.controls.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.controls.getArray === \'function\', 47); // Expected `controls` to be an array or an `import("./Collection.js").Collection`\n\n controls =\n /** @type {Collection} */\n options.controls;\n }\n }\n\n var interactions;\n\n if (options.interactions !== undefined) {\n if (Array.isArray(options.interactions)) {\n interactions = new ol_Collection(options.interactions.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.interactions.getArray === \'function\', 48); // Expected `interactions` to be an array or an `import("./Collection.js").Collection`\n\n interactions =\n /** @type {Collection} */\n options.interactions;\n }\n }\n\n var overlays;\n\n if (options.overlays !== undefined) {\n if (Array.isArray(options.overlays)) {\n overlays = new ol_Collection(options.overlays.slice());\n } else {\n asserts_assert(typeof\n /** @type {?} */\n options.overlays.getArray === \'function\', 49); // Expected `overlays` to be an array or an `import("./Collection.js").Collection`\n\n overlays = options.overlays;\n }\n } else {\n overlays = new ol_Collection();\n }\n\n return {\n controls: controls,\n interactions: interactions,\n keyboardEventTarget: keyboardEventTarget,\n overlays: overlays,\n values: values\n };\n}\n\n/* harmony default export */ var ol_PluggableMap = (PluggableMap);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Control.js\nvar Control_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Control\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {HTMLElement} [element] The element is the control\'s\n * container element. This only needs to be specified if you\'re developing\n * a custom control.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want\n * the control to be rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A control is a visible widget with a DOM element in a fixed position on the\n * screen. They can involve user input (buttons), or be informational only;\n * the position is determined using CSS. By default these are placed in the\n * container with CSS class name `ol-overlaycontainer-stopevent`, but can use\n * any outside DOM element.\n *\n * This is the base class for controls. You can use it for simple custom\n * controls by creating the element with listeners, creating an instance:\n * ```js\n * var myControl = new Control({element: myElement});\n * ```\n * and then adding this to the map.\n *\n * The main advantage of having this as a control rather than a simple separate\n * DOM element is that preventing propagation is handled for you. Controls\n * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.\n *\n * You can also extend this base for your own control class. See\n * examples/custom-controls for an example of how to do this.\n *\n * @api\n */\n\nvar Control =\n/** @class */\nfunction (_super) {\n Control_extends(Control, _super);\n /**\n * @param {Options} options Control options.\n */\n\n\n function Control(options) {\n var _this = _super.call(this) || this;\n\n var element = options.element;\n\n if (element && !options.target && !element.style.pointerEvents) {\n element.style.pointerEvents = \'auto\';\n }\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n\n _this.element = element ? element : null;\n /**\n * @private\n * @type {HTMLElement}\n */\n\n _this.target_ = null;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n _this.map_ = null;\n /**\n * @protected\n * @type {!Array<import("../events.js").EventsKey>}\n */\n\n _this.listenerKeys = [];\n\n if (options.render) {\n _this.render = options.render;\n }\n\n if (options.target) {\n _this.setTarget(options.target);\n }\n\n return _this;\n }\n /**\n * Clean up.\n */\n\n\n Control.prototype.disposeInternal = function () {\n removeNode(this.element);\n\n _super.prototype.disposeInternal.call(this);\n };\n /**\n * Get the map associated with this control.\n * @return {import("../PluggableMap.js").default} Map.\n * @api\n */\n\n\n Control.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Remove the control from its current map and attach it to the new map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import("../PluggableMap.js").default} map Map.\n * @api\n */\n\n\n Control.prototype.setMap = function (map) {\n if (this.map_) {\n removeNode(this.element);\n }\n\n for (var i = 0, ii = this.listenerKeys.length; i < ii; ++i) {\n unlistenByKey(this.listenerKeys[i]);\n }\n\n this.listenerKeys.length = 0;\n this.map_ = map;\n\n if (this.map_) {\n var target = this.target_ ? this.target_ : map.getOverlayContainerStopEvent();\n target.appendChild(this.element);\n\n if (this.render !== VOID) {\n this.listenerKeys.push(listen(map, MapEventType.POSTRENDER, this.render, this));\n }\n\n map.render();\n }\n };\n /**\n * Renders the control.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @api\n */\n\n\n Control.prototype.render = function (mapEvent) {};\n /**\n * This function is used to set a target element for the control. It has no\n * effect if it is called after the control has been added to the map (i.e.\n * after `setMap` is called on the control). If no `target` is set in the\n * options passed to the control constructor and if `setTarget` is not called\n * then the control is added to the map\'s overlay container.\n * @param {HTMLElement|string} target Target.\n * @api\n */\n\n\n Control.prototype.setTarget = function (target) {\n this.target_ = typeof target === \'string\' ? document.getElementById(target) : target;\n };\n\n return Control;\n}(ol_Object);\n\n/* harmony default export */ var control_Control = (Control);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Attribution.js\nvar Attribution_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Attribution\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-attribution\'] CSS class name.\n * @property {HTMLElement|string} [target] Specify a target if you\n * want the control to be rendered outside of the map\'s\n * viewport.\n * @property {boolean} [collapsible] Specify if attributions can\n * be collapsed. If not specified, sources control this behavior with their\n * `attributionsCollapsible` setting.\n * @property {boolean} [collapsed=true] Specify if attributions should\n * be collapsed at startup.\n * @property {string} [tipLabel=\'Attributions\'] Text label to use for the button tip.\n * @property {string} [label=\'i\'] Text label to use for the\n * collapsed attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [expandClassName=className + \'-expand\'] CSS class name for the\n * collapsed attributions button.\n * @property {string|HTMLElement} [collapseLabel=\'»\'] Text label to use\n * for the expanded attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [collapseClassName=className + \'-collapse\'] CSS class name for the\n * expanded attributions button.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n */\n\n/**\n * @classdesc\n * Control to show all the attributions associated with the layer sources\n * in the map. This control is one of the default controls included in maps.\n * By default it will show in the bottom right portion of the map, but this can\n * be changed by using a css selector for `.ol-attribution`.\n *\n * @api\n */\n\nvar Attribution =\n/** @class */\nfunction (_super) {\n Attribution_extends(Attribution, _super);\n /**\n * @param {Options=} opt_options Attribution options.\n */\n\n\n function Attribution(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n render: options.render,\n target: options.target\n }) || this;\n /**\n * @private\n * @type {HTMLElement}\n */\n\n _this.ulElement_ = document.createElement(\'ul\');\n /**\n * @private\n * @type {boolean}\n */\n\n _this.collapsed_ = options.collapsed !== undefined ? options.collapsed : true;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.userCollapsed_ = _this.collapsed_;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overrideCollapsible_ = options.collapsible !== undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.collapsible_ = options.collapsible !== undefined ? options.collapsible : true;\n\n if (!_this.collapsible_) {\n _this.collapsed_ = false;\n }\n\n var className = options.className !== undefined ? options.className : \'ol-attribution\';\n var tipLabel = options.tipLabel !== undefined ? options.tipLabel : \'Attributions\';\n var expandClassName = options.expandClassName !== undefined ? options.expandClassName : className + \'-expand\';\n var collapseLabel = options.collapseLabel !== undefined ? options.collapseLabel : "\\xBB";\n var collapseClassName = options.collapseClassName !== undefined ? options.collapseClassName : className + \'-collpase\';\n\n if (typeof collapseLabel === \'string\') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.collapseLabel_ = document.createElement(\'span\');\n _this.collapseLabel_.textContent = collapseLabel;\n _this.collapseLabel_.className = collapseClassName;\n } else {\n _this.collapseLabel_ = collapseLabel;\n }\n\n var label = options.label !== undefined ? options.label : \'i\';\n\n if (typeof label === \'string\') {\n /**\n * @private\n * @type {HTMLElement}\n */\n _this.label_ = document.createElement(\'span\');\n _this.label_.textContent = label;\n _this.label_.className = expandClassName;\n } else {\n _this.label_ = label;\n }\n\n var activeLabel = _this.collapsible_ && !_this.collapsed_ ? _this.collapseLabel_ : _this.label_;\n var button = document.createElement(\'button\');\n button.setAttribute(\'type\', \'button\');\n button.title = tipLabel;\n button.appendChild(activeLabel);\n button.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL + (_this.collapsed_ && _this.collapsible_ ? \' \' + CLASS_COLLAPSED : \'\') + (_this.collapsible_ ? \'\' : \' ol-uncollapsible\');\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(_this.ulElement_);\n element.appendChild(button);\n /**\n * A list of currently rendered resolutions.\n * @type {Array<string>}\n * @private\n */\n\n _this.renderedAttributions_ = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderedVisible_ = true;\n return _this;\n }\n /**\n * Collect a list of visible attributions and set the collapsible state.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @return {Array<string>} Attributions.\n * @private\n */\n\n\n Attribution.prototype.collectSourceAttributions_ = function (frameState) {\n /**\n * Used to determine if an attribution already exists.\n * @type {!Object<string, boolean>}\n */\n var lookup = {};\n /**\n * A list of visible attributions.\n * @type {Array<string>}\n */\n\n var visibleAttributions = [];\n var collapsible = true;\n var layerStatesArray = frameState.layerStatesArray;\n\n for (var i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n var layerState = layerStatesArray[i];\n\n if (!inView(layerState, frameState.viewState)) {\n continue;\n }\n\n var source =\n /** @type {import("../layer/Layer.js").default} */\n layerState.layer.getSource();\n\n if (!source) {\n continue;\n }\n\n var attributionGetter = source.getAttributions();\n\n if (!attributionGetter) {\n continue;\n }\n\n var attributions = attributionGetter(frameState);\n\n if (!attributions) {\n continue;\n }\n\n collapsible = collapsible && source.getAttributionsCollapsible() !== false;\n\n if (Array.isArray(attributions)) {\n for (var j = 0, jj = attributions.length; j < jj; ++j) {\n if (!(attributions[j] in lookup)) {\n visibleAttributions.push(attributions[j]);\n lookup[attributions[j]] = true;\n }\n }\n } else {\n if (!(attributions in lookup)) {\n visibleAttributions.push(attributions);\n lookup[attributions] = true;\n }\n }\n }\n\n if (!this.overrideCollapsible_) {\n this.setCollapsible(collapsible);\n }\n\n return visibleAttributions;\n };\n /**\n * @private\n * @param {?import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n Attribution.prototype.updateElement_ = function (frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element.style.display = \'none\';\n this.renderedVisible_ = false;\n }\n\n return;\n }\n\n var attributions = this.collectSourceAttributions_(frameState);\n var visible = attributions.length > 0;\n\n if (this.renderedVisible_ != visible) {\n this.element.style.display = visible ? \'\' : \'none\';\n this.renderedVisible_ = visible;\n }\n\n if (equals(attributions, this.renderedAttributions_)) {\n return;\n }\n\n removeChildren(this.ulElement_); // append the attributions\n\n for (var i = 0, ii = attributions.length; i < ii; ++i) {\n var element = document.createElement(\'li\');\n element.innerHTML = attributions[i];\n this.ulElement_.appendChild(element);\n }\n\n this.renderedAttributions_ = attributions;\n };\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Attribution.prototype.handleClick_ = function (event) {\n event.preventDefault();\n this.handleToggle_();\n this.userCollapsed_ = this.collapsed_;\n };\n /**\n * @private\n */\n\n\n Attribution.prototype.handleToggle_ = function () {\n this.element.classList.toggle(CLASS_COLLAPSED);\n\n if (this.collapsed_) {\n replaceNode(this.collapseLabel_, this.label_);\n } else {\n replaceNode(this.label_, this.collapseLabel_);\n }\n\n this.collapsed_ = !this.collapsed_;\n };\n /**\n * Return `true` if the attribution is collapsible, `false` otherwise.\n * @return {boolean} True if the widget is collapsible.\n * @api\n */\n\n\n Attribution.prototype.getCollapsible = function () {\n return this.collapsible_;\n };\n /**\n * Set whether the attribution should be collapsible.\n * @param {boolean} collapsible True if the widget is collapsible.\n * @api\n */\n\n\n Attribution.prototype.setCollapsible = function (collapsible) {\n if (this.collapsible_ === collapsible) {\n return;\n }\n\n this.collapsible_ = collapsible;\n this.element.classList.toggle(\'ol-uncollapsible\');\n\n if (this.userCollapsed_) {\n this.handleToggle_();\n }\n };\n /**\n * Collapse or expand the attribution according to the passed parameter. Will\n * not do anything if the attribution isn\'t collapsible or if the current\n * collapsed state is already the one requested.\n * @param {boolean} collapsed True if the widget is collapsed.\n * @api\n */\n\n\n Attribution.prototype.setCollapsed = function (collapsed) {\n this.userCollapsed_ = collapsed;\n\n if (!this.collapsible_ || this.collapsed_ === collapsed) {\n return;\n }\n\n this.handleToggle_();\n };\n /**\n * Return `true` when the attribution is currently collapsed or `false`\n * otherwise.\n * @return {boolean} True if the widget is collapsed.\n * @api\n */\n\n\n Attribution.prototype.getCollapsed = function () {\n return this.collapsed_;\n };\n /**\n * Update the attribution element.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @override\n */\n\n\n Attribution.prototype.render = function (mapEvent) {\n this.updateElement_(mapEvent.frameState);\n };\n\n return Attribution;\n}(control_Control);\n\n/* harmony default export */ var control_Attribution = (Attribution);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Rotate.js\nvar Rotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Rotate\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-rotate\'] CSS class name.\n * @property {string|HTMLElement} [label=\'⇧\'] Text label to use for the rotate button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel=\'Reset rotation\'] Text label to use for the rotate tip.\n * @property {string} [compassClassName=\'ol-compass\'] CSS class name for the compass.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {boolean} [autoHide=true] Hide the control when rotation is 0.\n * @property {function(import("../MapEvent.js").default):void} [render] Function called when the control should\n * be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {function():void} [resetNorth] Function called when the control is clicked.\n * This will override the default `resetNorth`.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A button control to reset rotation to 0.\n * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css\n * selector is added to the button when the rotation is 0.\n *\n * @api\n */\n\nvar Rotate =\n/** @class */\nfunction (_super) {\n Rotate_extends(Rotate, _super);\n /**\n * @param {Options=} opt_options Rotate options.\n */\n\n\n function Rotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n render: options.render,\n target: options.target\n }) || this;\n var className = options.className !== undefined ? options.className : \'ol-rotate\';\n var label = options.label !== undefined ? options.label : "\\u21E7";\n var compassClassName = options.compassClassName !== undefined ? options.compassClassName : \'ol-compass\';\n /**\n * @type {HTMLElement}\n * @private\n */\n\n _this.label_ = null;\n\n if (typeof label === \'string\') {\n _this.label_ = document.createElement(\'span\');\n _this.label_.className = compassClassName;\n _this.label_.textContent = label;\n } else {\n _this.label_ = label;\n\n _this.label_.classList.add(compassClassName);\n }\n\n var tipLabel = options.tipLabel ? options.tipLabel : \'Reset rotation\';\n var button = document.createElement(\'button\');\n button.className = className + \'-reset\';\n button.setAttribute(\'type\', \'button\');\n button.title = tipLabel;\n button.appendChild(_this.label_);\n button.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(button);\n _this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;\n /**\n * @type {number}\n * @private\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.rotation_ = undefined;\n\n if (_this.autoHide_) {\n _this.element.classList.add(CLASS_HIDDEN);\n }\n\n return _this;\n }\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Rotate.prototype.handleClick_ = function (event) {\n event.preventDefault();\n\n if (this.callResetNorth_ !== undefined) {\n this.callResetNorth_();\n } else {\n this.resetNorth_();\n }\n };\n /**\n * @private\n */\n\n\n Rotate.prototype.resetNorth_ = function () {\n var map = this.getMap();\n var view = map.getView();\n\n if (!view) {\n // the map does not have a view, so we can\'t act\n // upon it\n return;\n }\n\n var rotation = view.getRotation();\n\n if (rotation !== undefined) {\n if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {\n view.animate({\n rotation: 0,\n duration: this.duration_,\n easing: easeOut\n });\n } else {\n view.setRotation(0);\n }\n }\n };\n /**\n * Update the rotate control element.\n * @param {import("../MapEvent.js").default} mapEvent Map event.\n * @override\n */\n\n\n Rotate.prototype.render = function (mapEvent) {\n var frameState = mapEvent.frameState;\n\n if (!frameState) {\n return;\n }\n\n var rotation = frameState.viewState.rotation;\n\n if (rotation != this.rotation_) {\n var transform = \'rotate(\' + rotation + \'rad)\';\n\n if (this.autoHide_) {\n var contains = this.element.classList.contains(CLASS_HIDDEN);\n\n if (!contains && rotation === 0) {\n this.element.classList.add(CLASS_HIDDEN);\n } else if (contains && rotation !== 0) {\n this.element.classList.remove(CLASS_HIDDEN);\n }\n }\n\n this.label_.style.transform = transform;\n }\n\n this.rotation_ = rotation;\n };\n\n return Rotate;\n}(control_Control);\n\n/* harmony default export */ var control_Rotate = (Rotate);\n;// CONCATENATED MODULE: ./node_modules/ol/control/Zoom.js\nvar Zoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/control/Zoom\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {string} [className=\'ol-zoom\'] CSS class name.\n * @property {string} [zoomInClassName=className + \'-in\'] CSS class name for the zoom-in button.\n * @property {string} [zoomOutClassName=className + \'-out\'] CSS class name for the zoom-out button.\n * @property {string|HTMLElement} [zoomInLabel=\'+\'] Text label to use for the zoom-in\n * button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [zoomOutLabel=\'-\'] Text label to use for the zoom-out button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [zoomInTipLabel=\'Zoom in\'] Text label to use for the button tip.\n * @property {string} [zoomOutTipLabel=\'Zoom out\'] Text label to use for the button tip.\n * @property {number} [delta=1] The zoom delta applied on each click.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map\'s viewport.\n */\n\n/**\n * @classdesc\n * A control with 2 buttons, one for zoom in and one for zoom out.\n * This control is one of the default controls of a map. To style this control\n * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.\n *\n * @api\n */\n\nvar Zoom =\n/** @class */\nfunction (_super) {\n Zoom_extends(Zoom, _super);\n /**\n * @param {Options=} opt_options Zoom options.\n */\n\n\n function Zoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n element: document.createElement(\'div\'),\n target: options.target\n }) || this;\n var className = options.className !== undefined ? options.className : \'ol-zoom\';\n var delta = options.delta !== undefined ? options.delta : 1;\n var zoomInClassName = options.zoomInClassName !== undefined ? options.zoomInClassName : className + \'-in\';\n var zoomOutClassName = options.zoomOutClassName !== undefined ? options.zoomOutClassName : className + \'-out\';\n var zoomInLabel = options.zoomInLabel !== undefined ? options.zoomInLabel : \'+\';\n var zoomOutLabel = options.zoomOutLabel !== undefined ? options.zoomOutLabel : "\\u2212";\n var zoomInTipLabel = options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : \'Zoom in\';\n var zoomOutTipLabel = options.zoomOutTipLabel !== undefined ? options.zoomOutTipLabel : \'Zoom out\';\n var inElement = document.createElement(\'button\');\n inElement.className = zoomInClassName;\n inElement.setAttribute(\'type\', \'button\');\n inElement.title = zoomInTipLabel;\n inElement.appendChild(typeof zoomInLabel === \'string\' ? document.createTextNode(zoomInLabel) : zoomInLabel);\n inElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, delta), false);\n var outElement = document.createElement(\'button\');\n outElement.className = zoomOutClassName;\n outElement.setAttribute(\'type\', \'button\');\n outElement.title = zoomOutTipLabel;\n outElement.appendChild(typeof zoomOutLabel === \'string\' ? document.createTextNode(zoomOutLabel) : zoomOutLabel);\n outElement.addEventListener(EventType.CLICK, _this.handleClick_.bind(_this, -delta), false);\n var cssClasses = className + \' \' + CLASS_UNSELECTABLE + \' \' + CLASS_CONTROL;\n var element = _this.element;\n element.className = cssClasses;\n element.appendChild(inElement);\n element.appendChild(outElement);\n /**\n * @type {number}\n * @private\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * @param {number} delta Zoom delta.\n * @param {MouseEvent} event The event to handle\n * @private\n */\n\n\n Zoom.prototype.handleClick_ = function (delta, event) {\n event.preventDefault();\n this.zoomByDelta_(delta);\n };\n /**\n * @param {number} delta Zoom delta.\n * @private\n */\n\n\n Zoom.prototype.zoomByDelta_ = function (delta) {\n var map = this.getMap();\n var view = map.getView();\n\n if (!view) {\n // the map does not have a view, so we can\'t act\n // upon it\n return;\n }\n\n var currentZoom = view.getZoom();\n\n if (currentZoom !== undefined) {\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n\n if (this.duration_ > 0) {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.animate({\n zoom: newZoom,\n duration: this.duration_,\n easing: easeOut\n });\n } else {\n view.setZoom(newZoom);\n }\n }\n };\n\n return Zoom;\n}(control_Control);\n\n/* harmony default export */ var control_Zoom = (Zoom);\n;// CONCATENATED MODULE: ./node_modules/ol/control.js\n/**\n * @module ol/control\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [attribution=true] Include\n * {@link module:ol/control/Attribution~Attribution}.\n * @property {import("./control/Attribution.js").Options} [attributionOptions]\n * Options for {@link module:ol/control/Attribution~Attribution}.\n * @property {boolean} [rotate=true] Include\n * {@link module:ol/control/Rotate~Rotate}.\n * @property {import("./control/Rotate.js").Options} [rotateOptions] Options\n * for {@link module:ol/control/Rotate~Rotate}.\n * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.\n * @property {import("./control/Zoom.js").Options} [zoomOptions] Options for\n * {@link module:ol/control/Zoom~Zoom}.\n * @api\n */\n\n/**\n * Set of controls included in maps by default. Unless configured otherwise,\n * this returns a collection containing an instance of each of the following\n * controls:\n * * {@link module:ol/control/Zoom~Zoom}\n * * {@link module:ol/control/Rotate~Rotate}\n * * {@link module:ol/control/Attribution~Attribution}\n *\n * @param {DefaultsOptions=} opt_options\n * Defaults options.\n * @return {Collection<import("./control/Control.js").default>}\n * Controls.\n * @api\n */\n\nfunction defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var controls = new ol_Collection();\n var zoomControl = options.zoom !== undefined ? options.zoom : true;\n\n if (zoomControl) {\n controls.push(new control_Zoom(options.zoomOptions));\n }\n\n var rotateControl = options.rotate !== undefined ? options.rotate : true;\n\n if (rotateControl) {\n controls.push(new control_Rotate(options.rotateOptions));\n }\n\n var attributionControl = options.attribution !== undefined ? options.attribution : true;\n\n if (attributionControl) {\n controls.push(new control_Attribution(options.attributionOptions));\n }\n\n return controls;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Property.js\n/**\n * @module ol/interaction/Property\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var interaction_Property = ({\n ACTIVE: \'active\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Interaction.js\nvar Interaction_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/Interaction\n */\n\n\n\n\n\n/**\n * Object literal with config options for interactions.\n * @typedef {Object} InteractionOptions\n * @property {function(import("../MapBrowserEvent.js").default):boolean} handleEvent\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. If the function returns a falsy value, propagation of\n * the event to other interactions in the map\'s interactions chain will be\n * prevented (this includes functions with no explicit return). The interactions\n * are traversed in reverse order of the interactions collection of the map.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * User actions that change the state of the map. Some are similar to controls,\n * but are not associated with a DOM element.\n * For example, {@link module:ol/interaction/KeyboardZoom~KeyboardZoom} is\n * functionally the same as {@link module:ol/control/Zoom~Zoom}, but triggered\n * by a keyboard event not a button element event.\n * Although interactions do not have a DOM element, some of them do render\n * vectors and so are visible on the screen.\n * @api\n */\n\nvar Interaction =\n/** @class */\nfunction (_super) {\n Interaction_extends(Interaction, _super);\n /**\n * @param {InteractionOptions=} opt_options Options.\n */\n\n\n function Interaction(opt_options) {\n var _this = _super.call(this) || this;\n\n if (opt_options && opt_options.handleEvent) {\n _this.handleEvent = opt_options.handleEvent;\n }\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n\n _this.map_ = null;\n\n _this.setActive(true);\n\n return _this;\n }\n /**\n * Return whether the interaction is currently active.\n * @return {boolean} `true` if the interaction is active, `false` otherwise.\n * @observable\n * @api\n */\n\n\n Interaction.prototype.getActive = function () {\n return (\n /** @type {boolean} */\n this.get(interaction_Property.ACTIVE)\n );\n };\n /**\n * Get the map associated with this interaction.\n * @return {import("../PluggableMap.js").default} Map.\n * @api\n */\n\n\n Interaction.prototype.getMap = function () {\n return this.map_;\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event}.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n\n\n Interaction.prototype.handleEvent = function (mapBrowserEvent) {\n return true;\n };\n /**\n * Activate or deactivate the interaction.\n * @param {boolean} active Active.\n * @observable\n * @api\n */\n\n\n Interaction.prototype.setActive = function (active) {\n this.set(interaction_Property.ACTIVE, active);\n };\n /**\n * Remove the interaction from its current map and attach it to the new map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n Interaction.prototype.setMap = function (map) {\n this.map_ = map;\n };\n\n return Interaction;\n}(ol_Object);\n/**\n * @param {import("../View.js").default} view View.\n * @param {import("../coordinate.js").Coordinate} delta Delta.\n * @param {number=} opt_duration Duration.\n */\n\n\nfunction pan(view, delta, opt_duration) {\n var currentCenter = view.getCenterInternal();\n\n if (currentCenter) {\n var center = [currentCenter[0] + delta[0], currentCenter[1] + delta[1]];\n view.animateInternal({\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: linear,\n center: view.getConstrainedCenter(center)\n });\n }\n}\n/**\n * @param {import("../View.js").default} view View.\n * @param {number} delta Delta from previous zoom level.\n * @param {import("../coordinate.js").Coordinate=} opt_anchor Anchor coordinate in the user projection.\n * @param {number=} opt_duration Duration.\n */\n\nfunction zoomByDelta(view, delta, opt_anchor, opt_duration) {\n var currentZoom = view.getZoom();\n\n if (currentZoom === undefined) {\n return;\n }\n\n var newZoom = view.getConstrainedZoom(currentZoom + delta);\n var newResolution = view.getResolutionForZoom(newZoom);\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.animate({\n resolution: newResolution,\n anchor: opt_anchor,\n duration: opt_duration !== undefined ? opt_duration : 250,\n easing: easeOut\n });\n}\n/* harmony default export */ var interaction_Interaction = (Interaction);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DoubleClickZoom.js\nvar DoubleClickZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DoubleClickZoom\n */\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [delta=1] The zoom delta applied on each double click.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom by double-clicking on the map.\n * @api\n */\n\nvar DoubleClickZoom =\n/** @class */\nfunction (_super) {\n DoubleClickZoom_extends(DoubleClickZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DoubleClickZoom(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {number}\n */\n\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a\n * doubleclick) and eventually zooms the map.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n\n\n DoubleClickZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == ol_MapBrowserEventType.DBLCLICK) {\n var browserEvent =\n /** @type {MouseEvent} */\n mapBrowserEvent.originalEvent;\n var map = mapBrowserEvent.map;\n var anchor = mapBrowserEvent.coordinate;\n var delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, anchor, this.duration_);\n browserEvent.preventDefault();\n stopEvent = true;\n }\n\n return !stopEvent;\n };\n\n return DoubleClickZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_DoubleClickZoom = (DoubleClickZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/Pointer.js\nvar Pointer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/Pointer\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleDownEvent]\n * Function handling "down" events. If the function returns `true` then a drag\n * sequence is started.\n * @property {function(import("../MapBrowserEvent.js").default):void} [handleDragEvent]\n * Function handling "drag" events. This function is called on "move" events\n * during a drag sequence.\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleEvent]\n * Method called by the map to notify the interaction that a browser event was\n * dispatched to the map. The function may return `false` to prevent the\n * propagation of the event to other interactions in the map\'s interactions\n * chain.\n * @property {function(import("../MapBrowserEvent.js").default):void} [handleMoveEvent]\n * Function handling "move" events. This function is called on "move" events.\n * This functions is also called during a drag sequence, so during a drag\n * sequence both the `handleDragEvent` function and this function are called.\n * If `handleDownEvent` is defined and it returns true this function will not\n * be called during a drag sequence.\n * @property {function(import("../MapBrowserEvent.js").default):boolean} [handleUpEvent]\n * Function handling "up" events. If the function returns `false` then the\n * current drag sequence is stopped.\n * @property {function(boolean):boolean} [stopDown]\n * Should the down event be propagated to other interactions, or should be\n * stopped?\n */\n\n/**\n * @classdesc\n * Base class that calls user-defined functions on `down`, `move` and `up`\n * events. This class also manages "drag sequences".\n *\n * When the `handleDownEvent` user function returns `true` a drag sequence is\n * started. During a drag sequence the `handleDragEvent` user function is\n * called on `move` events. The drag sequence ends when the `handleUpEvent`\n * user function is called and returns `false`.\n * @api\n */\n\nvar PointerInteraction =\n/** @class */\nfunction (_super) {\n Pointer_extends(PointerInteraction, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PointerInteraction(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this,\n /** @type {import("./Interaction.js").InteractionOptions} */\n options) || this;\n\n if (options.handleDownEvent) {\n _this.handleDownEvent = options.handleDownEvent;\n }\n\n if (options.handleDragEvent) {\n _this.handleDragEvent = options.handleDragEvent;\n }\n\n if (options.handleMoveEvent) {\n _this.handleMoveEvent = options.handleMoveEvent;\n }\n\n if (options.handleUpEvent) {\n _this.handleUpEvent = options.handleUpEvent;\n }\n\n if (options.stopDown) {\n _this.stopDown = options.stopDown;\n }\n /**\n * @type {boolean}\n * @protected\n */\n\n\n _this.handlingDownUpSequence = false;\n /**\n * @type {!Object<string, PointerEvent>}\n * @private\n */\n\n _this.trackedPointers_ = {};\n /**\n * @type {Array<PointerEvent>}\n * @protected\n */\n\n _this.targetPointers = [];\n return _this;\n }\n /**\n * Returns the current number of pointers involved in the interaction,\n * e.g. `2` when two fingers are used.\n * @return {number} The number of pointers.\n * @api\n */\n\n\n PointerInteraction.prototype.getPointerCount = function () {\n return this.targetPointers.length;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleDownEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleDragEvent = function (mapBrowserEvent) {};\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} and may call into\n * other functions, if event sequences like e.g. \'drag\' or \'down-up\' etc. are\n * detected.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @api\n */\n\n\n PointerInteraction.prototype.handleEvent = function (mapBrowserEvent) {\n if (!mapBrowserEvent.originalEvent) {\n return true;\n }\n\n var stopEvent = false;\n this.updateTrackedPointers_(mapBrowserEvent);\n\n if (this.handlingDownUpSequence) {\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDRAG) {\n this.handleDragEvent(mapBrowserEvent); // prevent page scrolling during dragging\n\n mapBrowserEvent.originalEvent.preventDefault();\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERUP) {\n var handledUp = this.handleUpEvent(mapBrowserEvent);\n this.handlingDownUpSequence = handledUp && this.targetPointers.length > 0;\n }\n } else {\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDOWN) {\n var handled = this.handleDownEvent(mapBrowserEvent);\n this.handlingDownUpSequence = handled;\n stopEvent = this.stopDown(handled);\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERMOVE) {\n this.handleMoveEvent(mapBrowserEvent);\n }\n }\n\n return !stopEvent;\n };\n /**\n * Handle pointer move events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleMoveEvent = function (mapBrowserEvent) {};\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @protected\n */\n\n\n PointerInteraction.prototype.handleUpEvent = function (mapBrowserEvent) {\n return false;\n };\n /**\n * This function is used to determine if "down" events should be propagated\n * to other interactions or should be stopped.\n * @param {boolean} handled Was the event handled by the interaction?\n * @return {boolean} Should the `down` event be stopped?\n */\n\n\n PointerInteraction.prototype.stopDown = function (handled) {\n return handled;\n };\n /**\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @private\n */\n\n\n PointerInteraction.prototype.updateTrackedPointers_ = function (mapBrowserEvent) {\n if (isPointerDraggingEvent(mapBrowserEvent)) {\n var event_1 = mapBrowserEvent.originalEvent;\n var id = event_1.pointerId.toString();\n\n if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERUP) {\n delete this.trackedPointers_[id];\n } else if (mapBrowserEvent.type == ol_MapBrowserEventType.POINTERDOWN) {\n this.trackedPointers_[id] = event_1;\n } else if (id in this.trackedPointers_) {\n // update only when there was a pointerdown event for this pointer\n this.trackedPointers_[id] = event_1;\n }\n\n this.targetPointers = getValues(this.trackedPointers_);\n }\n };\n\n return PointerInteraction;\n}(interaction_Interaction);\n/**\n * @param {Array<PointerEvent>} pointerEvents List of events.\n * @return {import("../pixel.js").Pixel} Centroid pixel.\n */\n\n\nfunction Pointer_centroid(pointerEvents) {\n var length = pointerEvents.length;\n var clientX = 0;\n var clientY = 0;\n\n for (var i = 0; i < length; i++) {\n clientX += pointerEvents[i].clientX;\n clientY += pointerEvents[i].clientY;\n }\n\n return [clientX / length, clientY / length];\n}\n/**\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} Whether the event is a pointerdown, pointerdrag\n * or pointerup event.\n */\n\nfunction isPointerDraggingEvent(mapBrowserEvent) {\n var type = mapBrowserEvent.type;\n return type === ol_MapBrowserEventType.POINTERDOWN || type === ol_MapBrowserEventType.POINTERDRAG || type === ol_MapBrowserEventType.POINTERUP;\n}\n\n/* harmony default export */ var Pointer = (PointerInteraction);\n;// CONCATENATED MODULE: ./node_modules/ol/events/condition.js\n/**\n * @module ol/events/condition\n */\n\n\n\n\n/**\n * A function that takes an {@link module:ol/MapBrowserEvent} and returns a\n * `{boolean}`. If the condition is met, true should be returned.\n *\n * @typedef {function(this: ?, import("../MapBrowserEvent.js").default): boolean} Condition\n */\n\n/**\n * Creates a condition function that passes when all provided conditions pass.\n * @param {...Condition} var_args Conditions to check.\n * @return {Condition} Condition function.\n */\n\nfunction condition_all(var_args) {\n var conditions = arguments;\n /**\n * @param {import("../MapBrowserEvent.js").default} event Event.\n * @return {boolean} All conditions passed.\n */\n\n return function (event) {\n var pass = true;\n\n for (var i = 0, ii = conditions.length; i < ii; ++i) {\n pass = pass && conditions[i](event);\n\n if (!pass) {\n break;\n }\n }\n\n return pass;\n };\n}\n/**\n * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when\n * additionally the shift-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt key is pressed.\n * @api\n */\n\nvar altKeyOnly = function altKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise\n * (e.g. when additionally the platform-modifier-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt and shift keys are pressed.\n * @api\n */\n\nvar altShiftKeysOnly = function altShiftKeysOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n};\n/**\n * Return `true` if the map has the focus. This condition requires a map target\n * element with a `tabindex` attribute, e.g. `<div id="map" tabindex="1">`.\n *\n * @param {import("../MapBrowserEvent.js").default} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\n\nvar condition_focus = function focus(event) {\n return event.target.getTargetElement().contains(document.activeElement);\n};\n/**\n * Return `true` if the map has the focus or no \'tabindex\' attribute set.\n *\n * @param {import("../MapBrowserEvent.js").default} event Map browser event.\n * @return {boolean} The map container has the focus or no \'tabindex\' attribute.\n */\n\nvar focusWithTabindex = function focusWithTabindex(event) {\n return event.map.getTargetElement().hasAttribute(\'tabindex\') ? condition_focus(event) : true;\n};\n/**\n * Return always true.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @api\n */\n\nvar always = TRUE;\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\n\nvar click = function click(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n/**\n * Return `true` if the event has an "action"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\n\nvar mouseActionButton = function mouseActionButton(mapBrowserEvent) {\n var originalEvent =\n /** @type {MouseEvent} */\n mapBrowserEvent.originalEvent;\n return originalEvent.button == 0 && !(WEBKIT && has_MAC && originalEvent.ctrlKey);\n};\n/**\n * Return always false.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @api\n */\n\nvar never = (/* unused pure expression or super */ null && (FALSE));\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\n\nvar pointerMove = function pointerMove(mapBrowserEvent) {\n return mapBrowserEvent.type == \'pointermove\';\n};\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\n\nvar singleClick = function singleClick(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\n\nvar doubleClick = function doubleClick(mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\n\nvar noModifierKeys = function noModifierKeys(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\n\nvar platformModifierKeyOnly = function platformModifierKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) && !originalEvent.shiftKey;\n};\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\n\nvar shiftKeyOnly = function shiftKeyOnly(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n return !originalEvent.altKey && !(originalEvent.metaKey || originalEvent.ctrlKey) && originalEvent.shiftKey;\n};\n/**\n * Return `true` if the target element is not editable, i.e. not a `<input>`-,\n * `<select>`- or `<textarea>`-element, `false` otherwise.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\n\nvar targetNotEditable = function targetNotEditable(mapBrowserEvent) {\n var originalEvent =\n /** @type {KeyboardEvent|MouseEvent|TouchEvent} */\n mapBrowserEvent.originalEvent;\n var tagName =\n /** @type {Element} */\n originalEvent.target.tagName;\n return tagName !== \'INPUT\' && tagName !== \'SELECT\' && tagName !== \'TEXTAREA\';\n};\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\n\nvar mouseOnly = function mouseOnly(mapBrowserEvent) {\n var pointerEvent =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvent.pointerType == \'mouse\';\n};\n/**\n * Return `true` if the event originates from a touchable device.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a touchable device.\n * @api\n */\n\nvar touchOnly = function touchOnly(mapBrowserEvent) {\n var pointerEvt =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvt.pointerType === \'touch\';\n};\n/**\n * Return `true` if the event originates from a digital pen.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a digital pen.\n * @api\n */\n\nvar penOnly = function penOnly(mapBrowserEvent) {\n var pointerEvt =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n // see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n\n return pointerEvt.pointerType === \'pen\';\n};\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See http://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\n\nvar primaryAction = function primaryAction(mapBrowserEvent) {\n var pointerEvent =\n /** @type {import("../MapBrowserEvent").default} */\n mapBrowserEvent.originalEvent;\n asserts_assert(pointerEvent !== undefined, 56); // mapBrowserEvent must originate from a pointer event\n\n return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragPan.js\nvar DragPan_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragPan\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~noModifierKeys} and {@link module:ol/events/condition~primaryAction}.\n * @property {boolean} [onFocusOnly=false] When the map\'s target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {import("../Kinetic.js").default} [kinetic] Kinetic inertia to apply to the pan.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map by dragging the map.\n * @api\n */\n\nvar DragPan =\n/** @class */\nfunction (_super) {\n DragPan_extends(DragPan, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragPan(opt_options) {\n var _this = _super.call(this, {\n stopDown: functions_FALSE\n }) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import("../Kinetic.js").default|undefined}\n */\n\n _this.kinetic_ = options.kinetic;\n /**\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.lastCentroid = null;\n /**\n * @type {number}\n */\n\n _this.lastPointersCount_;\n /**\n * @type {boolean}\n */\n\n _this.panning_ = false;\n var condition = options.condition ? options.condition : condition_all(noModifierKeys, primaryAction);\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.onFocusOnly ? condition_all(focusWithTabindex, condition) : condition;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.noKinetic_ = false;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragPan.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!this.panning_) {\n this.panning_ = true;\n this.getMap().getView().beginInteraction();\n }\n\n var targetPointers = this.targetPointers;\n var centroid = Pointer_centroid(targetPointers);\n\n if (targetPointers.length == this.lastPointersCount_) {\n if (this.kinetic_) {\n this.kinetic_.update(centroid[0], centroid[1]);\n }\n\n if (this.lastCentroid) {\n var delta = [this.lastCentroid[0] - centroid[0], centroid[1] - this.lastCentroid[1]];\n var map = mapBrowserEvent.map;\n var view = map.getView();\n coordinate_scale(delta, view.getResolution());\n coordinate_rotate(delta, view.getRotation());\n view.adjustCenterInternal(delta);\n }\n } else if (this.kinetic_) {\n // reset so we don\'t overestimate the kinetic energy after\n // after one finger down, tiny drag, second finger down\n this.kinetic_.begin();\n }\n\n this.lastCentroid = centroid;\n this.lastPointersCount_ = targetPointers.length;\n mapBrowserEvent.originalEvent.preventDefault();\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragPan.prototype.handleUpEvent = function (mapBrowserEvent) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (this.targetPointers.length === 0) {\n if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {\n var distance = this.kinetic_.getDistance();\n var angle = this.kinetic_.getAngle();\n var center = view.getCenterInternal();\n var centerpx = map.getPixelFromCoordinateInternal(center);\n var dest = map.getCoordinateFromPixelInternal([centerpx[0] - distance * Math.cos(angle), centerpx[1] - distance * Math.sin(angle)]);\n view.animateInternal({\n center: view.getConstrainedCenter(dest),\n duration: 500,\n easing: easeOut\n });\n }\n\n if (this.panning_) {\n this.panning_ = false;\n view.endInteraction();\n }\n\n return false;\n } else {\n if (this.kinetic_) {\n // reset so we don\'t overestimate the kinetic energy after\n // after one finger up, tiny drag, second finger up\n this.kinetic_.begin();\n }\n\n this.lastCentroid = null;\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragPan.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n this.lastCentroid = null; // stop any current animation\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n if (this.kinetic_) {\n this.kinetic_.begin();\n } // No kinetic as soon as more than one pointer on the screen is\n // detected. This is to prevent nasty pans after pinch.\n\n\n this.noKinetic_ = this.targetPointers.length > 1;\n return true;\n } else {\n return false;\n }\n };\n\n return DragPan;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragPan = (DragPan);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragRotate.js\nvar DragRotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragRotate\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an\n * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~altShiftKeysOnly}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the alt and shift keys are held down.\n *\n * This interaction is only supported for mouse devices.\n * @api\n */\n\nvar DragRotate =\n/** @class */\nfunction (_super) {\n DragRotate_extends(DragRotate, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragRotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n stopDown: functions_FALSE\n }) || this;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : altShiftKeysOnly;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return;\n }\n\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (view.getConstraints().rotation === disable) {\n return;\n }\n\n var size = map.getSize();\n var offset = mapBrowserEvent.pixel;\n var theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);\n\n if (this.lastAngle_ !== undefined) {\n var delta = theta - this.lastAngle_;\n view.adjustRotationInternal(-delta);\n }\n\n this.lastAngle_ = theta;\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return true;\n }\n\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return false;\n }\n\n if (mouseActionButton(mapBrowserEvent) && this.condition_(mapBrowserEvent)) {\n var map = mapBrowserEvent.map;\n map.getView().beginInteraction();\n this.lastAngle_ = undefined;\n return true;\n } else {\n return false;\n }\n };\n\n return DragRotate;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragRotate = (DragRotate);\n;// CONCATENATED MODULE: ./node_modules/ol/render/Box.js\n/**\n * @module ol/render/Box\n */\nvar Box_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\nvar RenderBox =\n/** @class */\nfunction (_super) {\n Box_extends(RenderBox, _super);\n /**\n * @param {string} className CSS class name.\n */\n\n\n function RenderBox(className) {\n var _this = _super.call(this) || this;\n /**\n * @type {import("../geom/Polygon.js").default}\n * @private\n */\n\n\n _this.geometry_ = null;\n /**\n * @type {HTMLDivElement}\n * @private\n */\n\n _this.element_ = document.createElement(\'div\');\n _this.element_.style.position = \'absolute\';\n _this.element_.style.pointerEvents = \'auto\';\n _this.element_.className = \'ol-box \' + className;\n /**\n * @private\n * @type {import("../PluggableMap.js").default}\n */\n\n _this.map_ = null;\n /**\n * @private\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import("../pixel.js").Pixel}\n */\n\n _this.endPixel_ = null;\n return _this;\n }\n /**\n * Clean up.\n */\n\n\n RenderBox.prototype.disposeInternal = function () {\n this.setMap(null);\n };\n /**\n * @private\n */\n\n\n RenderBox.prototype.render_ = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var px = \'px\';\n var style = this.element_.style;\n style.left = Math.min(startPixel[0], endPixel[0]) + px;\n style.top = Math.min(startPixel[1], endPixel[1]) + px;\n style.width = Math.abs(endPixel[0] - startPixel[0]) + px;\n style.height = Math.abs(endPixel[1] - startPixel[1]) + px;\n };\n /**\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n RenderBox.prototype.setMap = function (map) {\n if (this.map_) {\n this.map_.getOverlayContainer().removeChild(this.element_);\n var style = this.element_.style;\n style.left = \'inherit\';\n style.top = \'inherit\';\n style.width = \'inherit\';\n style.height = \'inherit\';\n }\n\n this.map_ = map;\n\n if (this.map_) {\n this.map_.getOverlayContainer().appendChild(this.element_);\n }\n };\n /**\n * @param {import("../pixel.js").Pixel} startPixel Start pixel.\n * @param {import("../pixel.js").Pixel} endPixel End pixel.\n */\n\n\n RenderBox.prototype.setPixels = function (startPixel, endPixel) {\n this.startPixel_ = startPixel;\n this.endPixel_ = endPixel;\n this.createOrUpdateGeometry();\n this.render_();\n };\n /**\n * Creates or updates the cached geometry.\n */\n\n\n RenderBox.prototype.createOrUpdateGeometry = function () {\n var startPixel = this.startPixel_;\n var endPixel = this.endPixel_;\n var pixels = [startPixel, [startPixel[0], endPixel[1]], endPixel, [endPixel[0], startPixel[1]]];\n var coordinates = pixels.map(this.map_.getCoordinateFromPixelInternal, this.map_); // close the polygon\n\n coordinates[4] = coordinates[0].slice();\n\n if (!this.geometry_) {\n this.geometry_ = new geom_Polygon([coordinates]);\n } else {\n this.geometry_.setCoordinates([coordinates]);\n }\n };\n /**\n * @return {import("../geom/Polygon.js").default} Geometry.\n */\n\n\n RenderBox.prototype.getGeometry = function () {\n return this.geometry_;\n };\n\n return RenderBox;\n}(ol_Disposable);\n\n/* harmony default export */ var Box = (RenderBox);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragBox.js\nvar DragBox_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragBox\n */\n// FIXME draw drag box\n\n\n\n\n\n\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,\n * true should be returned.\n * @typedef {function(this: ?, import("../MapBrowserEvent.js").default, import("../pixel.js").Pixel, import("../pixel.js").Pixel):boolean} EndCondition\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-dragbox\'] CSS class name for styling the box.\n * @property {import("../events/condition.js").Condition} [condition] A function that takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link ol/events/condition~mouseActionButton}.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default\n * `boxEndCondition` function.\n * @property {EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.\n * Default is `true` if the area of the box is bigger than the `minArea` option.\n * @property {function(this:DragBox, import("../MapBrowserEvent.js").default):void} [onBoxEnd] Code to execute just\n * before `boxend` is fired.\n */\n\n/**\n * @enum {string}\n */\n\nvar DragBoxEventType = {\n /**\n * Triggered upon drag box start.\n * @event DragBoxEvent#boxstart\n * @api\n */\n BOXSTART: \'boxstart\',\n\n /**\n * Triggered on drag when box is active.\n * @event DragBoxEvent#boxdrag\n * @api\n */\n BOXDRAG: \'boxdrag\',\n\n /**\n * Triggered upon drag box end.\n * @event DragBoxEvent#boxend\n * @api\n */\n BOXEND: \'boxend\',\n\n /**\n * Triggered upon drag box canceled.\n * @event DragBoxEvent#boxcancel\n * @api\n */\n BOXCANCEL: \'boxcancel\'\n};\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of\n * this type.\n */\n\nvar DragBoxEvent =\n/** @class */\nfunction (_super) {\n DragBox_extends(DragBoxEvent, _super);\n /**\n * @param {string} type The event type.\n * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Originating event.\n */\n\n\n function DragBoxEvent(type, coordinate, mapBrowserEvent) {\n var _this = _super.call(this, type) || this;\n /**\n * The coordinate of the drag event.\n * @const\n * @type {import("../coordinate.js").Coordinate}\n * @api\n */\n\n\n _this.coordinate = coordinate;\n /**\n * @const\n * @type {import("../MapBrowserEvent.js").default}\n * @api\n */\n\n _this.mapBrowserEvent = mapBrowserEvent;\n return _this;\n }\n\n return DragBoxEvent;\n}(Event);\n\n\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when the shift or other key is held down. This is used, for example,\n * for zooming to a specific area of the map\n * (see {@link module:ol/interaction/DragZoom~DragZoom} and\n * {@link module:ol/interaction/DragRotateAndZoom}).\n *\n * @fires DragBoxEvent\n * @api\n */\n\nvar DragBox =\n/** @class */\nfunction (_super) {\n DragBox_extends(DragBox, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragBox(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {import("../render/Box.js").default}\n * @private\n */\n\n _this.box_ = new Box(options.className || \'ol-dragbox\');\n /**\n * @type {number}\n * @private\n */\n\n _this.minArea_ = options.minArea !== undefined ? options.minArea : 64;\n\n if (options.onBoxEnd) {\n _this.onBoxEnd = options.onBoxEnd;\n }\n /**\n * @type {import("../pixel.js").Pixel}\n * @private\n */\n\n\n _this.startPixel_ = null;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : mouseActionButton;\n /**\n * @private\n * @type {EndCondition}\n */\n\n _this.boxEndCondition_ = options.boxEndCondition ? options.boxEndCondition : _this.defaultBoxEndCondition;\n return _this;\n }\n /**\n * The default condition for determining whether the boxend event\n * should fire.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent\n * leading to the box end.\n * @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.\n * @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.\n * @return {boolean} Whether or not the boxend condition should be fired.\n */\n\n\n DragBox.prototype.defaultBoxEndCondition = function (mapBrowserEvent, startPixel, endPixel) {\n var width = endPixel[0] - startPixel[0];\n var height = endPixel[1] - startPixel[1];\n return width * width + height * height >= this.minArea_;\n };\n /**\n * Returns geometry of last drawn box.\n * @return {import("../geom/Polygon.js").default} Geometry.\n * @api\n */\n\n\n DragBox.prototype.getGeometry = function () {\n return this.box_.getGeometry();\n };\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n DragBox.prototype.handleDragEvent = function (mapBrowserEvent) {\n this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG, mapBrowserEvent.coordinate, mapBrowserEvent));\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragBox.prototype.handleUpEvent = function (mapBrowserEvent) {\n this.box_.setMap(null);\n var completeBox = this.boxEndCondition_(mapBrowserEvent, this.startPixel_, mapBrowserEvent.pixel);\n\n if (completeBox) {\n this.onBoxEnd(mapBrowserEvent);\n }\n\n this.dispatchEvent(new DragBoxEvent(completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL, mapBrowserEvent.coordinate, mapBrowserEvent));\n return false;\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n DragBox.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.condition_(mapBrowserEvent)) {\n this.startPixel_ = mapBrowserEvent.pixel;\n this.box_.setMap(mapBrowserEvent.map);\n this.box_.setPixels(this.startPixel_, this.startPixel_);\n this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXSTART, mapBrowserEvent.coordinate, mapBrowserEvent));\n return true;\n } else {\n return false;\n }\n };\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import("../MapBrowserEvent.js").default} event Event.\n */\n\n\n DragBox.prototype.onBoxEnd = function (event) {};\n\n return DragBox;\n}(Pointer);\n\n/* harmony default export */ var interaction_DragBox = (DragBox);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/DragZoom.js\nvar DragZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/DragZoom\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-dragzoom\'] CSS class name for styling the\n * box.\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition~shiftKeyOnly}.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {boolean} [out=false] Use interaction for zooming out.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default\n * `boxEndCondition` function.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by clicking and dragging on the map,\n * normally combined with an {@link module:ol/events/condition} that limits\n * it to when a key, shift by default, is held down.\n *\n * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or\n * your custom one configured with `className`.\n * @api\n */\n\nvar DragZoom =\n/** @class */\nfunction (_super) {\n DragZoom_extends(DragZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function DragZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var condition = options.condition ? options.condition : shiftKeyOnly;\n _this = _super.call(this, {\n condition: condition,\n className: options.className || \'ol-dragzoom\',\n minArea: options.minArea\n }) || this;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 200;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.out_ = options.out !== undefined ? options.out : false;\n return _this;\n }\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import("../MapBrowserEvent.js").default} event Event.\n */\n\n\n DragZoom.prototype.onBoxEnd = function (event) {\n var map = this.getMap();\n var view =\n /** @type {!import("../View.js").default} */\n map.getView();\n var size =\n /** @type {!import("../size.js").Size} */\n map.getSize();\n var extent = this.getGeometry().getExtent();\n\n if (this.out_) {\n var mapExtent = view.calculateExtentInternal(size);\n var boxPixelExtent = createOrUpdateFromCoordinates([map.getPixelFromCoordinateInternal(getBottomLeft(extent)), map.getPixelFromCoordinateInternal(getTopRight(extent))]);\n var factor = view.getResolutionForExtentInternal(boxPixelExtent, size);\n scaleFromCenter(mapExtent, 1 / factor);\n extent = mapExtent;\n }\n\n var resolution = view.getConstrainedResolution(view.getResolutionForExtentInternal(extent, size));\n var center = view.getConstrainedCenter(getCenter(extent), resolution);\n view.animateInternal({\n resolution: resolution,\n center: center,\n duration: this.duration_,\n easing: easeOut\n });\n };\n\n return DragZoom;\n}(interaction_DragBox);\n\n/* harmony default export */ var interaction_DragZoom = (DragZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/events/KeyCode.js\n/**\n * @module ol/events/KeyCode\n */\n\n/**\n * @enum {number}\n * @const\n */\n/* harmony default export */ var KeyCode = ({\n LEFT: 37,\n UP: 38,\n RIGHT: 39,\n DOWN: 40\n});\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardPan.js\nvar KeyboardPan_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/KeyboardPan\n */\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~noModifierKeys} and\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {number} [pixelDelta=128] The amount of pixels to pan on each key\n * press.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map using keyboard arrows.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.\n * @api\n */\n\nvar KeyboardPan =\n/** @class */\nfunction (_super) {\n KeyboardPan_extends(KeyboardPan, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function KeyboardPan(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options || {};\n /**\n * @private\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.\n * @return {boolean} Combined condition result.\n */\n\n _this.defaultCondition_ = function (mapBrowserEvent) {\n return noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent);\n };\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n\n _this.condition_ = options.condition !== undefined ? options.condition : _this.defaultCondition_;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelDelta_ = options.pixelDelta !== undefined ? options.pixelDelta : 128;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides the direction to pan to (if an arrow key was\n * pressed).\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardPan}\n */\n\n\n KeyboardPan.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == EventType.KEYDOWN) {\n var keyEvent =\n /** @type {KeyboardEvent} */\n mapBrowserEvent.originalEvent;\n var keyCode = keyEvent.keyCode;\n\n if (this.condition_(mapBrowserEvent) && (keyCode == KeyCode.DOWN || keyCode == KeyCode.LEFT || keyCode == KeyCode.RIGHT || keyCode == KeyCode.UP)) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var mapUnitsDelta = view.getResolution() * this.pixelDelta_;\n var deltaX = 0,\n deltaY = 0;\n\n if (keyCode == KeyCode.DOWN) {\n deltaY = -mapUnitsDelta;\n } else if (keyCode == KeyCode.LEFT) {\n deltaX = -mapUnitsDelta;\n } else if (keyCode == KeyCode.RIGHT) {\n deltaX = mapUnitsDelta;\n } else {\n deltaY = mapUnitsDelta;\n }\n\n var delta = [deltaX, deltaY];\n coordinate_rotate(delta, view.getRotation());\n pan(view, delta, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n\n return !stopEvent;\n };\n\n return KeyboardPan;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_KeyboardPan = (KeyboardPan);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/KeyboardZoom.js\nvar KeyboardZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/KeyboardZoom\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~targetNotEditable}.\n * @property {number} [delta=1] The zoom level delta on each key press.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map using keyboard + and -.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardPan~KeyboardPan}.\n * @api\n */\n\nvar KeyboardZoom =\n/** @class */\nfunction (_super) {\n KeyboardZoom_extends(KeyboardZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function KeyboardZoom(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.condition ? options.condition : targetNotEditable;\n /**\n * @private\n * @type {number}\n */\n\n _this.delta_ = options.delta ? options.delta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 100;\n return _this;\n }\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides whether to zoom in or out (depending on whether the\n * key pressed was \'+\' or \'-\').\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @this {KeyboardZoom}\n */\n\n\n KeyboardZoom.prototype.handleEvent = function (mapBrowserEvent) {\n var stopEvent = false;\n\n if (mapBrowserEvent.type == EventType.KEYDOWN || mapBrowserEvent.type == EventType.KEYPRESS) {\n var keyEvent =\n /** @type {KeyboardEvent} */\n mapBrowserEvent.originalEvent;\n var charCode = keyEvent.charCode;\n\n if (this.condition_(mapBrowserEvent) && (charCode == \'+\'.charCodeAt(0) || charCode == \'-\'.charCodeAt(0))) {\n var map = mapBrowserEvent.map;\n var delta = charCode == \'+\'.charCodeAt(0) ? this.delta_ : -this.delta_;\n var view = map.getView();\n zoomByDelta(view, delta, undefined, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n\n return !stopEvent;\n };\n\n return KeyboardZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_KeyboardZoom = (KeyboardZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/Kinetic.js\n/**\n * @module ol/Kinetic\n */\n\n/**\n * @classdesc\n * Implementation of inertial deceleration for map movement.\n *\n * @api\n */\nvar Kinetic =\n/** @class */\nfunction () {\n /**\n * @param {number} decay Rate of decay (must be negative).\n * @param {number} minVelocity Minimum velocity (pixels/millisecond).\n * @param {number} delay Delay to consider to calculate the kinetic\n * initial values (milliseconds).\n */\n function Kinetic(decay, minVelocity, delay) {\n /**\n * @private\n * @type {number}\n */\n this.decay_ = decay;\n /**\n * @private\n * @type {number}\n */\n\n this.minVelocity_ = minVelocity;\n /**\n * @private\n * @type {number}\n */\n\n this.delay_ = delay;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.points_ = [];\n /**\n * @private\n * @type {number}\n */\n\n this.angle_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n this.initialVelocity_ = 0;\n }\n /**\n * FIXME empty description for jsdoc\n */\n\n\n Kinetic.prototype.begin = function () {\n this.points_.length = 0;\n this.angle_ = 0;\n this.initialVelocity_ = 0;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n */\n\n\n Kinetic.prototype.update = function (x, y) {\n this.points_.push(x, y, Date.now());\n };\n /**\n * @return {boolean} Whether we should do kinetic animation.\n */\n\n\n Kinetic.prototype.end = function () {\n if (this.points_.length < 6) {\n // at least 2 points are required (i.e. there must be at least 6 elements\n // in the array)\n return false;\n }\n\n var delay = Date.now() - this.delay_;\n var lastIndex = this.points_.length - 3;\n\n if (this.points_[lastIndex + 2] < delay) {\n // the last tracked point is too old, which means that the user stopped\n // panning before releasing the map\n return false;\n } // get the first point which still falls into the delay time\n\n\n var firstIndex = lastIndex - 3;\n\n while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {\n firstIndex -= 3;\n }\n\n var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2]; // we don\'t want a duration of 0 (divide by zero)\n // we also make sure the user panned for a duration of at least one frame\n // (1/60s) to compute sane displacement values\n\n if (duration < 1000 / 60) {\n return false;\n }\n\n var dx = this.points_[lastIndex] - this.points_[firstIndex];\n var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];\n this.angle_ = Math.atan2(dy, dx);\n this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;\n return this.initialVelocity_ > this.minVelocity_;\n };\n /**\n * @return {number} Total distance travelled (pixels).\n */\n\n\n Kinetic.prototype.getDistance = function () {\n return (this.minVelocity_ - this.initialVelocity_) / this.decay_;\n };\n /**\n * @return {number} Angle of the kinetic panning animation (radians).\n */\n\n\n Kinetic.prototype.getAngle = function () {\n return this.angle_;\n };\n\n return Kinetic;\n}();\n\n/* harmony default export */ var ol_Kinetic = (Kinetic);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/MouseWheelZoom.js\nvar MouseWheelZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/MouseWheelZoom\n */\n\n\n\n\n\n\n\n/**\n * @enum {string}\n */\n\nvar Mode = {\n TRACKPAD: \'trackpad\',\n WHEEL: \'wheel\'\n};\n/**\n * @typedef {Object} Options\n * @property {import("../events/condition.js").Condition} [condition] A function that\n * takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition~always}.\n * @property {boolean} [onFocusOnly=false] When the map\'s target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {number} [maxDelta=1] Maximum mouse wheel delta.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.\n * @property {boolean} [useAnchor=true] Enable zooming using the mouse\'s\n * location as the anchor. When set to `false`, zooming in and out will zoom to\n * the center of the screen instead of zooming on the mouse\'s location.\n * @property {boolean} [constrainResolution=false] If true, the mouse wheel zoom\n * event will always animate to the closest zoom level after an interaction;\n * false means intermediary zoom levels are allowed.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by scrolling the mouse wheel.\n * @api\n */\n\nvar MouseWheelZoom =\n/** @class */\nfunction (_super) {\n MouseWheelZoom_extends(MouseWheelZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function MouseWheelZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this,\n /** @type {import("./Interaction.js").InteractionOptions} */\n options) || this;\n /**\n * @private\n * @type {number}\n */\n\n _this.totalDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.lastDelta_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n /**\n * @private\n * @type {number}\n */\n\n _this.timeout_ = options.timeout !== undefined ? options.timeout : 80;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.constrainResolution_ = options.constrainResolution !== undefined ? options.constrainResolution : false;\n var condition = options.condition ? options.condition : always;\n /**\n * @private\n * @type {import("../events/condition.js").Condition}\n */\n\n _this.condition_ = options.onFocusOnly ? condition_all(focusWithTabindex, condition) : condition;\n /**\n * @private\n * @type {?import("../coordinate.js").Coordinate}\n */\n\n _this.lastAnchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.startTime_ = undefined;\n /**\n * @private\n * @type {?}\n */\n\n _this.timeoutId_;\n /**\n * @private\n * @type {Mode|undefined}\n */\n\n _this.mode_ = undefined;\n /**\n * Trackpad events separated by this delay will be considered separate\n * interactions.\n * @type {number}\n */\n\n _this.trackpadEventGap_ = 400;\n /**\n * @type {?}\n */\n\n _this.trackpadTimeoutId_;\n /**\n * The number of delta values per zoom level\n * @private\n * @type {number}\n */\n\n _this.deltaPerZoom_ = 300;\n return _this;\n }\n /**\n * @private\n */\n\n\n MouseWheelZoom.prototype.endInteraction_ = function () {\n this.trackpadTimeoutId_ = undefined;\n var view = this.getMap().getView();\n view.endInteraction(undefined, this.lastDelta_ ? this.lastDelta_ > 0 ? 1 : -1 : 0, this.lastAnchor_);\n };\n /**\n * Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually\n * zooms the map.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n */\n\n\n MouseWheelZoom.prototype.handleEvent = function (mapBrowserEvent) {\n if (!this.condition_(mapBrowserEvent)) {\n return true;\n }\n\n var type = mapBrowserEvent.type;\n\n if (type !== EventType.WHEEL) {\n return true;\n }\n\n var map = mapBrowserEvent.map;\n var wheelEvent =\n /** @type {WheelEvent} */\n mapBrowserEvent.originalEvent;\n wheelEvent.preventDefault();\n\n if (this.useAnchor_) {\n this.lastAnchor_ = mapBrowserEvent.coordinate;\n } // Delta normalisation inspired by\n // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js\n\n\n var delta;\n\n if (mapBrowserEvent.type == EventType.WHEEL) {\n delta = wheelEvent.deltaY;\n\n if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n delta /= DEVICE_PIXEL_RATIO;\n }\n\n if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= 40;\n }\n }\n\n if (delta === 0) {\n return false;\n } else {\n this.lastDelta_ = delta;\n }\n\n var now = Date.now();\n\n if (this.startTime_ === undefined) {\n this.startTime_ = now;\n }\n\n if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {\n this.mode_ = Math.abs(delta) < 4 ? Mode.TRACKPAD : Mode.WHEEL;\n }\n\n var view = map.getView();\n\n if (this.mode_ === Mode.TRACKPAD && !(view.getConstrainResolution() || this.constrainResolution_)) {\n if (this.trackpadTimeoutId_) {\n clearTimeout(this.trackpadTimeoutId_);\n } else {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n view.beginInteraction();\n }\n\n this.trackpadTimeoutId_ = setTimeout(this.endInteraction_.bind(this), this.timeout_);\n view.adjustZoom(-delta / this.deltaPerZoom_, this.lastAnchor_);\n this.startTime_ = now;\n return false;\n }\n\n this.totalDelta_ += delta;\n var timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);\n clearTimeout(this.timeoutId_);\n this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);\n return false;\n };\n /**\n * @private\n * @param {import("../PluggableMap.js").default} map Map.\n */\n\n\n MouseWheelZoom.prototype.handleWheelZoom_ = function (map) {\n var view = map.getView();\n\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n\n var delta = -math_clamp(this.totalDelta_, -this.maxDelta_ * this.deltaPerZoom_, this.maxDelta_ * this.deltaPerZoom_) / this.deltaPerZoom_;\n\n if (view.getConstrainResolution() || this.constrainResolution_) {\n // view has a zoom constraint, zoom by 1\n delta = delta ? delta > 0 ? 1 : -1 : 0;\n }\n\n zoomByDelta(view, delta, this.lastAnchor_, this.duration_);\n this.mode_ = undefined;\n this.totalDelta_ = 0;\n this.lastAnchor_ = null;\n this.startTime_ = undefined;\n this.timeoutId_ = undefined;\n };\n /**\n * Enable or disable using the mouse\'s location as an anchor when zooming\n * @param {boolean} useAnchor true to zoom to the mouse\'s location, false\n * to zoom to the center of the map\n * @api\n */\n\n\n MouseWheelZoom.prototype.setMouseAnchor = function (useAnchor) {\n this.useAnchor_ = useAnchor;\n\n if (!useAnchor) {\n this.lastAnchor_ = null;\n }\n };\n\n return MouseWheelZoom;\n}(interaction_Interaction);\n\n/* harmony default export */ var interaction_MouseWheelZoom = (MouseWheelZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchRotate.js\nvar PinchRotate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/PinchRotate\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] The duration of the animation in\n * milliseconds.\n * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by twisting with two fingers\n * on a touch screen.\n * @api\n */\n\nvar PinchRotate =\n/** @class */\nfunction (_super) {\n PinchRotate_extends(PinchRotate, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PinchRotate(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var pointerOptions =\n /** @type {import("./Pointer.js").Options} */\n options;\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = functions_FALSE;\n }\n\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastAngle_ = undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.rotating_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.rotationDelta_ = 0.0;\n /**\n * @private\n * @type {number}\n */\n\n _this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 250;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n PinchRotate.prototype.handleDragEvent = function (mapBrowserEvent) {\n var rotationDelta = 0.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1]; // angle between touches\n\n var angle = Math.atan2(touch1.clientY - touch0.clientY, touch1.clientX - touch0.clientX);\n\n if (this.lastAngle_ !== undefined) {\n var delta = angle - this.lastAngle_;\n this.rotationDelta_ += delta;\n\n if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {\n this.rotating_ = true;\n }\n\n rotationDelta = delta;\n }\n\n this.lastAngle_ = angle;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (view.getConstraints().rotation === disable) {\n return;\n } // rotate anchor point.\n // FIXME: should be the intersection point between the lines:\n // touch0,touch1 and previousTouch0,previousTouch1\n\n\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = Pointer_centroid(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid); // rotate\n\n if (this.rotating_) {\n map.render();\n view.adjustRotationInternal(rotationDelta, this.anchor_);\n }\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchRotate.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n } else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchRotate.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastAngle_ = undefined;\n this.rotating_ = false;\n this.rotationDelta_ = 0.0;\n\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n\n return true;\n } else {\n return false;\n }\n };\n\n return PinchRotate;\n}(Pointer);\n\n/* harmony default export */ var interaction_PinchRotate = (PinchRotate);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction/PinchZoom.js\nvar PinchZoom_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/interaction/PinchZoom\n */\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=400] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by pinching with two fingers\n * on a touch screen.\n * @api\n */\n\nvar PinchZoom =\n/** @class */\nfunction (_super) {\n PinchZoom_extends(PinchZoom, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function PinchZoom(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var pointerOptions =\n /** @type {import("./Pointer.js").Options} */\n options;\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = functions_FALSE;\n }\n\n _this = _super.call(this, pointerOptions) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.duration_ = options.duration !== undefined ? options.duration : 400;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.lastDistance_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.lastScaleDelta_ = 1;\n return _this;\n }\n /**\n * Handle pointer drag events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n */\n\n\n PinchZoom.prototype.handleDragEvent = function (mapBrowserEvent) {\n var scaleDelta = 1.0;\n var touch0 = this.targetPointers[0];\n var touch1 = this.targetPointers[1];\n var dx = touch0.clientX - touch1.clientX;\n var dy = touch0.clientY - touch1.clientY; // distance between touches\n\n var distance = Math.sqrt(dx * dx + dy * dy);\n\n if (this.lastDistance_ !== undefined) {\n scaleDelta = this.lastDistance_ / distance;\n }\n\n this.lastDistance_ = distance;\n var map = mapBrowserEvent.map;\n var view = map.getView();\n\n if (scaleDelta != 1.0) {\n this.lastScaleDelta_ = scaleDelta;\n } // scale anchor point.\n\n\n var viewportPosition = map.getViewport().getBoundingClientRect();\n var centroid = Pointer_centroid(this.targetPointers);\n centroid[0] -= viewportPosition.left;\n centroid[1] -= viewportPosition.top;\n this.anchor_ = map.getCoordinateFromPixelInternal(centroid); // scale, bypass the resolution constraint\n\n map.render();\n view.adjustResolutionInternal(scaleDelta, this.anchor_);\n };\n /**\n * Handle pointer up events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchZoom.prototype.handleUpEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n var map = mapBrowserEvent.map;\n var view = map.getView();\n var direction = this.lastScaleDelta_ > 1 ? 1 : -1;\n view.endInteraction(this.duration_, direction);\n return false;\n } else {\n return true;\n }\n };\n /**\n * Handle pointer down events.\n * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n */\n\n\n PinchZoom.prototype.handleDownEvent = function (mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n var map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastDistance_ = undefined;\n this.lastScaleDelta_ = 1;\n\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n\n return true;\n } else {\n return false;\n }\n };\n\n return PinchZoom;\n}(Pointer);\n\n/* harmony default export */ var interaction_PinchZoom = (PinchZoom);\n;// CONCATENATED MODULE: ./node_modules/ol/interaction.js\n/**\n * @module ol/interaction\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 * @typedef {Object} DefaultsOptions\n * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is\n * desired.\n * @property {boolean} [onFocusOnly=false] Interact only when the map has the\n * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is\n * useful when page scroll is desired for maps that do not have the browser\'s\n * focus.\n * @property {boolean} [doubleClickZoom=true] Whether double click zoom is\n * desired.\n * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.\n * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.\n * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.\n * @property {boolean} [dragPan=true] Whether drag pan is desired.\n * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.\n * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.\n * @property {number} [zoomDelta] Zoom level delta when using keyboard or double click zoom.\n * @property {number} [zoomDuration] Duration of the zoom animation in\n * milliseconds.\n */\n\n/**\n * Set of interactions included in maps by default. Specific interactions can be\n * excluded by setting the appropriate option to false in the constructor\n * options, but the order of the interactions is fixed. If you want to specify\n * a different order for interactions, you will need to create your own\n * {@link module:ol/interaction/Interaction} instances and insert\n * them into a {@link module:ol/Collection} in the order you want\n * before creating your {@link module:ol/Map~Map} instance. Changing the order can\n * be of interest if the event propagation needs to be stopped at a point.\n * The default set of interactions, in sequence, is:\n * * {@link module:ol/interaction/DragRotate~DragRotate}\n * * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}\n * * {@link module:ol/interaction/DragPan~DragPan}\n * * {@link module:ol/interaction/PinchRotate~PinchRotate}\n * * {@link module:ol/interaction/PinchZoom~PinchZoom}\n * * {@link module:ol/interaction/KeyboardPan~KeyboardPan}\n * * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}\n * * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}\n * * {@link module:ol/interaction/DragZoom~DragZoom}\n *\n * @param {DefaultsOptions=} opt_options Defaults options.\n * @return {import("./Collection.js").default<import("./interaction/Interaction.js").default>}\n * A collection of interactions to be used with the {@link module:ol/Map~Map}\n * constructor\'s `interactions` option.\n * @api\n */\n\nfunction interaction_defaults(opt_options) {\n var options = opt_options ? opt_options : {};\n var interactions = new ol_Collection();\n var kinetic = new ol_Kinetic(-0.005, 0.05, 100);\n var altShiftDragRotate = options.altShiftDragRotate !== undefined ? options.altShiftDragRotate : true;\n\n if (altShiftDragRotate) {\n interactions.push(new interaction_DragRotate());\n }\n\n var doubleClickZoom = options.doubleClickZoom !== undefined ? options.doubleClickZoom : true;\n\n if (doubleClickZoom) {\n interactions.push(new interaction_DoubleClickZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration\n }));\n }\n\n var dragPan = options.dragPan !== undefined ? options.dragPan : true;\n\n if (dragPan) {\n interactions.push(new interaction_DragPan({\n onFocusOnly: options.onFocusOnly,\n kinetic: kinetic\n }));\n }\n\n var pinchRotate = options.pinchRotate !== undefined ? options.pinchRotate : true;\n\n if (pinchRotate) {\n interactions.push(new interaction_PinchRotate());\n }\n\n var pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;\n\n if (pinchZoom) {\n interactions.push(new interaction_PinchZoom({\n duration: options.zoomDuration\n }));\n }\n\n var keyboard = options.keyboard !== undefined ? options.keyboard : true;\n\n if (keyboard) {\n interactions.push(new interaction_KeyboardPan());\n interactions.push(new interaction_KeyboardZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration\n }));\n }\n\n var mouseWheelZoom = options.mouseWheelZoom !== undefined ? options.mouseWheelZoom : true;\n\n if (mouseWheelZoom) {\n interactions.push(new interaction_MouseWheelZoom({\n onFocusOnly: options.onFocusOnly,\n duration: options.zoomDuration\n }));\n }\n\n var shiftDragZoom = options.shiftDragZoom !== undefined ? options.shiftDragZoom : true;\n\n if (shiftDragZoom) {\n interactions.push(new interaction_DragZoom({\n duration: options.zoomDuration\n }));\n }\n\n return interactions;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/Map.js\nvar ol_Map_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Map\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * The map is the core component of OpenLayers. For a map to render, a view,\n * one or more layers, and a target container are needed:\n *\n * import Map from \'ol/Map\';\n * import View from \'ol/View\';\n * import TileLayer from \'ol/layer/Tile\';\n * import OSM from \'ol/source/OSM\';\n *\n * var map = new Map({\n * view: new View({\n * center: [0, 0],\n * zoom: 1\n * }),\n * layers: [\n * new TileLayer({\n * source: new OSM()\n * })\n * ],\n * target: \'map\'\n * });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~Group}\n * is a subclass of {@link module:ol/layer/Base}, so layers entered in the\n * options or added with `addLayer` can be groups, which can contain further\n * groups, and so on.\n *\n * @api\n */\n\nvar Map_Map =\n/** @class */\nfunction (_super) {\n ol_Map_extends(Map, _super);\n /**\n * @param {import("./PluggableMap.js").MapOptions} options Map options.\n */\n\n\n function Map(options) {\n var _this = this;\n\n options = obj_assign({}, options);\n\n if (!options.controls) {\n options.controls = defaults();\n }\n\n if (!options.interactions) {\n options.interactions = interaction_defaults({\n onFocusOnly: true\n });\n }\n\n _this = _super.call(this, options) || this;\n return _this;\n }\n\n Map.prototype.createRenderer = function () {\n return new Composite(this);\n };\n\n return Map;\n}(ol_PluggableMap);\n\n/* harmony default export */ var ol_Map = (Map_Map);\n// EXTERNAL MODULE: ./node_modules/rbush/rbush.min.js\nvar rbush_min = __webpack_require__(5792);\nvar rbush_min_default = /*#__PURE__*/__webpack_require__.n(rbush_min);\n;// CONCATENATED MODULE: ./node_modules/ol/ImageState.js\n/**\n * @module ol/ImageState\n */\n\n/**\n * @enum {number}\n */\n/* harmony default export */ var ImageState = ({\n IDLE: 0,\n LOADING: 1,\n LOADED: 2,\n ERROR: 3,\n EMPTY: 4\n});\n;// CONCATENATED MODULE: ./node_modules/ol/style/Image.js\n/**\n * @module ol/style/Image\n */\n\n\n/**\n * @typedef {Object} Options\n * @property {number} opacity\n * @property {boolean} rotateWithView\n * @property {number} rotation\n * @property {number|import("../size.js").Size} scale\n * @property {Array<number>} displacement\n */\n\n/**\n * @classdesc\n * A base class used for creating subclasses and not instantiated in\n * apps. Base class for {@link module:ol/style/Icon~Icon}, {@link module:ol/style/Circle~CircleStyle} and\n * {@link module:ol/style/RegularShape~RegularShape}.\n * @abstract\n * @api\n */\n\nvar ImageStyle =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Options.\n */\n function ImageStyle(options) {\n /**\n * @private\n * @type {number}\n */\n this.opacity_ = options.opacity;\n /**\n * @private\n * @type {boolean}\n */\n\n this.rotateWithView_ = options.rotateWithView;\n /**\n * @private\n * @type {number}\n */\n\n this.rotation_ = options.rotation;\n /**\n * @private\n * @type {number|import("../size.js").Size}\n */\n\n this.scale_ = options.scale;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n this.scaleArray_ = toSize(options.scale);\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.displacement_ = options.displacement;\n }\n /**\n * Clones the style.\n * @return {ImageStyle} The cloned style.\n * @api\n */\n\n\n ImageStyle.prototype.clone = function () {\n var scale = this.getScale();\n return new ImageStyle({\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice()\n });\n };\n /**\n * Get the symbolizer opacity.\n * @return {number} Opacity.\n * @api\n */\n\n\n ImageStyle.prototype.getOpacity = function () {\n return this.opacity_;\n };\n /**\n * Determine whether the symbolizer rotates with the map.\n * @return {boolean} Rotate with map.\n * @api\n */\n\n\n ImageStyle.prototype.getRotateWithView = function () {\n return this.rotateWithView_;\n };\n /**\n * Get the symoblizer rotation.\n * @return {number} Rotation.\n * @api\n */\n\n\n ImageStyle.prototype.getRotation = function () {\n return this.rotation_;\n };\n /**\n * Get the symbolizer scale.\n * @return {number|import("../size.js").Size} Scale.\n * @api\n */\n\n\n ImageStyle.prototype.getScale = function () {\n return this.scale_;\n };\n /**\n * Get the symbolizer scale array.\n * @return {import("../size.js").Size} Scale array.\n */\n\n\n ImageStyle.prototype.getScaleArray = function () {\n return this.scaleArray_;\n };\n /**\n * Get the displacement of the shape\n * @return {Array<number>} Shape\'s center displacement\n * @api\n */\n\n\n ImageStyle.prototype.getDisplacement = function () {\n return this.displacement_;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @abstract\n * @return {Array<number>} Anchor.\n */\n\n\n ImageStyle.prototype.getAnchor = function () {\n return util_abstract();\n };\n /**\n * Get the image element for the symbolizer.\n * @abstract\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n\n\n ImageStyle.prototype.getImage = function (pixelRatio) {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} Image element.\n */\n\n\n ImageStyle.prototype.getHitDetectionImage = function () {\n return util_abstract();\n };\n /*\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * */\n\n\n ImageStyle.prototype.getPixelRatio = function (pixelRatio) {\n return 1;\n };\n /**\n * @abstract\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n ImageStyle.prototype.getImageState = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {import("../size.js").Size} Image size.\n */\n\n\n ImageStyle.prototype.getImageSize = function () {\n return util_abstract();\n };\n /**\n * @abstract\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n ImageStyle.prototype.getHitDetectionImageSize = function () {\n return util_abstract();\n };\n /**\n * Get the origin of the symbolizer.\n * @abstract\n * @return {Array<number>} Origin.\n */\n\n\n ImageStyle.prototype.getOrigin = function () {\n return util_abstract();\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @abstract\n * @return {import("../size.js").Size} Size.\n */\n\n\n ImageStyle.prototype.getSize = function () {\n return util_abstract();\n };\n /**\n * Set the opacity.\n *\n * @param {number} opacity Opacity.\n * @api\n */\n\n\n ImageStyle.prototype.setOpacity = function (opacity) {\n this.opacity_ = opacity;\n };\n /**\n * Set whether to rotate the style with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n\n\n ImageStyle.prototype.setRotateWithView = function (rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n };\n /**\n * Set the rotation.\n *\n * @param {number} rotation Rotation.\n * @api\n */\n\n\n ImageStyle.prototype.setRotation = function (rotation) {\n this.rotation_ = rotation;\n };\n /**\n * Set the scale.\n *\n * @param {number|import("../size.js").Size} scale Scale.\n * @api\n */\n\n\n ImageStyle.prototype.setScale = function (scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale);\n };\n /**\n * @abstract\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n ImageStyle.prototype.listenImageChange = function (listener) {\n util_abstract();\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n\n\n ImageStyle.prototype.load = function () {\n util_abstract();\n };\n /**\n * @abstract\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n ImageStyle.prototype.unlistenImageChange = function (listener) {\n util_abstract();\n };\n\n return ImageStyle;\n}();\n\n/* harmony default export */ var style_Image = (ImageStyle);\n;// CONCATENATED MODULE: ./node_modules/ol/colorlike.js\n/**\n * @module ol/colorlike\n */\n\n/**\n * A type accepted by CanvasRenderingContext2D.fillStyle\n * or CanvasRenderingContext2D.strokeStyle.\n * Represents a color, pattern, or gradient. The origin for patterns and\n * gradients as fill style is an increment of 512 css pixels from map coordinate\n * `[0, 0]`. For seamless repeat patterns, width and height of the pattern image\n * must be a factor of two (2, 4, 8, ..., 512).\n *\n * @typedef {string|CanvasPattern|CanvasGradient} ColorLike\n * @api\n */\n\n/**\n * @param {import("./color.js").Color|ColorLike} color Color.\n * @return {ColorLike} The color as an {@link ol/colorlike~ColorLike}.\n * @api\n */\n\nfunction asColorLike(color) {\n if (Array.isArray(color)) {\n return color_toString(color);\n } else {\n return color;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/style/RegularShape.js\n/**\n * @module ol/style/RegularShape\n */\nvar RegularShape_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n/**\n * Specify radius for regular polygons, or radius1 and radius2 for stars.\n * @typedef {Object} Options\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {number} points Number of points for stars and regular polygons. In case of a polygon, the number of points\n * is the number of sides.\n * @property {number} [radius] Radius of a regular polygon.\n * @property {number} [radius1] Outer radius of a star.\n * @property {number} [radius2] Inner radius of a star.\n * @property {number} [angle=0] Shape\'s angle in radians. A value of 0 will have one of the shape\'s point facing up.\n * @property {Array<number>} [displacement=[0,0]] Displacement of the shape\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view.\n * @property {number|import("../size.js").Size} [scale=1] Scale. Unless two dimensional scaling is required a better\n * result may be obtained with appropriate settings for `radius`, `radius1` and `radius2`.\n */\n\n/**\n * @typedef {Object} RenderOptions\n * @property {import("../colorlike.js").ColorLike} [strokeStyle]\n * @property {number} strokeWidth\n * @property {number} size\n * @property {CanvasLineCap} lineCap\n * @property {Array<number>} lineDash\n * @property {number} lineDashOffset\n * @property {CanvasLineJoin} lineJoin\n * @property {number} miterLimit\n */\n\n/**\n * @classdesc\n * Set regular shape style for vector features. The resulting shape will be\n * a regular polygon when `radius` is provided, or a star when `radius1` and\n * `radius2` are provided.\n * @api\n */\n\nvar RegularShape =\n/** @class */\nfunction (_super) {\n RegularShape_extends(RegularShape, _super);\n /**\n * @param {Options} options Options.\n */\n\n\n function RegularShape(options) {\n var _this = this;\n /**\n * @type {boolean}\n */\n\n\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: 1,\n rotateWithView: rotateWithView,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n scale: options.scale !== undefined ? options.scale : 1,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0]\n }) || this;\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n\n _this.canvas_ = {};\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n\n _this.hitDetectionCanvas_ = null;\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n _this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.origin_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n\n _this.points_ = options.points;\n /**\n * @protected\n * @type {number}\n */\n\n _this.radius_ = options.radius !== undefined ? options.radius : options.radius1;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.radius2_ = options.radius2;\n /**\n * @private\n * @type {number}\n */\n\n _this.angle_ = options.angle !== undefined ? options.angle : 0;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n _this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.anchor_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.imageSize_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.hitDetectionImageSize_ = null;\n\n _this.render();\n\n return _this;\n }\n /**\n * Clones the style.\n * @return {RegularShape} The cloned style.\n * @api\n */\n\n\n RegularShape.prototype.clone = function () {\n var scale = this.getScale();\n var style = new RegularShape({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n points: this.getPoints(),\n radius: this.getRadius(),\n radius2: this.getRadius2(),\n angle: this.getAngle(),\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n displacement: this.getDisplacement().slice()\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n\n\n RegularShape.prototype.getAnchor = function () {\n return this.anchor_;\n };\n /**\n * Get the angle used in generating the shape.\n * @return {number} Shape\'s rotation in radians.\n * @api\n */\n\n\n RegularShape.prototype.getAngle = function () {\n return this.angle_;\n };\n /**\n * Get the fill style for the shape.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n RegularShape.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * @return {HTMLCanvasElement} Image element.\n */\n\n\n RegularShape.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionCanvas_) {\n var renderOptions = this.createRenderOptions();\n this.createHitDetectionCanvas_(renderOptions);\n }\n\n return this.hitDetectionCanvas_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n\n\n RegularShape.prototype.getImage = function (pixelRatio) {\n if (!this.canvas_[pixelRatio || 1]) {\n var renderOptions = this.createRenderOptions();\n var context = createCanvasContext2D(renderOptions.size * pixelRatio || 1, renderOptions.size * pixelRatio || 1);\n this.draw_(renderOptions, context, 0, 0, pixelRatio || 1);\n this.canvas_[pixelRatio || 1] = context.canvas;\n }\n\n return this.canvas_[pixelRatio || 1];\n };\n /*\n * Get the image pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * */\n\n\n RegularShape.prototype.getPixelRatio = function (pixelRatio) {\n return pixelRatio;\n };\n /**\n * @return {import("../size.js").Size} Image size.\n */\n\n\n RegularShape.prototype.getImageSize = function () {\n return this.imageSize_;\n };\n /**\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n RegularShape.prototype.getHitDetectionImageSize = function () {\n return this.hitDetectionImageSize_;\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n RegularShape.prototype.getImageState = function () {\n return ImageState.LOADED;\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n\n\n RegularShape.prototype.getOrigin = function () {\n return this.origin_;\n };\n /**\n * Get the number of points for generating the shape.\n * @return {number} Number of points for stars and regular polygons.\n * @api\n */\n\n\n RegularShape.prototype.getPoints = function () {\n return this.points_;\n };\n /**\n * Get the (primary) radius for the shape.\n * @return {number} Radius.\n * @api\n */\n\n\n RegularShape.prototype.getRadius = function () {\n return this.radius_;\n };\n /**\n * Get the secondary radius for the shape.\n * @return {number|undefined} Radius2.\n * @api\n */\n\n\n RegularShape.prototype.getRadius2 = function () {\n return this.radius2_;\n };\n /**\n * Get the size of the symbolizer (in pixels).\n * @return {import("../size.js").Size} Size.\n * @api\n */\n\n\n RegularShape.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * Get the stroke style for the shape.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n RegularShape.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n RegularShape.prototype.listenImageChange = function (listener) {};\n /**\n * Load not yet loaded URI.\n */\n\n\n RegularShape.prototype.load = function () {};\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n RegularShape.prototype.unlistenImageChange = function (listener) {};\n /**\n * @returns {RenderOptions} The render options\n * @protected\n */\n\n\n RegularShape.prototype.createRenderOptions = function () {\n var lineCap = defaultLineCap;\n var lineJoin = defaultLineJoin;\n var miterLimit = 0;\n var lineDash = null;\n var lineDashOffset = 0;\n var strokeStyle;\n var strokeWidth = 0;\n\n if (this.stroke_) {\n strokeStyle = this.stroke_.getColor();\n\n if (strokeStyle === null) {\n strokeStyle = defaultStrokeStyle;\n }\n\n strokeStyle = asColorLike(strokeStyle);\n strokeWidth = this.stroke_.getWidth();\n\n if (strokeWidth === undefined) {\n strokeWidth = defaultLineWidth;\n }\n\n lineDash = this.stroke_.getLineDash();\n lineDashOffset = this.stroke_.getLineDashOffset();\n lineJoin = this.stroke_.getLineJoin();\n\n if (lineJoin === undefined) {\n lineJoin = defaultLineJoin;\n }\n\n lineCap = this.stroke_.getLineCap();\n\n if (lineCap === undefined) {\n lineCap = defaultLineCap;\n }\n\n miterLimit = this.stroke_.getMiterLimit();\n\n if (miterLimit === undefined) {\n miterLimit = defaultMiterLimit;\n }\n }\n\n var size = 2 * (this.radius_ + strokeWidth) + 1;\n return {\n strokeStyle: strokeStyle,\n strokeWidth: strokeWidth,\n size: size,\n lineCap: lineCap,\n lineDash: lineDash,\n lineDashOffset: lineDashOffset,\n lineJoin: lineJoin,\n miterLimit: miterLimit\n };\n };\n /**\n * @protected\n */\n\n\n RegularShape.prototype.render = function () {\n var renderOptions = this.createRenderOptions();\n var context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.draw_(renderOptions, context, 0, 0, 1);\n this.canvas_ = {};\n this.canvas_[1] = context.canvas; // canvas.width and height are rounded to the closest integer\n\n var size = context.canvas.width;\n var imageSize = size;\n var displacement = this.getDisplacement();\n this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];\n this.createHitDetectionCanvas_(renderOptions);\n this.anchor_ = [size / 2 - displacement[0], size / 2 + displacement[1]];\n this.size_ = [size, size];\n this.imageSize_ = [imageSize, imageSize];\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The rendering context.\n * @param {number} x The origin for the symbol (x).\n * @param {number} y The origin for the symbol (y).\n * @param {number} pixelRatio The pixel ratio.\n */\n\n\n RegularShape.prototype.draw_ = function (renderOptions, context, x, y, pixelRatio) {\n var i, angle0, radiusC; // reset transform\n\n context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0); // then move to (x, y)\n\n context.translate(x, y);\n context.beginPath();\n var points = this.points_;\n\n if (points === Infinity) {\n context.arc(renderOptions.size / 2, renderOptions.size / 2, this.radius_, 0, 2 * Math.PI, true);\n } else {\n var radius2 = this.radius2_ !== undefined ? this.radius2_ : this.radius_;\n\n if (radius2 !== this.radius_) {\n points = 2 * points;\n }\n\n for (i = 0; i <= points; i++) {\n angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n radiusC = i % 2 === 0 ? this.radius_ : radius2;\n context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), renderOptions.size / 2 + radiusC * Math.sin(angle0));\n }\n }\n\n if (this.fill_) {\n var color = this.fill_.getColor();\n\n if (color === null) {\n color = defaultFillStyle;\n }\n\n context.fillStyle = asColorLike(color);\n context.fill();\n }\n\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n\n if (context.setLineDash && renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n\n context.lineCap = renderOptions.lineCap;\n context.lineJoin = renderOptions.lineJoin;\n context.miterLimit = renderOptions.miterLimit;\n context.stroke();\n }\n\n context.closePath();\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n */\n\n\n RegularShape.prototype.createHitDetectionCanvas_ = function (renderOptions) {\n this.hitDetectionCanvas_ = this.getImage(1);\n\n if (this.fill_) {\n var color = this.fill_.getColor(); // determine if fill is transparent (or pattern or gradient)\n\n var opacity = 0;\n\n if (typeof color === \'string\') {\n color = asArray(color);\n }\n\n if (color === null) {\n opacity = 1;\n } else if (Array.isArray(color)) {\n opacity = color.length === 4 ? color[3] : 1;\n }\n\n if (opacity === 0) {\n // if a transparent fill style is set, create an extra hit-detection image\n // with a default fill style\n var context = createCanvasContext2D(renderOptions.size, renderOptions.size);\n this.hitDetectionCanvas_ = context.canvas;\n this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);\n }\n }\n };\n /**\n * @private\n * @param {RenderOptions} renderOptions Render options.\n * @param {CanvasRenderingContext2D} context The context.\n * @param {number} x The origin for the symbol (x).\n * @param {number} y The origin for the symbol (y).\n */\n\n\n RegularShape.prototype.drawHitDetectionCanvas_ = function (renderOptions, context, x, y) {\n // move to (x, y)\n context.translate(x, y);\n context.beginPath();\n var points = this.points_;\n\n if (points === Infinity) {\n context.arc(renderOptions.size / 2, renderOptions.size / 2, this.radius_, 0, 2 * Math.PI, true);\n } else {\n var radius2 = this.radius2_ !== undefined ? this.radius2_ : this.radius_;\n\n if (radius2 !== this.radius_) {\n points = 2 * points;\n }\n\n var i = void 0,\n radiusC = void 0,\n angle0 = void 0;\n\n for (i = 0; i <= points; i++) {\n angle0 = i * 2 * Math.PI / points - Math.PI / 2 + this.angle_;\n radiusC = i % 2 === 0 ? this.radius_ : radius2;\n context.lineTo(renderOptions.size / 2 + radiusC * Math.cos(angle0), renderOptions.size / 2 + radiusC * Math.sin(angle0));\n }\n }\n\n context.fillStyle = defaultFillStyle;\n context.fill();\n\n if (this.stroke_) {\n context.strokeStyle = renderOptions.strokeStyle;\n context.lineWidth = renderOptions.strokeWidth;\n\n if (renderOptions.lineDash) {\n context.setLineDash(renderOptions.lineDash);\n context.lineDashOffset = renderOptions.lineDashOffset;\n }\n\n context.stroke();\n }\n\n context.closePath();\n };\n\n return RegularShape;\n}(style_Image);\n\n/* harmony default export */ var style_RegularShape = (RegularShape);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Circle.js\n/**\n * @module ol/style/Circle\n */\nvar Circle_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {number} radius Circle radius.\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {Array<number>} [displacement=[0,0]] displacement\n * @property {number|import("../size.js").Size} [scale=1] Scale. A two dimensional scale will produce an ellipse.\n * Unless two dimensional scaling is required a better result may be obtained with an appropriate setting for `radius`.\n * @property {number} [rotation=0] Rotation in radians\n * (positive rotation clockwise, meaningful only when used in conjunction with a two dimensional scale).\n * @property {boolean} [rotateWithView=false] Whether to rotate the shape with the view\n * (meaningful only when used in conjunction with a two dimensional scale).\n */\n\n/**\n * @classdesc\n * Set circle style for vector features.\n * @api\n */\n\nvar Circle_CircleStyle =\n/** @class */\nfunction (_super) {\n Circle_extends(CircleStyle, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function CircleStyle(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this, {\n points: Infinity,\n fill: options.fill,\n radius: options.radius,\n stroke: options.stroke,\n scale: options.scale !== undefined ? options.scale : 1,\n rotation: options.rotation !== undefined ? options.rotation : 0,\n rotateWithView: options.rotateWithView !== undefined ? options.rotateWithView : false,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0]\n }) || this;\n return _this;\n }\n /**\n * Clones the style.\n * @return {CircleStyle} The cloned style.\n * @api\n */\n\n\n CircleStyle.prototype.clone = function () {\n var scale = this.getScale();\n var style = new CircleStyle({\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n radius: this.getRadius(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n displacement: this.getDisplacement().slice()\n });\n style.setOpacity(this.getOpacity());\n return style;\n };\n /**\n * Set the circle radius.\n *\n * @param {number} radius Circle radius.\n * @api\n */\n\n\n CircleStyle.prototype.setRadius = function (radius) {\n this.radius_ = radius;\n this.render();\n };\n\n return CircleStyle;\n}(style_RegularShape);\n\n/* harmony default export */ var Circle = (Circle_CircleStyle);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Fill.js\n/**\n * @module ol/style/Fill\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color=null] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n */\n\n/**\n * @classdesc\n * Set fill style for vector features.\n * @api\n */\nvar Fill_Fill =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Options.\n */\n function Fill(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import("../color.js").Color|import("../colorlike.js").ColorLike}\n */\n\n this.color_ = options.color !== undefined ? options.color : null;\n }\n /**\n * Clones the style. The color is not cloned if it is an {@link module:ol/colorlike~ColorLike}.\n * @return {Fill} The cloned style.\n * @api\n */\n\n\n Fill.prototype.clone = function () {\n var color = this.getColor();\n return new Fill({\n color: Array.isArray(color) ? color.slice() : color || undefined\n });\n };\n /**\n * Get the fill color.\n * @return {import("../color.js").Color|import("../colorlike.js").ColorLike} Color.\n * @api\n */\n\n\n Fill.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Set the color.\n *\n * @param {import("../color.js").Color|import("../colorlike.js").ColorLike} color Color.\n * @api\n */\n\n\n Fill.prototype.setColor = function (color) {\n this.color_ = color;\n };\n\n return Fill;\n}();\n\n/* harmony default export */ var style_Fill = (Fill_Fill);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Stroke.js\n/**\n * @module ol/style/Stroke\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color] A color, gradient or pattern.\n * See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.\n * Default null; if null, the Canvas/renderer default black will be used.\n * @property {CanvasLineCap} [lineCap=\'round\'] Line cap style: `butt`, `round`, or `square`.\n * @property {CanvasLineJoin} [lineJoin=\'round\'] Line join style: `bevel`, `round`, or `miter`.\n * @property {Array<number>} [lineDash] Line dash pattern. Default is `null` (no dash).\n * Please note that Internet Explorer 10 and lower do not support the `setLineDash` method on\n * the `CanvasRenderingContext2D` and therefore this option will have no visual effect in these browsers.\n * @property {number} [lineDashOffset=0] Line dash offset.\n * @property {number} [miterLimit=10] Miter limit.\n * @property {number} [width] Width.\n */\n\n/**\n * @classdesc\n * Set stroke style for vector features.\n * Note that the defaults given are the Canvas defaults, which will be used if\n * option is not defined. The `get` functions return whatever was entered in\n * the options; they will not return the default.\n * @api\n */\nvar Stroke_Stroke =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Options.\n */\n function Stroke(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {import("../color.js").Color|import("../colorlike.js").ColorLike}\n */\n\n this.color_ = options.color !== undefined ? options.color : null;\n /**\n * @private\n * @type {CanvasLineCap|undefined}\n */\n\n this.lineCap_ = options.lineCap;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.lineDash_ = options.lineDash !== undefined ? options.lineDash : null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.lineDashOffset_ = options.lineDashOffset;\n /**\n * @private\n * @type {CanvasLineJoin|undefined}\n */\n\n this.lineJoin_ = options.lineJoin;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.miterLimit_ = options.miterLimit;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.width_ = options.width;\n }\n /**\n * Clones the style.\n * @return {Stroke} The cloned style.\n * @api\n */\n\n\n Stroke.prototype.clone = function () {\n var color = this.getColor();\n return new Stroke({\n color: Array.isArray(color) ? color.slice() : color || undefined,\n lineCap: this.getLineCap(),\n lineDash: this.getLineDash() ? this.getLineDash().slice() : undefined,\n lineDashOffset: this.getLineDashOffset(),\n lineJoin: this.getLineJoin(),\n miterLimit: this.getMiterLimit(),\n width: this.getWidth()\n });\n };\n /**\n * Get the stroke color.\n * @return {import("../color.js").Color|import("../colorlike.js").ColorLike} Color.\n * @api\n */\n\n\n Stroke.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the line cap type for the stroke.\n * @return {CanvasLineCap|undefined} Line cap.\n * @api\n */\n\n\n Stroke.prototype.getLineCap = function () {\n return this.lineCap_;\n };\n /**\n * Get the line dash style for the stroke.\n * @return {Array<number>} Line dash.\n * @api\n */\n\n\n Stroke.prototype.getLineDash = function () {\n return this.lineDash_;\n };\n /**\n * Get the line dash offset for the stroke.\n * @return {number|undefined} Line dash offset.\n * @api\n */\n\n\n Stroke.prototype.getLineDashOffset = function () {\n return this.lineDashOffset_;\n };\n /**\n * Get the line join type for the stroke.\n * @return {CanvasLineJoin|undefined} Line join.\n * @api\n */\n\n\n Stroke.prototype.getLineJoin = function () {\n return this.lineJoin_;\n };\n /**\n * Get the miter limit for the stroke.\n * @return {number|undefined} Miter limit.\n * @api\n */\n\n\n Stroke.prototype.getMiterLimit = function () {\n return this.miterLimit_;\n };\n /**\n * Get the stroke width.\n * @return {number|undefined} Width.\n * @api\n */\n\n\n Stroke.prototype.getWidth = function () {\n return this.width_;\n };\n /**\n * Set the color.\n *\n * @param {import("../color.js").Color|import("../colorlike.js").ColorLike} color Color.\n * @api\n */\n\n\n Stroke.prototype.setColor = function (color) {\n this.color_ = color;\n };\n /**\n * Set the line cap.\n *\n * @param {CanvasLineCap|undefined} lineCap Line cap.\n * @api\n */\n\n\n Stroke.prototype.setLineCap = function (lineCap) {\n this.lineCap_ = lineCap;\n };\n /**\n * Set the line dash.\n *\n * Please note that Internet Explorer 10 and lower [do not support][mdn] the\n * `setLineDash` method on the `CanvasRenderingContext2D` and therefore this\n * property will have no visual effect in these browsers.\n *\n * [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility\n *\n * @param {Array<number>} lineDash Line dash.\n * @api\n */\n\n\n Stroke.prototype.setLineDash = function (lineDash) {\n this.lineDash_ = lineDash;\n };\n /**\n * Set the line dash offset.\n *\n * @param {number|undefined} lineDashOffset Line dash offset.\n * @api\n */\n\n\n Stroke.prototype.setLineDashOffset = function (lineDashOffset) {\n this.lineDashOffset_ = lineDashOffset;\n };\n /**\n * Set the line join.\n *\n * @param {CanvasLineJoin|undefined} lineJoin Line join.\n * @api\n */\n\n\n Stroke.prototype.setLineJoin = function (lineJoin) {\n this.lineJoin_ = lineJoin;\n };\n /**\n * Set the miter limit.\n *\n * @param {number|undefined} miterLimit Miter limit.\n * @api\n */\n\n\n Stroke.prototype.setMiterLimit = function (miterLimit) {\n this.miterLimit_ = miterLimit;\n };\n /**\n * Set the width.\n *\n * @param {number|undefined} width Width.\n * @api\n */\n\n\n Stroke.prototype.setWidth = function (width) {\n this.width_ = width;\n };\n\n return Stroke;\n}();\n\n/* harmony default export */ var style_Stroke = (Stroke_Stroke);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Style.js\n/**\n * @module ol/style/Style\n */\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Feature} and a `{number}`\n * representing the view\'s resolution. The function should return a\n * {@link module:ol/style/Style} or an array of them. This way e.g. a\n * vector layer can be styled. If the function returns `undefined`, the\n * feature will not be rendered.\n *\n * @typedef {function(import("../Feature.js").FeatureLike, number):(Style|Array<Style>|void)} StyleFunction\n */\n\n/**\n * A {@link Style}, an array of {@link Style}, or a {@link StyleFunction}.\n * @typedef {Style|Array<Style>|StyleFunction} StyleLike\n */\n\n/**\n * A function that takes an {@link module:ol/Feature} as argument and returns an\n * {@link module:ol/geom/Geometry} that will be rendered and styled for the feature.\n *\n * @typedef {function(import("../Feature.js").FeatureLike):\n * (import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined)} GeometryFunction\n */\n\n/**\n * Custom renderer function. Takes two arguments:\n *\n * 1. The pixel coordinates of the geometry in GeoJSON notation.\n * 2. The {@link module:ol/render~State} of the layer renderer.\n *\n * @typedef {function((import("../coordinate.js").Coordinate|Array<import("../coordinate.js").Coordinate>|Array<Array<import("../coordinate.js").Coordinate>>),import("../render.js").State): void}\n * RenderFunction\n */\n\n/**\n * @typedef {Object} Options\n * @property {string|import("../geom/Geometry.js").default|GeometryFunction} [geometry] Feature property or geometry\n * or function returning a geometry to render for this style.\n * @property {import("./Fill.js").default} [fill] Fill style.\n * @property {import("./Image.js").default} [image] Image style.\n * @property {RenderFunction} [renderer] Custom renderer. When configured, `fill`, `stroke` and `image` will be\n * ignored, and the provided function will be called with each render frame for each geometry.\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {import("./Text.js").default} [text] Text style.\n * @property {number} [zIndex] Z index.\n */\n\n/**\n * @classdesc\n * Container for vector feature rendering styles. Any changes made to the style\n * or its children through `set*()` methods will not take effect until the\n * feature or layer that uses the style is re-rendered.\n *\n * ## Feature styles\n *\n * If no style is defined, the following default style is used:\n * ```js\n * import {Fill, Stroke, Circle, Style} from \'ol/style\';\n *\n * var fill = new Fill({\n * color: \'rgba(255,255,255,0.4)\'\n * });\n * var stroke = new Stroke({\n * color: \'#3399CC\',\n * width: 1.25\n * });\n * var styles = [\n * new Style({\n * image: new Circle({\n * fill: fill,\n * stroke: stroke,\n * radius: 5\n * }),\n * fill: fill,\n * stroke: stroke\n * })\n * ];\n * ```\n *\n * A separate editing style has the following defaults:\n * ```js\n * import {Fill, Stroke, Circle, Style} from \'ol/style\';\n * import GeometryType from \'ol/geom/GeometryType\';\n *\n * var white = [255, 255, 255, 1];\n * var blue = [0, 153, 255, 1];\n * var width = 3;\n * styles[GeometryType.POLYGON] = [\n * new Style({\n * fill: new Fill({\n * color: [255, 255, 255, 0.5]\n * })\n * })\n * ];\n * styles[GeometryType.MULTI_POLYGON] =\n * styles[GeometryType.POLYGON];\n * styles[GeometryType.LINE_STRING] = [\n * new Style({\n * stroke: new Stroke({\n * color: white,\n * width: width + 2\n * })\n * }),\n * new Style({\n * stroke: new Stroke({\n * color: blue,\n * width: width\n * })\n * })\n * ];\n * styles[GeometryType.MULTI_LINE_STRING] =\n * styles[GeometryType.LINE_STRING];\n * styles[GeometryType.POINT] = [\n * new Style({\n * image: new Circle({\n * radius: width * 2,\n * fill: new Fill({\n * color: blue\n * }),\n * stroke: new Stroke({\n * color: white,\n * width: width / 2\n * })\n * }),\n * zIndex: Infinity\n * })\n * ];\n * styles[GeometryType.MULTI_POINT] =\n * styles[GeometryType.POINT];\n * styles[GeometryType.GEOMETRY_COLLECTION] =\n * styles[GeometryType.POLYGON].concat(\n * styles[GeometryType.LINE_STRING],\n * styles[GeometryType.POINT]\n * );\n * ```\n *\n * @api\n */\n\nvar Style =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Style options.\n */\n function Style(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {string|import("../geom/Geometry.js").default|GeometryFunction}\n */\n\n this.geometry_ = null;\n /**\n * @private\n * @type {!GeometryFunction}\n */\n\n this.geometryFunction_ = defaultGeometryFunction;\n\n if (options.geometry !== undefined) {\n this.setGeometry(options.geometry);\n }\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n\n this.fill_ = options.fill !== undefined ? options.fill : null;\n /**\n * @private\n * @type {import("./Image.js").default}\n */\n\n this.image_ = options.image !== undefined ? options.image : null;\n /**\n * @private\n * @type {RenderFunction|null}\n */\n\n this.renderer_ = options.renderer !== undefined ? options.renderer : null;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {import("./Text.js").default}\n */\n\n this.text_ = options.text !== undefined ? options.text : null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.zIndex_ = options.zIndex;\n }\n /**\n * Clones the style.\n * @return {Style} The cloned style.\n * @api\n */\n\n\n Style.prototype.clone = function () {\n var geometry = this.getGeometry();\n\n if (geometry && typeof geometry === \'object\') {\n geometry =\n /** @type {import("../geom/Geometry.js").default} */\n geometry.clone();\n }\n\n return new Style({\n geometry: geometry,\n fill: this.getFill() ? this.getFill().clone() : undefined,\n image: this.getImage() ? this.getImage().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n text: this.getText() ? this.getText().clone() : undefined,\n zIndex: this.getZIndex()\n });\n };\n /**\n * Get the custom renderer function that was configured with\n * {@link #setRenderer} or the `renderer` constructor option.\n * @return {RenderFunction|null} Custom renderer function.\n * @api\n */\n\n\n Style.prototype.getRenderer = function () {\n return this.renderer_;\n };\n /**\n * Sets a custom renderer function for this style. When set, `fill`, `stroke`\n * and `image` options of the style will be ignored.\n * @param {RenderFunction|null} renderer Custom renderer function.\n * @api\n */\n\n\n Style.prototype.setRenderer = function (renderer) {\n this.renderer_ = renderer;\n };\n /**\n * Get the geometry to be rendered.\n * @return {string|import("../geom/Geometry.js").default|GeometryFunction}\n * Feature property or geometry or function that returns the geometry that will\n * be rendered with this style.\n * @api\n */\n\n\n Style.prototype.getGeometry = function () {\n return this.geometry_;\n };\n /**\n * Get the function used to generate a geometry for rendering.\n * @return {!GeometryFunction} Function that is called with a feature\n * and returns the geometry to render instead of the feature\'s geometry.\n * @api\n */\n\n\n Style.prototype.getGeometryFunction = function () {\n return this.geometryFunction_;\n };\n /**\n * Get the fill style.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n Style.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Set the fill style.\n * @param {import("./Fill.js").default} fill Fill style.\n * @api\n */\n\n\n Style.prototype.setFill = function (fill) {\n this.fill_ = fill;\n };\n /**\n * Get the image style.\n * @return {import("./Image.js").default} Image style.\n * @api\n */\n\n\n Style.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Set the image style.\n * @param {import("./Image.js").default} image Image style.\n * @api\n */\n\n\n Style.prototype.setImage = function (image) {\n this.image_ = image;\n };\n /**\n * Get the stroke style.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n Style.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Set the stroke style.\n * @param {import("./Stroke.js").default} stroke Stroke style.\n * @api\n */\n\n\n Style.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n };\n /**\n * Get the text style.\n * @return {import("./Text.js").default} Text style.\n * @api\n */\n\n\n Style.prototype.getText = function () {\n return this.text_;\n };\n /**\n * Set the text style.\n * @param {import("./Text.js").default} text Text style.\n * @api\n */\n\n\n Style.prototype.setText = function (text) {\n this.text_ = text;\n };\n /**\n * Get the z-index for the style.\n * @return {number|undefined} ZIndex.\n * @api\n */\n\n\n Style.prototype.getZIndex = function () {\n return this.zIndex_;\n };\n /**\n * Set a geometry that is rendered instead of the feature\'s geometry.\n *\n * @param {string|import("../geom/Geometry.js").default|GeometryFunction} geometry\n * Feature property or geometry or function returning a geometry to render\n * for this style.\n * @api\n */\n\n\n Style.prototype.setGeometry = function (geometry) {\n if (typeof geometry === \'function\') {\n this.geometryFunction_ = geometry;\n } else if (typeof geometry === \'string\') {\n this.geometryFunction_ = function (feature) {\n return (\n /** @type {import("../geom/Geometry.js").default} */\n feature.get(geometry)\n );\n };\n } else if (!geometry) {\n this.geometryFunction_ = defaultGeometryFunction;\n } else if (geometry !== undefined) {\n this.geometryFunction_ = function () {\n return (\n /** @type {import("../geom/Geometry.js").default} */\n geometry\n );\n };\n }\n\n this.geometry_ = geometry;\n };\n /**\n * Set the z-index.\n *\n * @param {number|undefined} zIndex ZIndex.\n * @api\n */\n\n\n Style.prototype.setZIndex = function (zIndex) {\n this.zIndex_ = zIndex;\n };\n\n return Style;\n}();\n/**\n * Convert the provided object into a style function. Functions passed through\n * unchanged. Arrays of Style or single style objects wrapped in a\n * new style function.\n * @param {StyleFunction|Array<Style>|Style} obj\n * A style function, a single style, or an array of styles.\n * @return {StyleFunction} A style function.\n */\n\n\nfunction toFunction(obj) {\n var styleFunction;\n\n if (typeof obj === \'function\') {\n styleFunction = obj;\n } else {\n /**\n * @type {Array<Style>}\n */\n var styles_1;\n\n if (Array.isArray(obj)) {\n styles_1 = obj;\n } else {\n asserts_assert(typeof\n /** @type {?} */\n obj.getZIndex === \'function\', 41); // Expected an `Style` or an array of `Style`\n\n var style =\n /** @type {Style} */\n obj;\n styles_1 = [style];\n }\n\n styleFunction = function styleFunction() {\n return styles_1;\n };\n }\n\n return styleFunction;\n}\n/**\n * @type {Array<Style>}\n */\n\nvar defaultStyles = null;\n/**\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {number} resolution Resolution.\n * @return {Array<Style>} Style.\n */\n\nfunction createDefaultStyle(feature, resolution) {\n // We don\'t use an immediately-invoked function\n // and a closure so we don\'t get an error at script evaluation time in\n // browsers that do not support Canvas. (import("./Circle.js").CircleStyle does\n // canvas.getContext(\'2d\') at construction time, which will cause an.error\n // in such browsers.)\n if (!defaultStyles) {\n var fill = new style_Fill({\n color: \'rgba(255,255,255,0.4)\'\n });\n var stroke = new style_Stroke({\n color: \'#3399CC\',\n width: 1.25\n });\n defaultStyles = [new Style({\n image: new Circle({\n fill: fill,\n stroke: stroke,\n radius: 5\n }),\n fill: fill,\n stroke: stroke\n })];\n }\n\n return defaultStyles;\n}\n/**\n * Default styles for editing features.\n * @return {Object<import("../geom/GeometryType.js").default, Array<Style>>} Styles\n */\n\nfunction createEditingStyle() {\n /** @type {Object<import("../geom/GeometryType.js").default, Array<Style>>} */\n var styles = {};\n var white = [255, 255, 255, 1];\n var blue = [0, 153, 255, 1];\n var width = 3;\n styles[GeometryType.POLYGON] = [new Style({\n fill: new Fill({\n color: [255, 255, 255, 0.5]\n })\n })];\n styles[GeometryType.MULTI_POLYGON] = styles[GeometryType.POLYGON];\n styles[GeometryType.LINE_STRING] = [new Style({\n stroke: new Stroke({\n color: white,\n width: width + 2\n })\n }), new Style({\n stroke: new Stroke({\n color: blue,\n width: width\n })\n })];\n styles[GeometryType.MULTI_LINE_STRING] = styles[GeometryType.LINE_STRING];\n styles[GeometryType.CIRCLE] = styles[GeometryType.POLYGON].concat(styles[GeometryType.LINE_STRING]);\n styles[GeometryType.POINT] = [new Style({\n image: new CircleStyle({\n radius: width * 2,\n fill: new Fill({\n color: blue\n }),\n stroke: new Stroke({\n color: white,\n width: width / 2\n })\n }),\n zIndex: Infinity\n })];\n styles[GeometryType.MULTI_POINT] = styles[GeometryType.POINT];\n styles[GeometryType.GEOMETRY_COLLECTION] = styles[GeometryType.POLYGON].concat(styles[GeometryType.LINE_STRING], styles[GeometryType.POINT]);\n return styles;\n}\n/**\n * Function that is called with a feature and returns its default geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature to get the geometry for.\n * @return {import("../geom/Geometry.js").default|import("../render/Feature.js").default|undefined} Geometry to render.\n */\n\nfunction defaultGeometryFunction(feature) {\n return feature.getGeometry();\n}\n\n/* harmony default export */ var style_Style = (Style);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseVector.js\nvar BaseVector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/BaseVector\n */\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the\n * renderer when getting features from the vector source for the rendering or hit-detection.\n * Recommended value: the size of the largest symbol, line width or label.\n * @property {import("../source/Vector.js").default} [source] Source.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority\n * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.\n * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has\n * higher priority.\n * @property {import("../style/Style.js").StyleLike|null} [style] Layer style. When set to `null`, only\n * features that have their own style will be rendered. See {@link module:ol/style} for default style\n * which will be used if this is not set.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will\n * be recreated during animations. This means that no vectors will be shown clipped, but the\n * setting will have a performance impact for large amounts of vector data. When set to `false`,\n * batches will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will\n * be recreated during interactions. See also `updateWhileAnimating`.\n */\n\n/**\n * @enum {string}\n * @private\n */\n\nvar BaseVector_Property = {\n RENDER_ORDER: \'renderOrder\'\n};\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType\n * @extends {Layer<VectorSourceType>}\n * @api\n */\n\nvar BaseVectorLayer =\n/** @class */\nfunction (_super) {\n BaseVector_extends(BaseVectorLayer, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function BaseVectorLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions = obj_assign({}, options);\n delete baseOptions.style;\n delete baseOptions.renderBuffer;\n delete baseOptions.updateWhileAnimating;\n delete baseOptions.updateWhileInteracting;\n _this = _super.call(this, baseOptions) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.declutter_ = options.declutter !== undefined ? options.declutter : false;\n /**\n * @type {number}\n * @private\n */\n\n _this.renderBuffer_ = options.renderBuffer !== undefined ? options.renderBuffer : 100;\n /**\n * User provided style.\n * @type {import("../style/Style.js").StyleLike}\n * @private\n */\n\n _this.style_ = null;\n /**\n * Style function for use within the library.\n * @type {import("../style/Style.js").StyleFunction|undefined}\n * @private\n */\n\n _this.styleFunction_ = undefined;\n\n _this.setStyle(options.style);\n /**\n * @type {boolean}\n * @private\n */\n\n\n _this.updateWhileAnimating_ = options.updateWhileAnimating !== undefined ? options.updateWhileAnimating : false;\n /**\n * @type {boolean}\n * @private\n */\n\n _this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ? options.updateWhileInteracting : false;\n return _this;\n }\n /**\n * @return {boolean} Declutter.\n */\n\n\n BaseVectorLayer.prototype.getDeclutter = function () {\n return this.declutter_;\n };\n /**\n * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise\n * that resolves with an array of features. The array will either contain the topmost feature\n * when a hit was detected, or it will be empty.\n *\n * The hit detection algorithm used for this method is optimized for performance, but is less\n * accurate than the one used in {@link import("../PluggableMap.js").default#getFeaturesAtPixel}: Text\n * is not considered, and icons are only represented by their bounding box instead of the exact\n * image.\n *\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with an array of features.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getFeatures = function (pixel) {\n return _super.prototype.getFeatures.call(this, pixel);\n };\n /**\n * @return {number|undefined} Render buffer.\n */\n\n\n BaseVectorLayer.prototype.getRenderBuffer = function () {\n return this.renderBuffer_;\n };\n /**\n * @return {function(import("../Feature.js").default, import("../Feature.js").default): number|null|undefined} Render\n * order.\n */\n\n\n BaseVectorLayer.prototype.getRenderOrder = function () {\n return (\n /** @type {import("../render.js").OrderFunction|null|undefined} */\n this.get(BaseVector_Property.RENDER_ORDER)\n );\n };\n /**\n * Get the style for features. This returns whatever was passed to the `style`\n * option at construction or to the `setStyle` method.\n * @return {import("../style/Style.js").StyleLike|null|undefined} Layer style.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getStyle = function () {\n return this.style_;\n };\n /**\n * Get the style function.\n * @return {import("../style/Style.js").StyleFunction|undefined} Layer style function.\n * @api\n */\n\n\n BaseVectorLayer.prototype.getStyleFunction = function () {\n return this.styleFunction_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * animating.\n */\n\n\n BaseVectorLayer.prototype.getUpdateWhileAnimating = function () {\n return this.updateWhileAnimating_;\n };\n /**\n * @return {boolean} Whether the rendered layer should be updated while\n * interacting.\n */\n\n\n BaseVectorLayer.prototype.getUpdateWhileInteracting = function () {\n return this.updateWhileInteracting_;\n };\n /**\n * Render declutter items for this layer\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n BaseVectorLayer.prototype.renderDeclutter = function (frameState) {\n if (!frameState.declutterTree) {\n frameState.declutterTree = new (rbush_min_default())(9);\n }\n /** @type {*} */\n\n\n this.getRenderer().renderDeclutter(frameState);\n };\n /**\n * @param {import("../render.js").OrderFunction|null|undefined} renderOrder\n * Render order.\n */\n\n\n BaseVectorLayer.prototype.setRenderOrder = function (renderOrder) {\n this.set(BaseVector_Property.RENDER_ORDER, renderOrder);\n };\n /**\n * Set the style for features. This can be a single style object, an array\n * of styles, or a function that takes a feature and resolution and returns\n * an array of styles. If set to `null`, the layer has no style (a `null` style),\n * so only features that have their own styles will be rendered in the layer. Call\n * `setStyle()` without arguments to reset to the default style. See\n * {@link module:ol/style} for information on the default style.\n * @param {(import("../style/Style.js").StyleLike|null)=} opt_style Layer style.\n * @api\n */\n\n\n BaseVectorLayer.prototype.setStyle = function (opt_style) {\n this.style_ = opt_style !== undefined ? opt_style : createDefaultStyle;\n this.styleFunction_ = opt_style === null ? undefined : toFunction(this.style_);\n this.changed();\n };\n\n return BaseVectorLayer;\n}(layer_Layer);\n\n/* harmony default export */ var BaseVector = (BaseVectorLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Instruction.js\n/**\n * @module ol/render/canvas/Instruction\n */\n\n/**\n * @enum {number}\n */\nvar Instruction = {\n BEGIN_GEOMETRY: 0,\n BEGIN_PATH: 1,\n CIRCLE: 2,\n CLOSE_PATH: 3,\n CUSTOM: 4,\n DRAW_CHARS: 5,\n DRAW_IMAGE: 6,\n END_GEOMETRY: 7,\n FILL: 8,\n MOVE_TO_LINE_TO: 9,\n SET_FILL_STYLE: 10,\n SET_STROKE_STYLE: 11,\n STROKE: 12\n};\n/**\n * @type {Array<Instruction>}\n */\n\nvar fillInstruction = [Instruction.FILL];\n/**\n * @type {Array<Instruction>}\n */\n\nvar strokeInstruction = [Instruction.STROKE];\n/**\n * @type {Array<Instruction>}\n */\n\nvar beginPathInstruction = [Instruction.BEGIN_PATH];\n/**\n * @type {Array<Instruction>}\n */\n\nvar closePathInstruction = [Instruction.CLOSE_PATH];\n/* harmony default export */ var canvas_Instruction = (Instruction);\n;// CONCATENATED MODULE: ./node_modules/ol/render/VectorContext.js\n/**\n * @module ol/render/VectorContext\n */\n\n/**\n * @classdesc\n * Context for drawing geometries. A vector context is available on render\n * events and does not need to be constructed directly.\n * @api\n */\nvar VectorContext =\n/** @class */\nfunction () {\n function VectorContext() {}\n /**\n * Render a geometry with a custom renderer.\n *\n * @param {import("../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n */\n\n\n VectorContext.prototype.drawCustom = function (geometry, feature, renderer) {};\n /**\n * Render a geometry.\n *\n * @param {import("../geom/Geometry.js").default} geometry The geometry to render.\n */\n\n\n VectorContext.prototype.drawGeometry = function (geometry) {};\n /**\n * Set the rendering style.\n *\n * @param {import("../style/Style.js").default} style The rendering style.\n */\n\n\n VectorContext.prototype.setStyle = function (style) {};\n /**\n * @param {import("../geom/Circle.js").default} circleGeometry Circle geometry.\n * @param {import("../Feature.js").default} feature Feature.\n */\n\n\n VectorContext.prototype.drawCircle = function (circleGeometry, feature) {};\n /**\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n */\n\n\n VectorContext.prototype.drawFeature = function (feature, style) {};\n /**\n * @param {import("../geom/GeometryCollection.js").default} geometryCollectionGeometry Geometry collection.\n * @param {import("../Feature.js").default} feature Feature.\n */\n\n\n VectorContext.prototype.drawGeometryCollection = function (geometryCollectionGeometry, feature) {};\n /**\n * @param {import("../geom/LineString.js").default|import("./Feature.js").default} lineStringGeometry Line string geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawLineString = function (lineStringGeometry, feature) {};\n /**\n * @param {import("../geom/MultiLineString.js").default|import("./Feature.js").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {};\n /**\n * @param {import("../geom/MultiPoint.js").default|import("./Feature.js").default} multiPointGeometry MultiPoint geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiPoint = function (multiPointGeometry, feature) {};\n /**\n * @param {import("../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) {};\n /**\n * @param {import("../geom/Point.js").default|import("./Feature.js").default} pointGeometry Point geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawPoint = function (pointGeometry, feature) {};\n /**\n * @param {import("../geom/Polygon.js").default|import("./Feature.js").default} polygonGeometry Polygon geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawPolygon = function (polygonGeometry, feature) {};\n /**\n * @param {import("../geom/SimpleGeometry.js").default|import("./Feature.js").default} geometry Geometry.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\n VectorContext.prototype.drawText = function (geometry, feature) {};\n /**\n * @param {import("../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n VectorContext.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {};\n /**\n * @param {import("../style/Image.js").default} imageStyle Image style.\n * @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with a text style.\n */\n\n\n VectorContext.prototype.setImageStyle = function (imageStyle, opt_declutterImageWithText) {};\n /**\n * @param {import("../style/Text.js").default} textStyle Text style.\n * @param {import("../render/canvas.js").DeclutterImageWithText=} opt_declutterImageWithText Shared data for combined decluttering with an image style.\n */\n\n\n VectorContext.prototype.setTextStyle = function (textStyle, opt_declutterImageWithText) {};\n\n return VectorContext;\n}();\n\n/* harmony default export */ var render_VectorContext = (VectorContext);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Builder.js\nvar Builder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/Builder\n */\n\n\n\n\n\n\n\n\n\n\n\n\nvar CanvasBuilder =\n/** @class */\nfunction (_super) {\n Builder_extends(CanvasBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {number}\n */\n\n\n _this.tolerance = tolerance;\n /**\n * @protected\n * @const\n * @type {import("../../extent.js").Extent}\n */\n\n _this.maxExtent = maxExtent;\n /**\n * @protected\n * @type {number}\n */\n\n _this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @type {number}\n */\n\n _this.maxLineWidth = 0;\n /**\n * @protected\n * @const\n * @type {number}\n */\n\n _this.resolution = resolution;\n /**\n * @private\n * @type {Array<*>}\n */\n\n _this.beginGeometryInstruction1_ = null;\n /**\n * @private\n * @type {Array<*>}\n */\n\n _this.beginGeometryInstruction2_ = null;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.bufferedMaxExtent_ = null;\n /**\n * @protected\n * @type {Array<*>}\n */\n\n _this.instructions = [];\n /**\n * @protected\n * @type {Array<number>}\n */\n\n _this.coordinates = [];\n /**\n * @private\n * @type {import("../../coordinate.js").Coordinate}\n */\n\n _this.tmpCoordinate_ = [];\n /**\n * @protected\n * @type {Array<*>}\n */\n\n _this.hitDetectionInstructions = [];\n /**\n * @protected\n * @type {import("../canvas.js").FillStrokeState}\n */\n\n _this.state =\n /** @type {import("../canvas.js").FillStrokeState} */\n {};\n return _this;\n }\n /**\n * @protected\n * @param {Array<number>} dashArray Dash array.\n * @return {Array<number>} Dash array with pixel ratio applied\n */\n\n\n CanvasBuilder.prototype.applyPixelRatio = function (dashArray) {\n var pixelRatio = this.pixelRatio;\n return pixelRatio == 1 ? dashArray : dashArray.map(function (dash) {\n return dash * pixelRatio;\n });\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} stride Stride.\n * @protected\n * @return {number} My end\n */\n\n\n CanvasBuilder.prototype.appendFlatPointCoordinates = function (flatCoordinates, stride) {\n var extent = this.getBufferedMaxExtent();\n var tmpCoord = this.tmpCoordinate_;\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n tmpCoord[0] = flatCoordinates[i];\n tmpCoord[1] = flatCoordinates[i + 1];\n\n if (containsCoordinate(extent, tmpCoord)) {\n coordinates[myEnd++] = tmpCoord[0];\n coordinates[myEnd++] = tmpCoord[1];\n }\n }\n\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} closed Last input coordinate equals first.\n * @param {boolean} skipFirst Skip first coordinate.\n * @protected\n * @return {number} My end.\n */\n\n\n CanvasBuilder.prototype.appendFlatLineCoordinates = function (flatCoordinates, offset, end, stride, closed, skipFirst) {\n var coordinates = this.coordinates;\n var myEnd = coordinates.length;\n var extent = this.getBufferedMaxExtent();\n\n if (skipFirst) {\n offset += stride;\n }\n\n var lastXCoord = flatCoordinates[offset];\n var lastYCoord = flatCoordinates[offset + 1];\n var nextCoord = this.tmpCoordinate_;\n var skipped = true;\n var i, lastRel, nextRel;\n\n for (i = offset + stride; i < end; i += stride) {\n nextCoord[0] = flatCoordinates[i];\n nextCoord[1] = flatCoordinates[i + 1];\n nextRel = coordinateRelationship(extent, nextCoord);\n\n if (nextRel !== lastRel) {\n if (skipped) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n skipped = false;\n }\n\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n } else if (nextRel === extent_Relationship.INTERSECTING) {\n coordinates[myEnd++] = nextCoord[0];\n coordinates[myEnd++] = nextCoord[1];\n skipped = false;\n } else {\n skipped = true;\n }\n\n lastXCoord = nextCoord[0];\n lastYCoord = nextCoord[1];\n lastRel = nextRel;\n } // Last coordinate equals first or only one point to append:\n\n\n if (closed && skipped || i === offset + stride) {\n coordinates[myEnd++] = lastXCoord;\n coordinates[myEnd++] = lastYCoord;\n }\n\n return myEnd;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {Array<number>} builderEnds Builder ends.\n * @return {number} Offset.\n */\n\n\n CanvasBuilder.prototype.drawCustomCoordinates_ = function (flatCoordinates, offset, ends, stride, builderEnds) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var builderEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n builderEnds.push(builderEnd);\n offset = end;\n }\n\n return offset;\n };\n /**\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {Function} renderer Renderer.\n */\n\n\n CanvasBuilder.prototype.drawCustom = function (geometry, feature, renderer) {\n this.beginGeometry(geometry, feature);\n var type = geometry.getType();\n var stride = geometry.getStride();\n var builderBegin = this.coordinates.length;\n var flatCoordinates, builderEnd, builderEnds, builderEndss;\n var offset;\n\n if (type == geom_GeometryType.MULTI_POLYGON) {\n flatCoordinates =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getOrientedFlatCoordinates();\n builderEndss = [];\n var endss =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getEndss();\n offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var myEnds = [];\n offset = this.drawCustomCoordinates_(flatCoordinates, offset, endss[i], stride, myEnds);\n builderEndss.push(myEnds);\n }\n\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEndss, geometry, renderer, inflateMultiCoordinatesArray]);\n } else if (type == geom_GeometryType.POLYGON || type == geom_GeometryType.MULTI_LINE_STRING) {\n builderEnds = [];\n flatCoordinates = type == geom_GeometryType.POLYGON ?\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getOrientedFlatCoordinates() : geometry.getFlatCoordinates();\n offset = this.drawCustomCoordinates_(flatCoordinates, 0,\n /** @type {import("../../geom/Polygon.js").default|import("../../geom/MultiLineString.js").default} */\n geometry.getEnds(), stride, builderEnds);\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnds, geometry, renderer, inflateCoordinatesArray]);\n } else if (type == geom_GeometryType.LINE_STRING || type == geom_GeometryType.CIRCLE) {\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates]);\n } else if (type == geom_GeometryType.MULTI_POINT) {\n flatCoordinates = geometry.getFlatCoordinates();\n builderEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n\n if (builderEnd > builderBegin) {\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer, inflateCoordinates]);\n }\n } else if (type == geom_GeometryType.POINT) {\n flatCoordinates = geometry.getFlatCoordinates();\n this.coordinates.push(flatCoordinates[0], flatCoordinates[1]);\n builderEnd = this.coordinates.length;\n this.instructions.push([canvas_Instruction.CUSTOM, builderBegin, builderEnd, geometry, renderer]);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @protected\n * @param {import("../../geom/Geometry").default|import("../Feature.js").default} geometry The geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasBuilder.prototype.beginGeometry = function (geometry, feature) {\n this.beginGeometryInstruction1_ = [canvas_Instruction.BEGIN_GEOMETRY, feature, 0, geometry];\n this.instructions.push(this.beginGeometryInstruction1_);\n this.beginGeometryInstruction2_ = [canvas_Instruction.BEGIN_GEOMETRY, feature, 0, geometry];\n this.hitDetectionInstructions.push(this.beginGeometryInstruction2_);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasBuilder.prototype.finish = function () {\n return {\n instructions: this.instructions,\n hitDetectionInstructions: this.hitDetectionInstructions,\n coordinates: this.coordinates\n };\n };\n /**\n * Reverse the hit detection instructions.\n */\n\n\n CanvasBuilder.prototype.reverseHitDetectionInstructions = function () {\n var hitDetectionInstructions = this.hitDetectionInstructions; // step 1 - reverse array\n\n hitDetectionInstructions.reverse(); // step 2 - reverse instructions within geometry blocks\n\n var i;\n var n = hitDetectionInstructions.length;\n var instruction;\n var type;\n var begin = -1;\n\n for (i = 0; i < n; ++i) {\n instruction = hitDetectionInstructions[i];\n type =\n /** @type {import("./Instruction.js").default} */\n instruction[0];\n\n if (type == canvas_Instruction.END_GEOMETRY) {\n begin = i;\n } else if (type == canvas_Instruction.BEGIN_GEOMETRY) {\n instruction[2] = i;\n reverseSubArray(this.hitDetectionInstructions, begin, i);\n begin = -1;\n }\n }\n };\n /**\n * @param {import("../../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n CanvasBuilder.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n var state = this.state;\n\n if (fillStyle) {\n var fillStyleColor = fillStyle.getColor();\n state.fillStyle = asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle);\n } else {\n state.fillStyle = undefined;\n }\n\n if (strokeStyle) {\n var strokeStyleColor = strokeStyle.getColor();\n state.strokeStyle = asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle);\n var strokeStyleLineCap = strokeStyle.getLineCap();\n state.lineCap = strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap;\n var strokeStyleLineDash = strokeStyle.getLineDash();\n state.lineDash = strokeStyleLineDash ? strokeStyleLineDash.slice() : defaultLineDash;\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n state.lineDashOffset = strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset;\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n state.lineJoin = strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : defaultLineJoin;\n var strokeStyleWidth = strokeStyle.getWidth();\n state.lineWidth = strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth;\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n state.miterLimit = strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : defaultMiterLimit;\n\n if (state.lineWidth > this.maxLineWidth) {\n this.maxLineWidth = state.lineWidth; // invalidate the buffered max extent cache\n\n this.bufferedMaxExtent_ = null;\n }\n } else {\n state.strokeStyle = undefined;\n state.lineCap = undefined;\n state.lineDash = null;\n state.lineDashOffset = undefined;\n state.lineJoin = undefined;\n state.lineWidth = undefined;\n state.miterLimit = undefined;\n }\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @return {Array<*>} Fill instruction.\n */\n\n\n CanvasBuilder.prototype.createFill = function (state) {\n var fillStyle = state.fillStyle;\n /** @type {Array<*>} */\n\n var fillInstruction = [canvas_Instruction.SET_FILL_STYLE, fillStyle];\n\n if (typeof fillStyle !== \'string\') {\n // Fill is a pattern or gradient - align it!\n fillInstruction.push(true);\n }\n\n return fillInstruction;\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n */\n\n\n CanvasBuilder.prototype.applyStroke = function (state) {\n this.instructions.push(this.createStroke(state));\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @return {Array<*>} Stroke instruction.\n */\n\n\n CanvasBuilder.prototype.createStroke = function (state) {\n return [canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth * this.pixelRatio, state.lineCap, state.lineJoin, state.miterLimit, this.applyPixelRatio(state.lineDash), state.lineDashOffset * this.pixelRatio];\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState):Array<*>} createFill Create fill.\n */\n\n\n CanvasBuilder.prototype.updateFillStyle = function (state, createFill) {\n var fillStyle = state.fillStyle;\n\n if (typeof fillStyle !== \'string\' || state.currentFillStyle != fillStyle) {\n if (fillStyle !== undefined) {\n this.instructions.push(createFill.call(this, state));\n }\n\n state.currentFillStyle = fillStyle;\n }\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n * @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState): void} applyStroke Apply stroke.\n */\n\n\n CanvasBuilder.prototype.updateStrokeStyle = function (state, applyStroke) {\n var strokeStyle = state.strokeStyle;\n var lineCap = state.lineCap;\n var lineDash = state.lineDash;\n var lineDashOffset = state.lineDashOffset;\n var lineJoin = state.lineJoin;\n var lineWidth = state.lineWidth;\n var miterLimit = state.miterLimit;\n\n if (state.currentStrokeStyle != strokeStyle || state.currentLineCap != lineCap || lineDash != state.currentLineDash && !equals(state.currentLineDash, lineDash) || state.currentLineDashOffset != lineDashOffset || state.currentLineJoin != lineJoin || state.currentLineWidth != lineWidth || state.currentMiterLimit != miterLimit) {\n if (strokeStyle !== undefined) {\n applyStroke.call(this, state);\n }\n\n state.currentStrokeStyle = strokeStyle;\n state.currentLineCap = lineCap;\n state.currentLineDash = lineDash;\n state.currentLineDashOffset = lineDashOffset;\n state.currentLineJoin = lineJoin;\n state.currentLineWidth = lineWidth;\n state.currentMiterLimit = miterLimit;\n }\n };\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasBuilder.prototype.endGeometry = function (feature) {\n this.beginGeometryInstruction1_[2] = this.instructions.length;\n this.beginGeometryInstruction1_ = null;\n this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;\n this.beginGeometryInstruction2_ = null;\n var endGeometryInstruction = [canvas_Instruction.END_GEOMETRY, feature];\n this.instructions.push(endGeometryInstruction);\n this.hitDetectionInstructions.push(endGeometryInstruction);\n };\n /**\n * Get the buffered rendering extent. Rendering will be clipped to the extent\n * provided to the constructor. To account for symbolizers that may intersect\n * this extent, we calculate a buffered extent (e.g. based on stroke width).\n * @return {import("../../extent.js").Extent} The buffered rendering extent.\n * @protected\n */\n\n\n CanvasBuilder.prototype.getBufferedMaxExtent = function () {\n if (!this.bufferedMaxExtent_) {\n this.bufferedMaxExtent_ = clone(this.maxExtent);\n\n if (this.maxLineWidth > 0) {\n var width = this.resolution * (this.maxLineWidth + 1) / 2;\n buffer(this.bufferedMaxExtent_, width, this.bufferedMaxExtent_);\n }\n }\n\n return this.bufferedMaxExtent_;\n };\n\n return CanvasBuilder;\n}(render_VectorContext);\n\n/* harmony default export */ var Builder = (CanvasBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ImageBuilder.js\nvar ImageBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/ImageBuilder\n */\n\n\n\n\n\nvar CanvasImageBuilder =\n/** @class */\nfunction (_super) {\n ImageBuilder_extends(CanvasImageBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasImageBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n _this.image_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.imagePixelRatio_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.anchorX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.anchorY_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.height_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.opacity_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.originX_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.originY_ = undefined;\n /**\n * @private\n * @type {boolean|undefined}\n */\n\n _this.rotateWithView_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.rotation_ = undefined;\n /**\n * @private\n * @type {import("../../size.js").Size|undefined}\n */\n\n _this.scale_ = undefined;\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.width_ = undefined;\n /**\n * Data shared with a text builder for combined decluttering.\n * @private\n * @type {import("../canvas.js").DeclutterImageWithText}\n */\n\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @param {import("../../geom/Point.js").default|import("../Feature.js").default} pointGeometry Point geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasImageBuilder.prototype.drawPoint = function (pointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n\n this.beginGeometry(pointGeometry, feature);\n var flatCoordinates = pointGeometry.getFlatCoordinates();\n var stride = pointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, [this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterImageWithText_]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_, this.anchorY_, this.height_, this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterImageWithText_]);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} multiPointGeometry MultiPoint geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasImageBuilder.prototype.drawMultiPoint = function (multiPointGeometry, feature) {\n if (!this.image_) {\n return;\n }\n\n this.beginGeometry(multiPointGeometry, feature);\n var flatCoordinates = multiPointGeometry.getFlatCoordinates();\n var stride = multiPointGeometry.getStride();\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatPointCoordinates(flatCoordinates, stride);\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.image_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_ * this.imagePixelRatio_, this.anchorY_ * this.imagePixelRatio_, Math.ceil(this.height_ * this.imagePixelRatio_), this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, [this.scale_[0] * this.pixelRatio / this.imagePixelRatio_, this.scale_[1] * this.pixelRatio / this.imagePixelRatio_], Math.ceil(this.width_ * this.imagePixelRatio_), this.declutterImageWithText_]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_, // Remaining arguments to DRAW_IMAGE are in alphabetical order\n this.anchorX_, this.anchorY_, this.height_, this.opacity_, this.originX_, this.originY_, this.rotateWithView_, this.rotation_, this.scale_, this.width_, this.declutterImageWithText_]);\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasImageBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions(); // FIXME this doesn\'t really protect us against further calls to draw*Geometry\n\n this.anchorX_ = undefined;\n this.anchorY_ = undefined;\n this.hitDetectionImage_ = null;\n this.image_ = null;\n this.imagePixelRatio_ = undefined;\n this.height_ = undefined;\n this.scale_ = undefined;\n this.opacity_ = undefined;\n this.originX_ = undefined;\n this.originY_ = undefined;\n this.rotateWithView_ = undefined;\n this.rotation_ = undefined;\n this.width_ = undefined;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import("../../style/Image.js").default} imageStyle Image style.\n * @param {Object=} opt_sharedData Shared data.\n */\n\n\n CanvasImageBuilder.prototype.setImageStyle = function (imageStyle, opt_sharedData) {\n var anchor = imageStyle.getAnchor();\n var size = imageStyle.getSize();\n var hitDetectionImage = imageStyle.getHitDetectionImage();\n var image = imageStyle.getImage(this.pixelRatio);\n var origin = imageStyle.getOrigin();\n this.imagePixelRatio_ = imageStyle.getPixelRatio(this.pixelRatio);\n this.anchorX_ = anchor[0];\n this.anchorY_ = anchor[1];\n this.hitDetectionImage_ = hitDetectionImage;\n this.image_ = image;\n this.height_ = size[1];\n this.opacity_ = imageStyle.getOpacity();\n this.originX_ = origin[0];\n this.originY_ = origin[1];\n this.rotateWithView_ = imageStyle.getRotateWithView();\n this.rotation_ = imageStyle.getRotation();\n this.scale_ = imageStyle.getScaleArray();\n this.width_ = size[0];\n this.declutterImageWithText_ = opt_sharedData;\n };\n\n return CanvasImageBuilder;\n}(Builder);\n\n/* harmony default export */ var ImageBuilder = (CanvasImageBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/LineStringBuilder.js\nvar LineStringBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/LineStringBuilder\n */\n\n\n\n\n\nvar CanvasLineStringBuilder =\n/** @class */\nfunction (_super) {\n LineStringBuilder_extends(CanvasLineStringBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasLineStringBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n * @return {number} end.\n */\n\n\n CanvasLineStringBuilder.prototype.drawFlatCoordinates_ = function (flatCoordinates, offset, end, stride) {\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, false, false);\n var moveToLineToInstruction = [canvas_Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n return end;\n };\n /**\n * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} lineStringGeometry Line string geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasLineStringBuilder.prototype.drawLineString = function (lineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(lineStringGeometry, feature);\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset], beginPathInstruction);\n var flatCoordinates = lineStringGeometry.getFlatCoordinates();\n var stride = lineStringGeometry.getStride();\n this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} multiLineStringGeometry MultiLineString geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasLineStringBuilder.prototype.drawMultiLineString = function (multiLineStringGeometry, feature) {\n var state = this.state;\n var strokeStyle = state.strokeStyle;\n var lineWidth = state.lineWidth;\n\n if (strokeStyle === undefined || lineWidth === undefined) {\n return;\n }\n\n this.updateStrokeStyle(state, this.applyStroke);\n this.beginGeometry(multiLineStringGeometry, feature);\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset], beginPathInstruction);\n var ends = multiLineStringGeometry.getEnds();\n var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();\n var stride = multiLineStringGeometry.getStride();\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.drawFlatCoordinates_(flatCoordinates, offset,\n /** @type {number} */\n ends[i], stride);\n }\n\n this.hitDetectionInstructions.push(strokeInstruction);\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasLineStringBuilder.prototype.finish = function () {\n var state = this.state;\n\n if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n }\n\n this.reverseHitDetectionInstructions();\n this.state = null;\n return _super.prototype.finish.call(this);\n };\n /**\n * @param {import("../canvas.js").FillStrokeState} state State.\n */\n\n\n CanvasLineStringBuilder.prototype.applyStroke = function (state) {\n if (state.lastStroke != undefined && state.lastStroke != this.coordinates.length) {\n this.instructions.push(strokeInstruction);\n state.lastStroke = this.coordinates.length;\n }\n\n state.lastStroke = 0;\n\n _super.prototype.applyStroke.call(this, state);\n\n this.instructions.push(beginPathInstruction);\n };\n\n return CanvasLineStringBuilder;\n}(Builder);\n\n/* harmony default export */ var LineStringBuilder = (CanvasLineStringBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/PolygonBuilder.js\nvar PolygonBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/PolygonBuilder\n */\n\n\n\n\n\n\n\nvar CanvasPolygonBuilder =\n/** @class */\nfunction (_super) {\n PolygonBuilder_extends(CanvasPolygonBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasPolygonBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n return _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n\n\n CanvasPolygonBuilder.prototype.drawFlatCoordinatess_ = function (flatCoordinates, offset, ends, stride) {\n var state = this.state;\n var fill = state.fillStyle !== undefined;\n var stroke = state.strokeStyle !== undefined;\n var numEnds = ends.length;\n this.instructions.push(beginPathInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction);\n\n for (var i = 0; i < numEnds; ++i) {\n var end = ends[i];\n var myBegin = this.coordinates.length;\n var myEnd = this.appendFlatLineCoordinates(flatCoordinates, offset, end, stride, true, !stroke);\n var moveToLineToInstruction = [canvas_Instruction.MOVE_TO_LINE_TO, myBegin, myEnd];\n this.instructions.push(moveToLineToInstruction);\n this.hitDetectionInstructions.push(moveToLineToInstruction);\n\n if (stroke) {\n // Performance optimization: only call closePath() when we have a stroke.\n // Otherwise the ring is closed already (see appendFlatLineCoordinates above).\n this.instructions.push(closePathInstruction);\n this.hitDetectionInstructions.push(closePathInstruction);\n }\n\n offset = end;\n }\n\n if (fill) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n\n if (stroke) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n\n return offset;\n };\n /**\n * @param {import("../../geom/Circle.js").default} circleGeometry Circle geometry.\n * @param {import("../../Feature.js").default} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawCircle = function (circleGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(circleGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var flatCoordinates = circleGeometry.getFlatCoordinates();\n var stride = circleGeometry.getStride();\n var myBegin = this.coordinates.length;\n this.appendFlatLineCoordinates(flatCoordinates, 0, flatCoordinates.length, stride, false, false);\n var circleInstruction = [canvas_Instruction.CIRCLE, myBegin];\n this.instructions.push(beginPathInstruction, circleInstruction);\n this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);\n\n if (state.fillStyle !== undefined) {\n this.instructions.push(fillInstruction);\n this.hitDetectionInstructions.push(fillInstruction);\n }\n\n if (state.strokeStyle !== undefined) {\n this.instructions.push(strokeInstruction);\n this.hitDetectionInstructions.push(strokeInstruction);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} polygonGeometry Polygon geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawPolygon = function (polygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(polygonGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var ends = polygonGeometry.getEnds();\n var flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();\n var stride = polygonGeometry.getStride();\n this.drawFlatCoordinatess_(flatCoordinates, 0,\n /** @type {Array<number>} */\n ends, stride);\n this.endGeometry(feature);\n };\n /**\n * @param {import("../../geom/MultiPolygon.js").default} multiPolygonGeometry MultiPolygon geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasPolygonBuilder.prototype.drawMultiPolygon = function (multiPolygonGeometry, feature) {\n var state = this.state;\n var fillStyle = state.fillStyle;\n var strokeStyle = state.strokeStyle;\n\n if (fillStyle === undefined && strokeStyle === undefined) {\n return;\n }\n\n this.setFillStrokeStyles_();\n this.beginGeometry(multiPolygonGeometry, feature);\n\n if (state.fillStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_FILL_STYLE, defaultFillStyle]);\n }\n\n if (state.strokeStyle !== undefined) {\n this.hitDetectionInstructions.push([canvas_Instruction.SET_STROKE_STYLE, state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin, state.miterLimit, state.lineDash, state.lineDashOffset]);\n }\n\n var endss = multiPolygonGeometry.getEndss();\n var flatCoordinates = multiPolygonGeometry.getOrientedFlatCoordinates();\n var stride = multiPolygonGeometry.getStride();\n var offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);\n }\n\n this.endGeometry(feature);\n };\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasPolygonBuilder.prototype.finish = function () {\n this.reverseHitDetectionInstructions();\n this.state = null; // We want to preserve topology when drawing polygons. Polygons are\n // simplified using quantization and point elimination. However, we might\n // have received a mix of quantized and non-quantized geometries, so ensure\n // that all are quantized by quantizing all coordinates in the batch.\n\n var tolerance = this.tolerance;\n\n if (tolerance !== 0) {\n var coordinates = this.coordinates;\n\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n coordinates[i] = snap(coordinates[i], tolerance);\n }\n }\n\n return _super.prototype.finish.call(this);\n };\n /**\n * @private\n */\n\n\n CanvasPolygonBuilder.prototype.setFillStrokeStyles_ = function () {\n var state = this.state;\n var fillStyle = state.fillStyle;\n\n if (fillStyle !== undefined) {\n this.updateFillStyle(state, this.createFill);\n }\n\n if (state.strokeStyle !== undefined) {\n this.updateStrokeStyle(state, this.applyStroke);\n }\n };\n\n return CanvasPolygonBuilder;\n}(Builder);\n\n/* harmony default export */ var PolygonBuilder = (CanvasPolygonBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/style/TextPlacement.js\n/**\n * @module ol/style/TextPlacement\n */\n\n/**\n * Text placement. One of `\'point\'`, `\'line\'`. Default is `\'point\'`. Note that\n * `\'line\'` requires the underlying geometry to be a {@link module:ol/geom/LineString~LineString},\n * {@link module:ol/geom/Polygon~Polygon}, {@link module:ol/geom/MultiLineString~MultiLineString} or\n * {@link module:ol/geom/MultiPolygon~MultiPolygon}.\n * @enum {string}\n */\n/* harmony default export */ var TextPlacement = ({\n POINT: \'point\',\n LINE: \'line\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/straightchunk.js\n/**\n * @module ol/geom/flat/straightchunk\n */\n\n/**\n * @param {number} maxAngle Maximum acceptable angle delta between segments.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Array<number>} Start and end of the first suitable chunk of the\n * given `flatCoordinates`.\n */\nfunction matchingChunk(maxAngle, flatCoordinates, offset, end, stride) {\n var chunkStart = offset;\n var chunkEnd = offset;\n var chunkM = 0;\n var m = 0;\n var start = offset;\n var acos, i, m12, m23, x1, y1, x12, y12, x23, y23;\n\n for (i = offset; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n\n if (x1 !== undefined) {\n x23 = x2 - x1;\n y23 = y2 - y1;\n m23 = Math.sqrt(x23 * x23 + y23 * y23);\n\n if (x12 !== undefined) {\n m += m12;\n acos = Math.acos((x12 * x23 + y12 * y23) / (m12 * m23));\n\n if (acos > maxAngle) {\n if (m > chunkM) {\n chunkM = m;\n chunkStart = start;\n chunkEnd = i;\n }\n\n m = 0;\n start = i - stride;\n }\n }\n\n m12 = m23;\n x12 = x23;\n y12 = y23;\n }\n\n x1 = x2;\n y1 = y2;\n }\n\n m += m23;\n return m > chunkM ? [start, i] : [chunkStart, chunkEnd];\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/TextBuilder.js\nvar TextBuilder_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/render/canvas/TextBuilder\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @const\n * @enum {number}\n */\n\nvar TEXT_ALIGN = {\n \'left\': 0,\n \'end\': 0,\n \'center\': 0.5,\n \'right\': 1,\n \'start\': 1,\n \'top\': 0,\n \'middle\': 0.5,\n \'hanging\': 0.2,\n \'alphabetic\': 0.8,\n \'ideographic\': 0.8,\n \'bottom\': 1\n};\n\nvar CanvasTextBuilder =\n/** @class */\nfunction (_super) {\n TextBuilder_extends(CanvasTextBuilder, _super);\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Maximum extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n\n\n function CanvasTextBuilder(tolerance, maxExtent, resolution, pixelRatio) {\n var _this = _super.call(this, tolerance, maxExtent, resolution, pixelRatio) || this;\n /**\n * @private\n * @type {Array<HTMLCanvasElement>}\n */\n\n\n _this.labels_ = null;\n /**\n * @private\n * @type {string}\n */\n\n _this.text_ = \'\';\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean|undefined}\n */\n\n _this.textRotateWithView_ = undefined;\n /**\n * @private\n * @type {number}\n */\n\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.textFillState_ = null;\n /**\n * @type {!Object<string, import("../canvas.js").FillState>}\n */\n\n _this.fillStates = {};\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.textStrokeState_ = null;\n /**\n * @type {!Object<string, import("../canvas.js").StrokeState>}\n */\n\n _this.strokeStates = {};\n /**\n * @private\n * @type {import("../canvas.js").TextState}\n */\n\n _this.textState_ =\n /** @type {import("../canvas.js").TextState} */\n {};\n /**\n * @type {!Object<string, import("../canvas.js").TextState>}\n */\n\n _this.textStates = {};\n /**\n * @private\n * @type {string}\n */\n\n _this.textKey_ = \'\';\n /**\n * @private\n * @type {string}\n */\n\n _this.fillKey_ = \'\';\n /**\n * @private\n * @type {string}\n */\n\n _this.strokeKey_ = \'\';\n /**\n * Data shared with an image builder for combined decluttering.\n * @private\n * @type {import("../canvas.js").DeclutterImageWithText}\n */\n\n _this.declutterImageWithText_ = undefined;\n return _this;\n }\n /**\n * @return {import("../canvas.js").SerializableInstructions} the serializable instructions.\n */\n\n\n CanvasTextBuilder.prototype.finish = function () {\n var instructions = _super.prototype.finish.call(this);\n\n instructions.textStates = this.textStates;\n instructions.fillStates = this.fillStates;\n instructions.strokeStates = this.strokeStates;\n return instructions;\n };\n /**\n * @param {import("../../geom/SimpleGeometry.js").default|import("../Feature.js").default} geometry Geometry.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n */\n\n\n CanvasTextBuilder.prototype.drawText = function (geometry, feature) {\n var fillState = this.textFillState_;\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n\n if (this.text_ === \'\' || !textState || !fillState && !strokeState) {\n return;\n }\n\n var coordinates = this.coordinates;\n var begin = coordinates.length;\n var geometryType = geometry.getType();\n var flatCoordinates = null;\n var stride = geometry.getStride();\n\n if (textState.placement === TextPlacement.LINE && (geometryType == geom_GeometryType.LINE_STRING || geometryType == geom_GeometryType.MULTI_LINE_STRING || geometryType == geom_GeometryType.POLYGON || geometryType == geom_GeometryType.MULTI_POLYGON)) {\n if (!intersects(this.getBufferedMaxExtent(), geometry.getExtent())) {\n return;\n }\n\n var ends = void 0;\n flatCoordinates = geometry.getFlatCoordinates();\n\n if (geometryType == geom_GeometryType.LINE_STRING) {\n ends = [flatCoordinates.length];\n } else if (geometryType == geom_GeometryType.MULTI_LINE_STRING) {\n ends =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.getEnds();\n } else if (geometryType == geom_GeometryType.POLYGON) {\n ends =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getEnds().slice(0, 1);\n } else if (geometryType == geom_GeometryType.MULTI_POLYGON) {\n var endss =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getEndss();\n ends = [];\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n ends.push(endss[i][0]);\n }\n }\n\n this.beginGeometry(geometry, feature);\n var textAlign = textState.textAlign;\n var flatOffset = 0;\n var flatEnd = void 0;\n\n for (var o = 0, oo = ends.length; o < oo; ++o) {\n if (textAlign == undefined) {\n var range = matchingChunk(textState.maxAngle, flatCoordinates, flatOffset, ends[o], stride);\n flatOffset = range[0];\n flatEnd = range[1];\n } else {\n flatEnd = ends[o];\n }\n\n for (var i = flatOffset; i < flatEnd; i += stride) {\n coordinates.push(flatCoordinates[i], flatCoordinates[i + 1]);\n }\n\n var end = coordinates.length;\n flatOffset = ends[o];\n this.drawChars_(begin, end);\n begin = end;\n }\n\n this.endGeometry(feature);\n } else {\n var geometryWidths = textState.overflow ? null : [];\n\n switch (geometryType) {\n case geom_GeometryType.POINT:\n case geom_GeometryType.MULTI_POINT:\n flatCoordinates =\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry.getFlatCoordinates();\n break;\n\n case geom_GeometryType.LINE_STRING:\n flatCoordinates =\n /** @type {import("../../geom/LineString.js").default} */\n geometry.getFlatMidpoint();\n break;\n\n case geom_GeometryType.CIRCLE:\n flatCoordinates =\n /** @type {import("../../geom/Circle.js").default} */\n geometry.getCenter();\n break;\n\n case geom_GeometryType.MULTI_LINE_STRING:\n flatCoordinates =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.getFlatMidpoints();\n stride = 2;\n break;\n\n case geom_GeometryType.POLYGON:\n flatCoordinates =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.getFlatInteriorPoint();\n\n if (!textState.overflow) {\n geometryWidths.push(flatCoordinates[2] / this.resolution);\n }\n\n stride = 3;\n break;\n\n case geom_GeometryType.MULTI_POLYGON:\n var interiorPoints =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.getFlatInteriorPoints();\n flatCoordinates = [];\n\n for (var i = 0, ii = interiorPoints.length; i < ii; i += 3) {\n if (!textState.overflow) {\n geometryWidths.push(interiorPoints[i + 2] / this.resolution);\n }\n\n flatCoordinates.push(interiorPoints[i], interiorPoints[i + 1]);\n }\n\n if (flatCoordinates.length === 0) {\n return;\n }\n\n stride = 2;\n break;\n\n default:\n }\n\n var end = this.appendFlatPointCoordinates(flatCoordinates, stride);\n\n if (end === begin) {\n return;\n }\n\n this.saveTextStates_();\n\n if (textState.backgroundFill || textState.backgroundStroke) {\n this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);\n\n if (textState.backgroundFill) {\n this.updateFillStyle(this.state, this.createFill);\n this.hitDetectionInstructions.push(this.createFill(this.state));\n }\n\n if (textState.backgroundStroke) {\n this.updateStrokeStyle(this.state, this.applyStroke);\n this.hitDetectionInstructions.push(this.createStroke(this.state));\n }\n }\n\n this.beginGeometry(geometry, feature); // adjust padding for negative scale\n\n var padding = textState.padding;\n\n if (padding != defaultPadding && (textState.scale[0] < 0 || textState.scale[1] < 0)) {\n var p0 = textState.padding[0];\n var p1 = textState.padding[1];\n var p2 = textState.padding[2];\n var p3 = textState.padding[3];\n\n if (textState.scale[0] < 0) {\n p1 = -p1;\n p3 = -p3;\n }\n\n if (textState.scale[1] < 0) {\n p0 = -p0;\n p2 = -p2;\n }\n\n padding = [p0, p1, p2, p3];\n } // The image is unknown at this stage so we pass null; it will be computed at render time.\n // For clarity, we pass NaN for offsetX, offsetY, width and height, which will be computed at\n // render time.\n\n\n var pixelRatio_1 = this.pixelRatio;\n this.instructions.push([canvas_Instruction.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [1, 1], NaN, this.declutterImageWithText_, padding == defaultPadding ? defaultPadding : padding.map(function (p) {\n return p * pixelRatio_1;\n }), !!textState.backgroundFill, !!textState.backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths]);\n var scale = 1 / pixelRatio_1;\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_IMAGE, begin, end, null, NaN, NaN, NaN, 1, 0, 0, this.textRotateWithView_, this.textRotation_, [scale, scale], NaN, this.declutterImageWithText_, padding, !!textState.backgroundFill, !!textState.backgroundStroke, this.text_, this.textKey_, this.strokeKey_, this.fillKey_, this.textOffsetX_, this.textOffsetY_, geometryWidths]);\n this.endGeometry(feature);\n }\n };\n /**\n * @private\n */\n\n\n CanvasTextBuilder.prototype.saveTextStates_ = function () {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var fillState = this.textFillState_;\n var strokeKey = this.strokeKey_;\n\n if (strokeState) {\n if (!(strokeKey in this.strokeStates)) {\n this.strokeStates[strokeKey] = {\n strokeStyle: strokeState.strokeStyle,\n lineCap: strokeState.lineCap,\n lineDashOffset: strokeState.lineDashOffset,\n lineWidth: strokeState.lineWidth,\n lineJoin: strokeState.lineJoin,\n miterLimit: strokeState.miterLimit,\n lineDash: strokeState.lineDash\n };\n }\n }\n\n var textKey = this.textKey_;\n\n if (!(textKey in this.textStates)) {\n this.textStates[textKey] = {\n font: textState.font,\n textAlign: textState.textAlign || defaultTextAlign,\n textBaseline: textState.textBaseline || defaultTextBaseline,\n scale: textState.scale\n };\n }\n\n var fillKey = this.fillKey_;\n\n if (fillState) {\n if (!(fillKey in this.fillStates)) {\n this.fillStates[fillKey] = {\n fillStyle: fillState.fillStyle\n };\n }\n }\n };\n /**\n * @private\n * @param {number} begin Begin.\n * @param {number} end End.\n */\n\n\n CanvasTextBuilder.prototype.drawChars_ = function (begin, end) {\n var strokeState = this.textStrokeState_;\n var textState = this.textState_;\n var strokeKey = this.strokeKey_;\n var textKey = this.textKey_;\n var fillKey = this.fillKey_;\n this.saveTextStates_();\n var pixelRatio = this.pixelRatio;\n var baseline = TEXT_ALIGN[textState.textBaseline];\n var offsetY = this.textOffsetY_ * pixelRatio;\n var text = this.text_;\n var strokeWidth = strokeState ? strokeState.lineWidth * Math.abs(textState.scale[0]) / 2 : 0;\n this.instructions.push([canvas_Instruction.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey, textState.maxAngle, pixelRatio, offsetY, strokeKey, strokeWidth * pixelRatio, text, textKey, 1]);\n this.hitDetectionInstructions.push([canvas_Instruction.DRAW_CHARS, begin, end, baseline, textState.overflow, fillKey, textState.maxAngle, 1, offsetY, strokeKey, strokeWidth, text, textKey, 1 / pixelRatio]);\n };\n /**\n * @param {import("../../style/Text.js").default} textStyle Text style.\n * @param {Object=} opt_sharedData Shared data.\n */\n\n\n CanvasTextBuilder.prototype.setTextStyle = function (textStyle, opt_sharedData) {\n var textState, fillState, strokeState;\n\n if (!textStyle) {\n this.text_ = \'\';\n } else {\n var textFillStyle = textStyle.getFill();\n\n if (!textFillStyle) {\n fillState = null;\n this.textFillState_ = fillState;\n } else {\n fillState = this.textFillState_;\n\n if (!fillState) {\n fillState =\n /** @type {import("../canvas.js").FillState} */\n {};\n this.textFillState_ = fillState;\n }\n\n fillState.fillStyle = asColorLike(textFillStyle.getColor() || defaultFillStyle);\n }\n\n var textStrokeStyle = textStyle.getStroke();\n\n if (!textStrokeStyle) {\n strokeState = null;\n this.textStrokeState_ = strokeState;\n } else {\n strokeState = this.textStrokeState_;\n\n if (!strokeState) {\n strokeState =\n /** @type {import("../canvas.js").StrokeState} */\n {};\n this.textStrokeState_ = strokeState;\n }\n\n var lineDash = textStrokeStyle.getLineDash();\n var lineDashOffset = textStrokeStyle.getLineDashOffset();\n var lineWidth = textStrokeStyle.getWidth();\n var miterLimit = textStrokeStyle.getMiterLimit();\n strokeState.lineCap = textStrokeStyle.getLineCap() || defaultLineCap;\n strokeState.lineDash = lineDash ? lineDash.slice() : defaultLineDash;\n strokeState.lineDashOffset = lineDashOffset === undefined ? defaultLineDashOffset : lineDashOffset;\n strokeState.lineJoin = textStrokeStyle.getLineJoin() || defaultLineJoin;\n strokeState.lineWidth = lineWidth === undefined ? defaultLineWidth : lineWidth;\n strokeState.miterLimit = miterLimit === undefined ? defaultMiterLimit : miterLimit;\n strokeState.strokeStyle = asColorLike(textStrokeStyle.getColor() || defaultStrokeStyle);\n }\n\n textState = this.textState_;\n var font = textStyle.getFont() || defaultFont;\n registerFont(font);\n var textScale = textStyle.getScaleArray();\n textState.overflow = textStyle.getOverflow();\n textState.font = font;\n textState.maxAngle = textStyle.getMaxAngle();\n textState.placement = textStyle.getPlacement();\n textState.textAlign = textStyle.getTextAlign();\n textState.textBaseline = textStyle.getTextBaseline() || defaultTextBaseline;\n textState.backgroundFill = textStyle.getBackgroundFill();\n textState.backgroundStroke = textStyle.getBackgroundStroke();\n textState.padding = textStyle.getPadding() || defaultPadding;\n textState.scale = textScale === undefined ? [1, 1] : textScale;\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n this.text_ = textStyle.getText() || \'\';\n this.textOffsetX_ = textOffsetX === undefined ? 0 : textOffsetX;\n this.textOffsetY_ = textOffsetY === undefined ? 0 : textOffsetY;\n this.textRotateWithView_ = textRotateWithView === undefined ? false : textRotateWithView;\n this.textRotation_ = textRotation === undefined ? 0 : textRotation;\n this.strokeKey_ = strokeState ? (typeof strokeState.strokeStyle == \'string\' ? strokeState.strokeStyle : getUid(strokeState.strokeStyle)) + strokeState.lineCap + strokeState.lineDashOffset + \'|\' + strokeState.lineWidth + strokeState.lineJoin + strokeState.miterLimit + \'[\' + strokeState.lineDash.join() + \']\' : \'\';\n this.textKey_ = textState.font + textState.scale + (textState.textAlign || \'?\') + (textState.textBaseline || \'?\');\n this.fillKey_ = fillState ? typeof fillState.fillStyle == \'string\' ? fillState.fillStyle : \'|\' + getUid(fillState.fillStyle) : \'\';\n }\n\n this.declutterImageWithText_ = opt_sharedData;\n };\n\n return CanvasTextBuilder;\n}(Builder);\n\n/* harmony default export */ var TextBuilder = (CanvasTextBuilder);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/BuilderGroup.js\n/**\n * @module ol/render/canvas/BuilderGroup\n */\n\n\n\n\n\n/**\n * @type {Object<import("./BuilderType").default, typeof Builder>}\n */\n\nvar BATCH_CONSTRUCTORS = {\n \'Circle\': PolygonBuilder,\n \'Default\': Builder,\n \'Image\': ImageBuilder,\n \'LineString\': LineStringBuilder,\n \'Polygon\': PolygonBuilder,\n \'Text\': TextBuilder\n};\n\nvar BuilderGroup =\n/** @class */\nfunction () {\n /**\n * @param {number} tolerance Tolerance.\n * @param {import("../../extent.js").Extent} maxExtent Max extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n */\n function BuilderGroup(tolerance, maxExtent, resolution, pixelRatio) {\n /**\n * @private\n * @type {number}\n */\n this.tolerance_ = tolerance;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {number}\n */\n\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n this.resolution_ = resolution;\n /**\n * @private\n * @type {!Object<string, !Object<import("./BuilderType").default, Builder>>}\n */\n\n this.buildersByZIndex_ = {};\n }\n /**\n * @return {!Object<string, !Object<import("./BuilderType").default, import("./Builder.js").SerializableInstructions>>} The serializable instructions\n */\n\n\n BuilderGroup.prototype.finish = function () {\n var builderInstructions = {};\n\n for (var zKey in this.buildersByZIndex_) {\n builderInstructions[zKey] = builderInstructions[zKey] || {};\n var builders = this.buildersByZIndex_[zKey];\n\n for (var builderKey in builders) {\n var builderInstruction = builders[builderKey].finish();\n builderInstructions[zKey][builderKey] = builderInstruction;\n }\n }\n\n return builderInstructions;\n };\n /**\n * @param {number|undefined} zIndex Z index.\n * @param {import("./BuilderType.js").default} builderType Replay type.\n * @return {import("../VectorContext.js").default} Replay.\n */\n\n\n BuilderGroup.prototype.getBuilder = function (zIndex, builderType) {\n var zIndexKey = zIndex !== undefined ? zIndex.toString() : \'0\';\n var replays = this.buildersByZIndex_[zIndexKey];\n\n if (replays === undefined) {\n replays = {};\n this.buildersByZIndex_[zIndexKey] = replays;\n }\n\n var replay = replays[builderType];\n\n if (replay === undefined) {\n var Constructor = BATCH_CONSTRUCTORS[builderType];\n replay = new Constructor(this.tolerance_, this.maxExtent_, this.resolution_, this.pixelRatio_);\n replays[builderType] = replay;\n }\n\n return replay;\n };\n\n return BuilderGroup;\n}();\n\n/* harmony default export */ var canvas_BuilderGroup = (BuilderGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/Layer.js\nvar renderer_Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/Layer\n */\n\n\n\n\n\n\n\n/**\n * @template {import("../layer/Layer.js").default} LayerType\n */\n\nvar LayerRenderer =\n/** @class */\nfunction (_super) {\n renderer_Layer_extends(LayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n\n\n function LayerRenderer(layer) {\n var _this = _super.call(this) || this;\n /** @private */\n\n\n _this.boundHandleImageChange_ = _this.handleImageChange_.bind(_this);\n /**\n * @protected\n * @type {LayerType}\n */\n\n _this.layer_ = layer;\n /**\n * @type {import("../render/canvas/ExecutorGroup").default}\n */\n\n _this.declutterExecutorGroup = null;\n return _this;\n }\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with\n * an array of features.\n */\n\n\n LayerRenderer.prototype.getFeatures = function (pixel) {\n return util_abstract();\n };\n /**\n * Determine whether render should be called.\n * @abstract\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n LayerRenderer.prototype.prepareFrame = function (frameState) {\n return util_abstract();\n };\n /**\n * Render the layer.\n * @abstract\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n LayerRenderer.prototype.renderFrame = function (frameState, target) {\n return util_abstract();\n };\n /**\n * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import("../Tile.js").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n\n\n LayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (!tiles[zoom]) {\n tiles[zoom] = {};\n }\n\n tiles[zoom][tile.tileCoord.toString()] = tile;\n return undefined;\n };\n /**\n * Create a function that adds loaded tiles to the tile lookup.\n * @param {import("../source/Tile.js").default} source Tile source.\n * @param {import("../proj/Projection.js").default} projection Projection of the tiles.\n * @param {Object<number, Object<string, import("../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @return {function(number, import("../TileRange.js").default):boolean} A function that can be\n * called with a zoom level and a tile range to add loaded tiles to the lookup.\n * @protected\n */\n\n\n LayerRenderer.prototype.createLoadedTileFinder = function (source, projection, tiles) {\n return (\n /**\n * @param {number} zoom Zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @return {boolean} The tile range is fully loaded.\n * @this {LayerRenderer}\n */\n function (zoom, tileRange) {\n var callback = this.loadedTileCallback.bind(this, tiles, zoom);\n return source.forEachLoadedTile(projection, zoom, tileRange, callback);\n }.bind(this)\n );\n };\n /**\n * @abstract\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("./Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n LayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n return undefined;\n };\n /**\n * @abstract\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @param {import("../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n\n\n LayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n return util_abstract();\n };\n /**\n * @return {LayerType} Layer.\n */\n\n\n LayerRenderer.prototype.getLayer = function () {\n return this.layer_;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n * @abstract\n */\n\n\n LayerRenderer.prototype.handleFontsChanged = function () {};\n /**\n * Handle changes in image state.\n * @param {import("../events/Event.js").default} event Image change event.\n * @private\n */\n\n\n LayerRenderer.prototype.handleImageChange_ = function (event) {\n var image =\n /** @type {import("../Image.js").default} */\n event.target;\n\n if (image.getState() === ImageState.LOADED) {\n this.renderIfReadyAndVisible();\n }\n };\n /**\n * Load the image if not already loaded, and register the image change\n * listener if needed.\n * @param {import("../ImageBase.js").default} image Image.\n * @return {boolean} `true` if the image is already loaded, `false` otherwise.\n * @protected\n */\n\n\n LayerRenderer.prototype.loadImage = function (image) {\n var imageState = image.getState();\n\n if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {\n image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);\n }\n\n if (imageState == ImageState.IDLE) {\n image.load();\n imageState = image.getState();\n }\n\n return imageState == ImageState.LOADED;\n };\n /**\n * @protected\n */\n\n\n LayerRenderer.prototype.renderIfReadyAndVisible = function () {\n var layer = this.getLayer();\n\n if (layer.getVisible() && layer.getSourceState() == State.READY) {\n layer.changed();\n }\n };\n\n return LayerRenderer;\n}(ol_Observable);\n\n/* harmony default export */ var renderer_Layer = (LayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/Layer.js\nvar canvas_Layer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/Layer\n */\n\n\n\n\n\n\n\n\n\n/**\n * @abstract\n * @template {import("../../layer/Layer.js").default} LayerType\n */\n\nvar CanvasLayerRenderer =\n/** @class */\nfunction (_super) {\n canvas_Layer_extends(CanvasLayerRenderer, _super);\n /**\n * @param {LayerType} layer Layer.\n */\n\n\n function CanvasLayerRenderer(layer) {\n var _this = _super.call(this, layer) || this;\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n\n _this.container = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedResolution;\n /**\n * A temporary transform. The values in this transform should only be used in a\n * function that sets the values.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tempTransform = create();\n /**\n * The transform for rendered pixels to viewport CSS pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.pixelTransform = create();\n /**\n * The transform for viewport CSS pixels to rendered pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import("../../transform.js").Transform}\n */\n\n _this.inversePixelTransform = create();\n /**\n * @type {CanvasRenderingContext2D}\n */\n\n _this.context = null;\n /**\n * @type {boolean}\n */\n\n _this.containerReused = false;\n return _this;\n }\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasLayerRenderer.prototype.useContainer = function (target, transform, opacity) {\n var layerClassName = this.getLayer().getClassName();\n var container, context;\n\n if (target && target.style.opacity === \'\' && target.className === layerClassName) {\n var canvas = target.firstElementChild;\n\n if (canvas instanceof HTMLCanvasElement) {\n context = canvas.getContext(\'2d\');\n }\n }\n\n if (context && (context.canvas.width === 0 || context.canvas.style.transform === transform)) {\n // Container of the previous layer renderer can be used.\n this.container = target;\n this.context = context;\n this.containerReused = true;\n } else if (this.containerReused) {\n // Previously reused container cannot be used any more.\n this.container = null;\n this.context = null;\n this.containerReused = false;\n }\n\n if (!this.container) {\n container = document.createElement(\'div\');\n container.className = layerClassName;\n var style = container.style;\n style.position = \'absolute\';\n style.width = \'100%\';\n style.height = \'100%\';\n context = createCanvasContext2D();\n var canvas = context.canvas;\n container.appendChild(canvas);\n style = canvas.style;\n style.position = \'absolute\';\n style.left = \'0\';\n style.transformOrigin = \'top left\';\n this.container = container;\n this.context = context;\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../extent.js").Extent} extent Clip extent.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.clip = function (context, frameState, extent) {\n var pixelRatio = frameState.pixelRatio;\n var halfWidth = frameState.size[0] * pixelRatio / 2;\n var halfHeight = frameState.size[1] * pixelRatio / 2;\n var rotation = frameState.viewState.rotation;\n var topLeft = getTopLeft(extent);\n var topRight = getTopRight(extent);\n var bottomRight = getBottomRight(extent);\n var bottomLeft = getBottomLeft(extent);\n apply(frameState.coordinateToPixelTransform, topLeft);\n apply(frameState.coordinateToPixelTransform, topRight);\n apply(frameState.coordinateToPixelTransform, bottomRight);\n apply(frameState.coordinateToPixelTransform, bottomLeft);\n context.save();\n rotateAtOffset(context, -rotation, halfWidth, halfHeight);\n context.beginPath();\n context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);\n context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);\n context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);\n context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);\n context.clip();\n rotateAtOffset(context, rotation, halfWidth, halfHeight);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../extent.js").Extent} extent Clip extent.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.clipUnrotated = function (context, frameState, extent) {\n var topLeft = getTopLeft(extent);\n var topRight = getTopRight(extent);\n var bottomRight = getBottomRight(extent);\n var bottomLeft = getBottomLeft(extent);\n apply(frameState.coordinateToPixelTransform, topLeft);\n apply(frameState.coordinateToPixelTransform, topRight);\n apply(frameState.coordinateToPixelTransform, bottomRight);\n apply(frameState.coordinateToPixelTransform, bottomLeft);\n var inverted = this.inversePixelTransform;\n apply(inverted, topLeft);\n apply(inverted, topRight);\n apply(inverted, bottomRight);\n apply(inverted, bottomLeft);\n context.save();\n context.beginPath();\n context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));\n context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));\n context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));\n context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));\n context.clip();\n };\n /**\n * @param {import("../../render/EventType.js").default} type Event type.\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @private\n */\n\n\n CanvasLayerRenderer.prototype.dispatchRenderEvent_ = function (type, context, frameState) {\n var layer = this.getLayer();\n\n if (layer.hasListener(type)) {\n var event_1 = new render_Event(type, this.inversePixelTransform, frameState, context);\n layer.dispatchEvent(event_1);\n }\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.preRender = function (context, frameState) {\n this.dispatchRenderEvent_(render_EventType.PRERENDER, context, frameState);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @protected\n */\n\n\n CanvasLayerRenderer.prototype.postRender = function (context, frameState) {\n this.dispatchRenderEvent_(render_EventType.POSTRENDER, context, frameState);\n };\n /**\n * Creates a transform for rendering to an element that will be rotated after rendering.\n * @param {import("../../coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} width Width of the rendered element (in pixels).\n * @param {number} height Height of the rendered element (in pixels).\n * @param {number} offsetX Offset on the x-axis in view coordinates.\n * @protected\n * @return {!import("../../transform.js").Transform} Transform.\n */\n\n\n CanvasLayerRenderer.prototype.getRenderTransform = function (center, resolution, rotation, pixelRatio, width, height, offsetX) {\n var dx1 = width / 2;\n var dy1 = height / 2;\n var sx = pixelRatio / resolution;\n var sy = -sx;\n var dx2 = -center[0] + offsetX;\n var dy2 = -center[1];\n return compose(this.tempTransform, dx1, dy1, sx, sy, -rotation, dx2, dy2);\n };\n /**\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @param {import("../../PluggableMap.js").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @return {Uint8ClampedArray|Uint8Array} The result. If there is no data at the pixel\n * location, null will be returned. If there is data, but pixel values cannot be\n * returned, and empty array will be returned.\n */\n\n\n CanvasLayerRenderer.prototype.getDataAtPixel = function (pixel, frameState, hitTolerance) {\n var renderPixel = apply(this.inversePixelTransform, pixel.slice());\n var context = this.context;\n var layer = this.getLayer();\n var layerExtent = layer.getExtent();\n\n if (layerExtent) {\n var renderCoordinate = apply(frameState.pixelToCoordinateTransform, pixel.slice());\n /** get only data inside of the layer extent */\n\n if (!containsCoordinate(layerExtent, renderCoordinate)) {\n return null;\n }\n }\n\n var data;\n\n try {\n var x = Math.round(renderPixel[0]);\n var y = Math.round(renderPixel[1]);\n var newCanvas = document.createElement(\'canvas\');\n var newContext = newCanvas.getContext(\'2d\');\n newCanvas.width = 1;\n newCanvas.height = 1;\n newContext.clearRect(0, 0, 1, 1);\n newContext.drawImage(context.canvas, x, y, 1, 1, 0, 0, 1, 1);\n data = newContext.getImageData(0, 0, 1, 1).data;\n } catch (err) {\n if (err.name === \'SecurityError\') {\n // tainted canvas, we assume there is data at the given pixel (although there might not be)\n return new Uint8Array();\n }\n\n return data;\n }\n\n if (data[3] === 0) {\n return null;\n }\n\n return data;\n };\n\n return CanvasLayerRenderer;\n}(renderer_Layer);\n\n/* harmony default export */ var canvas_Layer = (CanvasLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/BuilderType.js\n/**\n * @module ol/render/canvas/BuilderType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var BuilderType = ({\n CIRCLE: \'Circle\',\n DEFAULT: \'Default\',\n IMAGE: \'Image\',\n LINE_STRING: \'LineString\',\n POLYGON: \'Polygon\',\n TEXT: \'Text\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/textpath.js\n/**\n * @module ol/geom/flat/textpath\n */\n\n\n/**\n * @param {Array<number>} flatCoordinates Path to put text on.\n * @param {number} offset Start offset of the `flatCoordinates`.\n * @param {number} end End offset of the `flatCoordinates`.\n * @param {number} stride Stride.\n * @param {string} text Text to place on the path.\n * @param {number} startM m along the path where the text starts.\n * @param {number} maxAngle Max angle between adjacent chars in radians.\n * @param {number} scale The product of the text scale and the device pixel ratio.\n * @param {function(string, string, Object<string, number>):number} measureAndCacheTextWidth Measure and cache text width.\n * @param {string} font The font.\n * @param {Object<string, number>} cache A cache of measured widths.\n * @param {number} rotation Rotation to apply to the flatCoordinates to determine whether text needs to be reversed.\n * @return {Array<Array<*>>} The result array (or null if `maxAngle` was\n * exceeded). Entries of the array are x, y, anchorX, angle, chunk.\n */\n\nfunction drawTextOnPath(flatCoordinates, offset, end, stride, text, startM, maxAngle, scale, measureAndCacheTextWidth, font, cache, rotation) {\n var x2 = flatCoordinates[offset];\n var y2 = flatCoordinates[offset + 1];\n var x1 = 0;\n var y1 = 0;\n var segmentLength = 0;\n var segmentM = 0;\n\n function advance() {\n x1 = x2;\n y1 = y2;\n offset += stride;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1];\n segmentM += segmentLength;\n segmentLength = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n }\n\n do {\n advance();\n } while (offset < end - stride && segmentM + segmentLength < startM);\n\n var interpolate = (startM - segmentM) / segmentLength;\n var beginX = lerp(x1, x2, interpolate);\n var beginY = lerp(y1, y2, interpolate);\n var startOffset = offset - stride;\n var startLength = segmentM;\n var endM = startM + scale * measureAndCacheTextWidth(font, text, cache);\n\n while (offset < end - stride && segmentM + segmentLength < endM) {\n advance();\n }\n\n interpolate = (endM - segmentM) / segmentLength;\n var endX = lerp(x1, x2, interpolate);\n var endY = lerp(y1, y2, interpolate); // Keep text upright\n\n var reverse;\n\n if (rotation) {\n var flat = [beginX, beginY, endX, endY];\n transform_rotate(flat, 0, 4, 2, rotation, flat, flat);\n reverse = flat[0] > flat[2];\n } else {\n reverse = beginX > endX;\n }\n\n var PI = Math.PI;\n var result = [];\n var singleSegment = startOffset + stride === offset;\n offset = startOffset;\n segmentLength = 0;\n segmentM = startLength;\n x2 = flatCoordinates[offset];\n y2 = flatCoordinates[offset + 1]; // All on the same segment\n\n if (singleSegment) {\n advance();\n var previousAngle_1 = Math.atan2(y2 - y1, x2 - x1);\n\n if (reverse) {\n previousAngle_1 += previousAngle_1 > 0 ? -PI : PI;\n }\n\n var x = (endX + beginX) / 2;\n var y = (endY + beginY) / 2;\n result[0] = [x, y, (endM - startM) / 2, previousAngle_1, text];\n return result;\n }\n\n var previousAngle;\n\n for (var i = 0, ii = text.length; i < ii;) {\n advance();\n var angle = Math.atan2(y2 - y1, x2 - x1);\n\n if (reverse) {\n angle += angle > 0 ? -PI : PI;\n }\n\n if (previousAngle !== undefined) {\n var delta = angle - previousAngle;\n delta += delta > PI ? -2 * PI : delta < -PI ? 2 * PI : 0;\n\n if (Math.abs(delta) > maxAngle) {\n return null;\n }\n }\n\n previousAngle = angle;\n var iStart = i;\n var charLength = 0;\n\n for (; i < ii; ++i) {\n var index = reverse ? ii - i - 1 : i;\n var len = scale * measureAndCacheTextWidth(font, text[index], cache);\n\n if (offset + stride < end && segmentM + segmentLength < startM + charLength + len / 2) {\n break;\n }\n\n charLength += len;\n }\n\n if (i === iStart) {\n continue;\n }\n\n var chars = reverse ? text.substring(ii - iStart, ii - i) : text.substring(iStart, i);\n interpolate = (startM + charLength / 2 - segmentM) / segmentLength;\n var x = lerp(x1, x2, interpolate);\n var y = lerp(y1, y2, interpolate);\n result.push([x, y, charLength / 2, angle, chars]);\n startM += charLength;\n }\n\n return result;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/length.js\n/**\n * @module ol/geom/flat/length\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Length.\n */\nfunction lineStringLength(flatCoordinates, offset, end, stride) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length = 0;\n\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n x1 = x2;\n y1 = y2;\n }\n\n return length;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {number} Perimeter.\n */\n\nfunction linearRingLength(flatCoordinates, offset, end, stride) {\n var perimeter = lineStringLength(flatCoordinates, offset, end, stride);\n var dx = flatCoordinates[end - stride] - flatCoordinates[offset];\n var dy = flatCoordinates[end - stride + 1] - flatCoordinates[offset + 1];\n perimeter += Math.sqrt(dx * dx + dy * dy);\n return perimeter;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Executor.js\n/**\n * @module ol/render/canvas/Executor\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} BBox\n * @property {number} minX\n * @property {number} minY\n * @property {number} maxX\n * @property {number} maxY\n * @property {*} value\n */\n\n/**\n * @typedef {Object} ImageOrLabelDimensions\n * @property {number} drawImageX\n * @property {number} drawImageY\n * @property {number} drawImageW\n * @property {number} drawImageH\n * @property {number} originX\n * @property {number} originY\n * @property {Array<number>} scale\n * @property {BBox} declutterBox\n * @property {import("../../transform.js").Transform} canvasTransform\n */\n\n/**\n * @typedef {{0: CanvasRenderingContext2D, 1: number, 2: import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement, 3: ImageOrLabelDimensions, 4: number, 5: Array<*>, 6: Array<*>}} ReplayImageOrLabelArgs\n */\n\n/**\n * @template T\n * @typedef {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default): T} FeatureCallback\n */\n\n/**\n * @type {import("../../extent.js").Extent}\n */\n\nvar tmpExtent = createEmpty();\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p1 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p2 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p3 = [];\n/** @type {import("../../coordinate.js").Coordinate} */\n\nvar p4 = [];\n/**\n * @param {ReplayImageOrLabelArgs} replayImageOrLabelArgs Arguments to replayImageOrLabel\n * @return {BBox} Declutter bbox.\n */\n\nfunction getDeclutterBox(replayImageOrLabelArgs) {\n return replayImageOrLabelArgs[3].declutterBox;\n}\n\nvar rtlRegEx = new RegExp(\n/* eslint-disable prettier/prettier */\n\'[\' + String.fromCharCode(0x00591) + \'-\' + String.fromCharCode(0x008ff) + String.fromCharCode(0x0fb1d) + \'-\' + String.fromCharCode(0x0fdff) + String.fromCharCode(0x0fe70) + \'-\' + String.fromCharCode(0x0fefc) + String.fromCharCode(0x10800) + \'-\' + String.fromCharCode(0x10fff) + String.fromCharCode(0x1e800) + \'-\' + String.fromCharCode(0x1efff) + \']\'\n/* eslint-enable prettier/prettier */\n);\n/**\n * @param {string} text Text.\n * @param {string} align Alignment.\n * @return {number} Text alignment.\n */\n\nfunction horizontalTextAlign(text, align) {\n if ((align === \'start\' || align === \'end\') && !rtlRegEx.test(text)) {\n align = align === \'start\' ? \'left\' : \'right\';\n }\n\n return TEXT_ALIGN[align];\n}\n\nvar Executor =\n/** @class */\nfunction () {\n /**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The replay can have overlapping geometries.\n * @param {import("../canvas.js").SerializableInstructions} instructions The serializable instructions\n * @param {import("../../size.js").Size} renderBuffer Render buffer (width/height) in pixels.\n */\n function Executor(resolution, pixelRatio, overlaps, instructions, renderBuffer) {\n /**\n * @protected\n * @type {boolean}\n */\n this.overlaps = overlaps;\n /**\n * @protected\n * @type {number}\n */\n\n this.pixelRatio = pixelRatio;\n /**\n * @protected\n * @const\n * @type {number}\n */\n\n this.resolution = resolution;\n /**\n * @private\n * @type {boolean}\n */\n\n this.alignFill_;\n /**\n * @protected\n * @type {Array<*>}\n */\n\n this.instructions = instructions.instructions;\n /**\n * @protected\n * @type {Array<number>}\n */\n\n this.coordinates = instructions.coordinates;\n /**\n * @private\n * @type {!Object<number,import("../../coordinate.js").Coordinate|Array<import("../../coordinate.js").Coordinate>|Array<Array<import("../../coordinate.js").Coordinate>>>}\n */\n\n this.coordinateCache_ = {};\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n this.renderBuffer_ = renderBuffer;\n /**\n * @private\n * @type {!import("../../transform.js").Transform}\n */\n\n this.renderedTransform_ = create();\n /**\n * @protected\n * @type {Array<*>}\n */\n\n this.hitDetectionInstructions = instructions.hitDetectionInstructions;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.pixelCoordinates_ = null;\n /**\n * @private\n * @type {number}\n */\n\n this.viewRotation_ = 0;\n /**\n * @type {!Object<string, import("../canvas.js").FillState>}\n */\n\n this.fillStates = instructions.fillStates || {};\n /**\n * @type {!Object<string, import("../canvas.js").StrokeState>}\n */\n\n this.strokeStates = instructions.strokeStates || {};\n /**\n * @type {!Object<string, import("../canvas.js").TextState>}\n */\n\n this.textStates = instructions.textStates || {};\n /**\n * @private\n * @type {Object<string, Object<string, number>>}\n */\n\n this.widths_ = {};\n /**\n * @private\n * @type {Object<string, import("../canvas.js").Label>}\n */\n\n this.labels_ = {};\n }\n /**\n * @param {string} text Text.\n * @param {string} textKey Text style key.\n * @param {string} fillKey Fill style key.\n * @param {string} strokeKey Stroke style key.\n * @return {import("../canvas.js").Label} Label.\n */\n\n\n Executor.prototype.createLabel = function (text, textKey, fillKey, strokeKey) {\n var key = text + textKey + fillKey + strokeKey;\n\n if (this.labels_[key]) {\n return this.labels_[key];\n }\n\n var strokeState = strokeKey ? this.strokeStates[strokeKey] : null;\n var fillState = fillKey ? this.fillStates[fillKey] : null;\n var textState = this.textStates[textKey];\n var pixelRatio = this.pixelRatio;\n var scale = [textState.scale[0] * pixelRatio, textState.scale[1] * pixelRatio];\n var align = horizontalTextAlign(text, textState.textAlign || defaultTextAlign);\n var strokeWidth = strokeKey && strokeState.lineWidth ? strokeState.lineWidth : 0;\n var lines = text.split(\'\\n\');\n var numLines = lines.length;\n var widths = [];\n var width = measureTextWidths(textState.font, lines, widths);\n var lineHeight = measureTextHeight(textState.font);\n var height = lineHeight * numLines;\n var renderWidth = width + strokeWidth;\n var contextInstructions = []; // make canvas 2 pixels wider to account for italic text width measurement errors\n\n var w = (renderWidth + 2) * scale[0];\n var h = (height + strokeWidth) * scale[1];\n /** @type {import("../canvas.js").Label} */\n\n var label = {\n width: w < 0 ? Math.floor(w) : Math.ceil(w),\n height: h < 0 ? Math.floor(h) : Math.ceil(h),\n contextInstructions: contextInstructions\n };\n\n if (scale[0] != 1 || scale[1] != 1) {\n contextInstructions.push(\'scale\', scale);\n }\n\n contextInstructions.push(\'font\', textState.font);\n\n if (strokeKey) {\n contextInstructions.push(\'strokeStyle\', strokeState.strokeStyle);\n contextInstructions.push(\'lineWidth\', strokeWidth);\n contextInstructions.push(\'lineCap\', strokeState.lineCap);\n contextInstructions.push(\'lineJoin\', strokeState.lineJoin);\n contextInstructions.push(\'miterLimit\', strokeState.miterLimit); // eslint-disable-next-line\n\n var Context = WORKER_OFFSCREEN_CANVAS ? OffscreenCanvasRenderingContext2D : CanvasRenderingContext2D;\n\n if (Context.prototype.setLineDash) {\n contextInstructions.push(\'setLineDash\', [strokeState.lineDash]);\n contextInstructions.push(\'lineDashOffset\', strokeState.lineDashOffset);\n }\n }\n\n if (fillKey) {\n contextInstructions.push(\'fillStyle\', fillState.fillStyle);\n }\n\n contextInstructions.push(\'textBaseline\', \'middle\');\n contextInstructions.push(\'textAlign\', \'center\');\n var leftRight = 0.5 - align;\n var x = align * renderWidth + leftRight * strokeWidth;\n var i;\n\n if (strokeKey) {\n for (i = 0; i < numLines; ++i) {\n contextInstructions.push(\'strokeText\', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);\n }\n }\n\n if (fillKey) {\n for (i = 0; i < numLines; ++i) {\n contextInstructions.push(\'fillText\', [lines[i], x + leftRight * widths[i], 0.5 * (strokeWidth + lineHeight) + i * lineHeight]);\n }\n }\n\n this.labels_[key] = label;\n return label;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../coordinate.js").Coordinate} p1 1st point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p2 2nd point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p3 3rd point of the background box.\n * @param {import("../../coordinate.js").Coordinate} p4 4th point of the background box.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n */\n\n\n Executor.prototype.replayTextBackground_ = function (context, p1, p2, p3, p4, fillInstruction, strokeInstruction) {\n context.beginPath();\n context.moveTo.apply(context, p1);\n context.lineTo.apply(context, p2);\n context.lineTo.apply(context, p3);\n context.lineTo.apply(context, p4);\n context.lineTo.apply(context, p1);\n\n if (fillInstruction) {\n this.alignFill_ =\n /** @type {boolean} */\n fillInstruction[2];\n this.fill_(context);\n }\n\n if (strokeInstruction) {\n this.setStrokeStyle_(context,\n /** @type {Array<*>} */\n strokeInstruction);\n context.stroke();\n }\n };\n /**\n * @private\n * @param {number} sheetWidth Width of the sprite sheet.\n * @param {number} sheetHeight Height of the sprite sheet.\n * @param {number} centerX X.\n * @param {number} centerY Y.\n * @param {number} width Width.\n * @param {number} height Height.\n * @param {number} anchorX Anchor X.\n * @param {number} anchorY Anchor Y.\n * @param {number} originX Origin X.\n * @param {number} originY Origin Y.\n * @param {number} rotation Rotation.\n * @param {import("../../size.js").Size} scale Scale.\n * @param {boolean} snapToPixel Snap to pixel.\n * @param {Array<number>} padding Padding.\n * @param {boolean} fillStroke Background fill or stroke.\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @return {ImageOrLabelDimensions} Dimensions for positioning and decluttering the image or label.\n */\n\n\n Executor.prototype.calculateImageOrLabelDimensions_ = function (sheetWidth, sheetHeight, centerX, centerY, width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, fillStroke, feature) {\n anchorX *= scale[0];\n anchorY *= scale[1];\n var x = centerX - anchorX;\n var y = centerY - anchorY;\n var w = width + originX > sheetWidth ? sheetWidth - originX : width;\n var h = height + originY > sheetHeight ? sheetHeight - originY : height;\n var boxW = padding[3] + w * scale[0] + padding[1];\n var boxH = padding[0] + h * scale[1] + padding[2];\n var boxX = x - padding[3];\n var boxY = y - padding[0];\n\n if (fillStroke || rotation !== 0) {\n p1[0] = boxX;\n p4[0] = boxX;\n p1[1] = boxY;\n p2[1] = boxY;\n p2[0] = boxX + boxW;\n p3[0] = p2[0];\n p3[1] = boxY + boxH;\n p4[1] = p3[1];\n }\n\n var transform;\n\n if (rotation !== 0) {\n transform = compose(create(), centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n apply(transform, p1);\n apply(transform, p2);\n apply(transform, p3);\n apply(transform, p4);\n createOrUpdate(Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), Math.max(p1[0], p2[0], p3[0], p4[0]), Math.max(p1[1], p2[1], p3[1], p4[1]), tmpExtent);\n } else {\n createOrUpdate(Math.min(boxX, boxX + boxW), Math.min(boxY, boxY + boxH), Math.max(boxX, boxX + boxW), Math.max(boxY, boxY + boxH), tmpExtent);\n }\n\n if (snapToPixel) {\n x = Math.round(x);\n y = Math.round(y);\n }\n\n return {\n drawImageX: x,\n drawImageY: y,\n drawImageW: w,\n drawImageH: h,\n originX: originX,\n originY: originY,\n declutterBox: {\n minX: tmpExtent[0],\n minY: tmpExtent[1],\n maxX: tmpExtent[2],\n maxY: tmpExtent[3],\n value: feature\n },\n canvasTransform: transform,\n scale: scale\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../canvas.js").Label|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} imageOrLabel Image.\n * @param {ImageOrLabelDimensions} dimensions Dimensions.\n * @param {number} opacity Opacity.\n * @param {Array<*>} fillInstruction Fill instruction.\n * @param {Array<*>} strokeInstruction Stroke instruction.\n * @return {boolean} The image or label was rendered.\n */\n\n\n Executor.prototype.replayImageOrLabel_ = function (context, contextScale, imageOrLabel, dimensions, opacity, fillInstruction, strokeInstruction) {\n var fillStroke = !!(fillInstruction || strokeInstruction);\n var box = dimensions.declutterBox;\n var canvas = context.canvas;\n var strokePadding = strokeInstruction ? strokeInstruction[2] * dimensions.scale[0] / 2 : 0;\n var intersects = box.minX - strokePadding <= canvas.width / contextScale && box.maxX + strokePadding >= 0 && box.minY - strokePadding <= canvas.height / contextScale && box.maxY + strokePadding >= 0;\n\n if (intersects) {\n if (fillStroke) {\n this.replayTextBackground_(context, p1, p2, p3, p4,\n /** @type {Array<*>} */\n fillInstruction,\n /** @type {Array<*>} */\n strokeInstruction);\n }\n\n drawImageOrLabel(context, dimensions.canvasTransform, opacity, imageOrLabel, dimensions.originX, dimensions.originY, dimensions.drawImageW, dimensions.drawImageH, dimensions.drawImageX, dimensions.drawImageY, dimensions.scale);\n }\n\n return true;\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n */\n\n\n Executor.prototype.fill_ = function (context) {\n if (this.alignFill_) {\n var origin_1 = apply(this.renderedTransform_, [0, 0]);\n var repeatSize = 512 * this.pixelRatio;\n context.save();\n context.translate(origin_1[0] % repeatSize, origin_1[1] % repeatSize);\n context.rotate(this.viewRotation_);\n }\n\n context.fill();\n\n if (this.alignFill_) {\n context.restore();\n }\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {Array<*>} instruction Instruction.\n */\n\n\n Executor.prototype.setStrokeStyle_ = function (context, instruction) {\n context[\'strokeStyle\'] =\n /** @type {import("../../colorlike.js").ColorLike} */\n instruction[1];\n context.lineWidth =\n /** @type {number} */\n instruction[2];\n context.lineCap =\n /** @type {CanvasLineCap} */\n instruction[3];\n context.lineJoin =\n /** @type {CanvasLineJoin} */\n instruction[4];\n context.miterLimit =\n /** @type {number} */\n instruction[5];\n\n if (context.setLineDash) {\n context.lineDashOffset =\n /** @type {number} */\n instruction[7];\n context.setLineDash(\n /** @type {Array<number>} */\n instruction[6]);\n }\n };\n /**\n * @private\n * @param {string} text The text to draw.\n * @param {string} textKey The key of the text state.\n * @param {string} strokeKey The key for the stroke state.\n * @param {string} fillKey The key for the fill state.\n * @return {{label: import("../canvas.js").Label, anchorX: number, anchorY: number}} The text image and its anchor.\n */\n\n\n Executor.prototype.drawLabelWithPointPlacement_ = function (text, textKey, strokeKey, fillKey) {\n var textState = this.textStates[textKey];\n var label = this.createLabel(text, textKey, fillKey, strokeKey);\n var strokeState = this.strokeStates[strokeKey];\n var pixelRatio = this.pixelRatio;\n var align = horizontalTextAlign(text, textState.textAlign || defaultTextAlign);\n var baseline = TEXT_ALIGN[textState.textBaseline || defaultTextBaseline];\n var strokeWidth = strokeState && strokeState.lineWidth ? strokeState.lineWidth : 0; // Remove the 2 pixels we added in createLabel() for the anchor\n\n var width = label.width / pixelRatio - 2 * textState.scale[0];\n var anchorX = align * width + 2 * (0.5 - align) * strokeWidth;\n var anchorY = baseline * label.height / pixelRatio + 2 * (0.5 - baseline) * strokeWidth;\n return {\n label: label,\n anchorX: anchorX,\n anchorY: anchorY\n };\n };\n /**\n * @private\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {Array<*>} instructions Instructions array.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {FeatureCallback<T>=} opt_featureCallback Feature callback.\n * @param {import("../../extent.js").Extent=} opt_hitExtent Only check\n * features that intersect this extent.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n Executor.prototype.execute_ = function (context, contextScale, transform, instructions, snapToPixel, opt_featureCallback, opt_hitExtent, opt_declutterTree) {\n /** @type {Array<number>} */\n var pixelCoordinates;\n\n if (this.pixelCoordinates_ && equals(transform, this.renderedTransform_)) {\n pixelCoordinates = this.pixelCoordinates_;\n } else {\n if (!this.pixelCoordinates_) {\n this.pixelCoordinates_ = [];\n }\n\n pixelCoordinates = transform2D(this.coordinates, 0, this.coordinates.length, 2, transform, this.pixelCoordinates_);\n setFromArray(this.renderedTransform_, transform);\n }\n\n var i = 0; // instruction index\n\n var ii = instructions.length; // end of instructions\n\n var d = 0; // data index\n\n var dd; // end of per-instruction data\n\n var anchorX, anchorY, prevX, prevY, roundX, roundY, image, text, textKey, strokeKey, fillKey;\n var pendingFill = 0;\n var pendingStroke = 0;\n var lastFillInstruction = null;\n var lastStrokeInstruction = null;\n var coordinateCache = this.coordinateCache_;\n var viewRotation = this.viewRotation_;\n var viewRotationFromTransform = Math.round(Math.atan2(-transform[1], transform[0]) * 1e12) / 1e12;\n var state =\n /** @type {import("../../render.js").State} */\n {\n context: context,\n pixelRatio: this.pixelRatio,\n resolution: this.resolution,\n rotation: viewRotation\n }; // When the batch size gets too big, performance decreases. 200 is a good\n // balance between batch size and number of fill/stroke instructions.\n\n var batchSize = this.instructions != instructions || this.overlaps ? 0 : 200;\n var\n /** @type {import("../../Feature.js").FeatureLike} */\n feature;\n var x, y, currentGeometry;\n\n while (i < ii) {\n var instruction = instructions[i];\n var type =\n /** @type {import("./Instruction.js").default} */\n instruction[0];\n\n switch (type) {\n case canvas_Instruction.BEGIN_GEOMETRY:\n feature =\n /** @type {import("../../Feature.js").FeatureLike} */\n instruction[1];\n currentGeometry = instruction[3];\n\n if (!feature.getGeometry()) {\n i =\n /** @type {number} */\n instruction[2];\n } else if (opt_hitExtent !== undefined && !intersects(opt_hitExtent, currentGeometry.getExtent())) {\n i =\n /** @type {number} */\n instruction[2] + 1;\n } else {\n ++i;\n }\n\n break;\n\n case canvas_Instruction.BEGIN_PATH:\n if (pendingFill > batchSize) {\n this.fill_(context);\n pendingFill = 0;\n }\n\n if (pendingStroke > batchSize) {\n context.stroke();\n pendingStroke = 0;\n }\n\n if (!pendingFill && !pendingStroke) {\n context.beginPath();\n prevX = NaN;\n prevY = NaN;\n }\n\n ++i;\n break;\n\n case canvas_Instruction.CIRCLE:\n d =\n /** @type {number} */\n instruction[1];\n var x1 = pixelCoordinates[d];\n var y1 = pixelCoordinates[d + 1];\n var x2 = pixelCoordinates[d + 2];\n var y2 = pixelCoordinates[d + 3];\n var dx = x2 - x1;\n var dy = y2 - y1;\n var r = Math.sqrt(dx * dx + dy * dy);\n context.moveTo(x1 + r, y1);\n context.arc(x1, y1, r, 0, 2 * Math.PI, true);\n ++i;\n break;\n\n case canvas_Instruction.CLOSE_PATH:\n context.closePath();\n ++i;\n break;\n\n case canvas_Instruction.CUSTOM:\n d =\n /** @type {number} */\n instruction[1];\n dd = instruction[2];\n var geometry =\n /** @type {import("../../geom/SimpleGeometry.js").default} */\n instruction[3];\n var renderer = instruction[4];\n var fn = instruction.length == 6 ? instruction[5] : undefined;\n state.geometry = geometry;\n state.feature = feature;\n\n if (!(i in coordinateCache)) {\n coordinateCache[i] = [];\n }\n\n var coords = coordinateCache[i];\n\n if (fn) {\n fn(pixelCoordinates, d, dd, 2, coords);\n } else {\n coords[0] = pixelCoordinates[d];\n coords[1] = pixelCoordinates[d + 1];\n coords.length = 2;\n }\n\n renderer(coords, state);\n ++i;\n break;\n\n case canvas_Instruction.DRAW_IMAGE:\n d =\n /** @type {number} */\n instruction[1];\n dd =\n /** @type {number} */\n instruction[2];\n image =\n /** @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement} */\n instruction[3]; // Remaining arguments in DRAW_IMAGE are in alphabetical order\n\n anchorX =\n /** @type {number} */\n instruction[4];\n anchorY =\n /** @type {number} */\n instruction[5];\n var height =\n /** @type {number} */\n instruction[6];\n var opacity =\n /** @type {number} */\n instruction[7];\n var originX =\n /** @type {number} */\n instruction[8];\n var originY =\n /** @type {number} */\n instruction[9];\n var rotateWithView =\n /** @type {boolean} */\n instruction[10];\n var rotation =\n /** @type {number} */\n instruction[11];\n var scale =\n /** @type {import("../../size.js").Size} */\n instruction[12];\n var width =\n /** @type {number} */\n instruction[13];\n var declutterImageWithText =\n /** @type {import("../canvas.js").DeclutterImageWithText} */\n instruction[14];\n\n if (!image && instruction.length >= 19) {\n // create label images\n text =\n /** @type {string} */\n instruction[18];\n textKey =\n /** @type {string} */\n instruction[19];\n strokeKey =\n /** @type {string} */\n instruction[20];\n fillKey =\n /** @type {string} */\n instruction[21];\n var labelWithAnchor = this.drawLabelWithPointPlacement_(text, textKey, strokeKey, fillKey);\n image = labelWithAnchor.label;\n instruction[3] = image;\n var textOffsetX =\n /** @type {number} */\n instruction[22];\n anchorX = (labelWithAnchor.anchorX - textOffsetX) * this.pixelRatio;\n instruction[4] = anchorX;\n var textOffsetY =\n /** @type {number} */\n instruction[23];\n anchorY = (labelWithAnchor.anchorY - textOffsetY) * this.pixelRatio;\n instruction[5] = anchorY;\n height = image.height;\n instruction[6] = height;\n width = image.width;\n instruction[13] = width;\n }\n\n var geometryWidths = void 0;\n\n if (instruction.length > 24) {\n geometryWidths =\n /** @type {number} */\n instruction[24];\n }\n\n var padding = void 0,\n backgroundFill = void 0,\n backgroundStroke = void 0;\n\n if (instruction.length > 16) {\n padding =\n /** @type {Array<number>} */\n instruction[15];\n backgroundFill =\n /** @type {boolean} */\n instruction[16];\n backgroundStroke =\n /** @type {boolean} */\n instruction[17];\n } else {\n padding = defaultPadding;\n backgroundFill = false;\n backgroundStroke = false;\n }\n\n if (rotateWithView && viewRotationFromTransform) {\n // Canvas is expected to be rotated to reverse view rotation.\n rotation += viewRotation;\n } else if (!rotateWithView && !viewRotationFromTransform) {\n // Canvas is not rotated, images need to be rotated back to be north-up.\n rotation -= viewRotation;\n }\n\n var widthIndex = 0;\n\n for (; d < dd; d += 2) {\n if (geometryWidths && geometryWidths[widthIndex++] < width / this.pixelRatio) {\n continue;\n }\n\n var dimensions = this.calculateImageOrLabelDimensions_(image.width, image.height, pixelCoordinates[d], pixelCoordinates[d + 1], width, height, anchorX, anchorY, originX, originY, rotation, scale, snapToPixel, padding, backgroundFill || backgroundStroke, feature);\n /** @type {ReplayImageOrLabelArgs} */\n\n var args = [context, contextScale, image, dimensions, opacity, backgroundFill ?\n /** @type {Array<*>} */\n lastFillInstruction : null, backgroundStroke ?\n /** @type {Array<*>} */\n lastStrokeInstruction : null];\n var imageArgs = void 0;\n var imageDeclutterBox = void 0;\n\n if (opt_declutterTree && declutterImageWithText) {\n if (!declutterImageWithText[d]) {\n // We now have the image for an image+text combination.\n declutterImageWithText[d] = args; // Don\'t render anything for now, wait for the text.\n\n continue;\n }\n\n imageArgs = declutterImageWithText[d];\n delete declutterImageWithText[d];\n imageDeclutterBox = getDeclutterBox(imageArgs);\n\n if (opt_declutterTree.collides(imageDeclutterBox)) {\n continue;\n }\n }\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n continue;\n }\n\n if (imageArgs) {\n // We now have image and text for an image+text combination.\n if (opt_declutterTree) {\n opt_declutterTree.insert(imageDeclutterBox);\n } // Render the image before we render the text.\n\n\n this.replayImageOrLabel_.apply(this, imageArgs);\n }\n\n if (opt_declutterTree) {\n opt_declutterTree.insert(dimensions.declutterBox);\n }\n\n this.replayImageOrLabel_.apply(this, args);\n }\n\n ++i;\n break;\n\n case canvas_Instruction.DRAW_CHARS:\n var begin =\n /** @type {number} */\n instruction[1];\n var end =\n /** @type {number} */\n instruction[2];\n var baseline =\n /** @type {number} */\n instruction[3];\n var overflow =\n /** @type {number} */\n instruction[4];\n fillKey =\n /** @type {string} */\n instruction[5];\n var maxAngle =\n /** @type {number} */\n instruction[6];\n var measurePixelRatio =\n /** @type {number} */\n instruction[7];\n var offsetY =\n /** @type {number} */\n instruction[8];\n strokeKey =\n /** @type {string} */\n instruction[9];\n var strokeWidth =\n /** @type {number} */\n instruction[10];\n text =\n /** @type {string} */\n instruction[11];\n textKey =\n /** @type {string} */\n instruction[12];\n var pixelRatioScale = [\n /** @type {number} */\n instruction[13],\n /** @type {number} */\n instruction[13]];\n var textState = this.textStates[textKey];\n var font = textState.font;\n var textScale = [textState.scale[0] * measurePixelRatio, textState.scale[1] * measurePixelRatio];\n var cachedWidths = void 0;\n\n if (font in this.widths_) {\n cachedWidths = this.widths_[font];\n } else {\n cachedWidths = {};\n this.widths_[font] = cachedWidths;\n }\n\n var pathLength = lineStringLength(pixelCoordinates, begin, end, 2);\n var textLength = Math.abs(textScale[0]) * measureAndCacheTextWidth(font, text, cachedWidths);\n\n if (overflow || textLength <= pathLength) {\n var textAlign = this.textStates[textKey].textAlign;\n var startM = (pathLength - textLength) * TEXT_ALIGN[textAlign];\n var parts = drawTextOnPath(pixelCoordinates, begin, end, 2, text, startM, maxAngle, Math.abs(textScale[0]), measureAndCacheTextWidth, font, cachedWidths, viewRotationFromTransform ? 0 : this.viewRotation_);\n\n drawChars: if (parts) {\n /** @type {Array<ReplayImageOrLabelArgs>} */\n var replayImageOrLabelArgs = [];\n var c = void 0,\n cc = void 0,\n chars = void 0,\n label = void 0,\n part = void 0;\n\n if (strokeKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n\n chars =\n /** @type {string} */\n part[4];\n label = this.createLabel(chars, textKey, \'\', strokeKey);\n anchorX =\n /** @type {number} */\n part[2] + (textScale[0] < 0 ? -strokeWidth : strokeWidth);\n anchorY = baseline * label.height + (0.5 - baseline) * 2 * strokeWidth * textScale[1] / textScale[0] - offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n\n replayImageOrLabelArgs.push([context, contextScale, label, dimensions, 1, null, null]);\n }\n }\n\n if (fillKey) {\n for (c = 0, cc = parts.length; c < cc; ++c) {\n part = parts[c]; // x, y, anchorX, rotation, chunk\n\n chars =\n /** @type {string} */\n part[4];\n label = this.createLabel(chars, textKey, fillKey, \'\');\n anchorX =\n /** @type {number} */\n part[2];\n anchorY = baseline * label.height - offsetY;\n var dimensions = this.calculateImageOrLabelDimensions_(label.width, label.height, part[0], part[1], label.width, label.height, anchorX, anchorY, 0, 0, part[3], pixelRatioScale, false, defaultPadding, false, feature);\n\n if (opt_declutterTree && opt_declutterTree.collides(dimensions.declutterBox)) {\n break drawChars;\n }\n\n replayImageOrLabelArgs.push([context, contextScale, label, dimensions, 1, null, null]);\n }\n }\n\n if (opt_declutterTree) {\n opt_declutterTree.load(replayImageOrLabelArgs.map(getDeclutterBox));\n }\n\n for (var i_1 = 0, ii_1 = replayImageOrLabelArgs.length; i_1 < ii_1; ++i_1) {\n this.replayImageOrLabel_.apply(this, replayImageOrLabelArgs[i_1]);\n }\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.END_GEOMETRY:\n if (opt_featureCallback !== undefined) {\n feature =\n /** @type {import("../../Feature.js").FeatureLike} */\n instruction[1];\n var result = opt_featureCallback(feature, currentGeometry);\n\n if (result) {\n return result;\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.FILL:\n if (batchSize) {\n pendingFill++;\n } else {\n this.fill_(context);\n }\n\n ++i;\n break;\n\n case canvas_Instruction.MOVE_TO_LINE_TO:\n d =\n /** @type {number} */\n instruction[1];\n dd =\n /** @type {number} */\n instruction[2];\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = x + 0.5 | 0;\n roundY = y + 0.5 | 0;\n\n if (roundX !== prevX || roundY !== prevY) {\n context.moveTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n\n for (d += 2; d < dd; d += 2) {\n x = pixelCoordinates[d];\n y = pixelCoordinates[d + 1];\n roundX = x + 0.5 | 0;\n roundY = y + 0.5 | 0;\n\n if (d == dd - 2 || roundX !== prevX || roundY !== prevY) {\n context.lineTo(x, y);\n prevX = roundX;\n prevY = roundY;\n }\n }\n\n ++i;\n break;\n\n case canvas_Instruction.SET_FILL_STYLE:\n lastFillInstruction = instruction;\n this.alignFill_ = instruction[2];\n\n if (pendingFill) {\n this.fill_(context);\n pendingFill = 0;\n\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n }\n\n context.fillStyle =\n /** @type {import("../../colorlike.js").ColorLike} */\n instruction[1];\n ++i;\n break;\n\n case canvas_Instruction.SET_STROKE_STYLE:\n lastStrokeInstruction = instruction;\n\n if (pendingStroke) {\n context.stroke();\n pendingStroke = 0;\n }\n\n this.setStrokeStyle_(context,\n /** @type {Array<*>} */\n instruction);\n ++i;\n break;\n\n case canvas_Instruction.STROKE:\n if (batchSize) {\n pendingStroke++;\n } else {\n context.stroke();\n }\n\n ++i;\n break;\n\n default:\n ++i; // consume the instruction anyway, to avoid an infinite loop\n\n break;\n }\n }\n\n if (pendingFill) {\n this.fill_(context);\n }\n\n if (pendingStroke) {\n context.stroke();\n }\n\n return undefined;\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and text to integer pixels.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n Executor.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree) {\n this.viewRotation_ = viewRotation;\n this.execute_(context, contextScale, transform, this.instructions, snapToPixel, undefined, undefined, opt_declutterTree);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {FeatureCallback<T>=} opt_featureCallback Feature callback.\n * @param {import("../../extent.js").Extent=} opt_hitExtent Only check\n * features that intersect this extent.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n Executor.prototype.executeHitDetection = function (context, transform, viewRotation, opt_featureCallback, opt_hitExtent) {\n this.viewRotation_ = viewRotation;\n return this.execute_(context, 1, transform, this.hitDetectionInstructions, true, opt_featureCallback, opt_hitExtent);\n };\n\n return Executor;\n}();\n\n/* harmony default export */ var canvas_Executor = (Executor);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/ExecutorGroup.js\n/**\n * @module ol/render/canvas/ExecutorGroup\n */\n\n\n\n\n\n\n\n\n/**\n * @const\n * @type {Array<import("./BuilderType.js").default>}\n */\n\nvar ORDER = [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT];\n\nvar ExecutorGroup =\n/** @class */\nfunction () {\n /**\n * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a\n * `maxExtent` was set on the Buillder for this executor group, the same `maxExtent`\n * should be set here, unless the target context does not exceet that extent (which\n * can be the case when rendering to tiles).\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {boolean} overlaps The executor group can have overlapping geometries.\n * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions\n * The serializable instructions.\n * @param {number=} opt_renderBuffer Optional rendering buffer.\n */\n function ExecutorGroup(maxExtent, resolution, pixelRatio, overlaps, allInstructions, opt_renderBuffer) {\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n this.maxExtent_ = maxExtent;\n /**\n * @private\n * @type {boolean}\n */\n\n this.overlaps_ = overlaps;\n /**\n * @private\n * @type {number}\n */\n\n this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n this.resolution_ = resolution;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.renderBuffer_ = opt_renderBuffer;\n /**\n * @private\n * @type {!Object<string, !Object<import("./BuilderType.js").default, import("./Executor").default>>}\n */\n\n this.executorsByZIndex_ = {};\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n\n this.hitDetectionContext_ = null;\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n this.hitDetectionTransform_ = create();\n this.createExecutors_(allInstructions);\n }\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import("../../transform.js").Transform} transform Transform.\n */\n\n\n ExecutorGroup.prototype.clip = function (context, transform) {\n var flatClipCoords = this.getClipCoords(transform);\n context.beginPath();\n context.moveTo(flatClipCoords[0], flatClipCoords[1]);\n context.lineTo(flatClipCoords[2], flatClipCoords[3]);\n context.lineTo(flatClipCoords[4], flatClipCoords[5]);\n context.lineTo(flatClipCoords[6], flatClipCoords[7]);\n context.clip();\n };\n /**\n * Create executors and populate them using the provided instructions.\n * @private\n * @param {!Object<string, !Object<import("./BuilderType.js").default, import("../canvas.js").SerializableInstructions>>} allInstructions The serializable instructions\n */\n\n\n ExecutorGroup.prototype.createExecutors_ = function (allInstructions) {\n for (var zIndex in allInstructions) {\n var executors = this.executorsByZIndex_[zIndex];\n\n if (executors === undefined) {\n executors = {};\n this.executorsByZIndex_[zIndex] = executors;\n }\n\n var instructionByZindex = allInstructions[zIndex];\n var renderBuffer = [this.renderBuffer_ || 0, this.renderBuffer_ || 0];\n\n for (var builderType in instructionByZindex) {\n var instructions = instructionByZindex[builderType];\n executors[builderType] = new canvas_Executor(this.resolution_, this.pixelRatio_, this.overlaps_, instructions, renderBuffer);\n }\n }\n };\n /**\n * @param {Array<import("./BuilderType.js").default>} executors Executors.\n * @return {boolean} Has executors of the provided types.\n */\n\n\n ExecutorGroup.prototype.hasExecutors = function (executors) {\n for (var zIndex in this.executorsByZIndex_) {\n var candidates = this.executorsByZIndex_[zIndex];\n\n for (var i = 0, ii = executors.length; i < ii; ++i) {\n if (executors[i] in candidates) {\n return true;\n }\n }\n }\n\n return false;\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {function(import("../../Feature.js").FeatureLike, import("../../geom/SimpleGeometry.js").default, number): T} callback Feature callback.\n * @param {Array<import("../../Feature.js").FeatureLike>} declutteredFeatures Decluttered features.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n ExecutorGroup.prototype.forEachFeatureAtCoordinate = function (coordinate, resolution, rotation, hitTolerance, callback, declutteredFeatures) {\n hitTolerance = Math.round(hitTolerance);\n var contextSize = hitTolerance * 2 + 1;\n var transform = compose(this.hitDetectionTransform_, hitTolerance + 0.5, hitTolerance + 0.5, 1 / resolution, -1 / resolution, -rotation, -coordinate[0], -coordinate[1]);\n var newContext = !this.hitDetectionContext_;\n\n if (newContext) {\n this.hitDetectionContext_ = createCanvasContext2D(contextSize, contextSize);\n }\n\n var context = this.hitDetectionContext_;\n\n if (context.canvas.width !== contextSize || context.canvas.height !== contextSize) {\n context.canvas.width = contextSize;\n context.canvas.height = contextSize;\n } else if (!newContext) {\n context.clearRect(0, 0, contextSize, contextSize);\n }\n /**\n * @type {import("../../extent.js").Extent}\n */\n\n\n var hitExtent;\n\n if (this.renderBuffer_ !== undefined) {\n hitExtent = createEmpty();\n extendCoordinate(hitExtent, coordinate);\n buffer(hitExtent, resolution * (this.renderBuffer_ + hitTolerance), hitExtent);\n }\n\n var indexes = getPixelIndexArray(hitTolerance);\n var builderType;\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n\n function featureCallback(feature, geometry) {\n var imageData = context.getImageData(0, 0, contextSize, contextSize).data;\n\n for (var i_1 = 0, ii = indexes.length; i_1 < ii; i_1++) {\n if (imageData[indexes[i_1]] > 0) {\n if (!declutteredFeatures || builderType !== BuilderType.IMAGE && builderType !== BuilderType.TEXT || declutteredFeatures.indexOf(feature) !== -1) {\n var idx = (indexes[i_1] - 3) / 4;\n var x = hitTolerance - idx % contextSize;\n var y = hitTolerance - (idx / contextSize | 0);\n var result_1 = callback(feature, geometry, x * x + y * y);\n\n if (result_1) {\n return result_1;\n }\n }\n\n context.clearRect(0, 0, contextSize, contextSize);\n break;\n }\n }\n\n return undefined;\n }\n /** @type {Array<number>} */\n\n\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction);\n var i, j, executors, executor, result;\n\n for (i = zs.length - 1; i >= 0; --i) {\n var zIndexKey = zs[i].toString();\n executors = this.executorsByZIndex_[zIndexKey];\n\n for (j = ORDER.length - 1; j >= 0; --j) {\n builderType = ORDER[j];\n executor = executors[builderType];\n\n if (executor !== undefined) {\n result = executor.executeHitDetection(context, transform, rotation, featureCallback, hitExtent);\n\n if (result) {\n return result;\n }\n }\n }\n }\n\n return undefined;\n };\n /**\n * @param {import("../../transform.js").Transform} transform Transform.\n * @return {Array<number>} Clip coordinates.\n */\n\n\n ExecutorGroup.prototype.getClipCoords = function (transform) {\n var maxExtent = this.maxExtent_;\n\n if (!maxExtent) {\n return null;\n }\n\n var minX = maxExtent[0];\n var minY = maxExtent[1];\n var maxX = maxExtent[2];\n var maxY = maxExtent[3];\n var flatClipCoords = [minX, minY, minX, maxY, maxX, maxY, maxX, minY];\n transform2D(flatClipCoords, 0, 8, 2, transform, flatClipCoords);\n return flatClipCoords;\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n ExecutorGroup.prototype.isEmpty = function () {\n return obj_isEmpty(this.executorsByZIndex_);\n };\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} contextScale Scale of the context.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {boolean} snapToPixel Snap point symbols and test to integer pixel.\n * @param {Array<import("./BuilderType.js").default>=} opt_builderTypes Ordered replay types to replay.\n * Default is {@link module:ol/render/replay~ORDER}\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n ExecutorGroup.prototype.execute = function (context, contextScale, transform, viewRotation, snapToPixel, opt_builderTypes, opt_declutterTree) {\n /** @type {Array<number>} */\n var zs = Object.keys(this.executorsByZIndex_).map(Number);\n zs.sort(numberSafeCompareFunction); // setup clipping so that the parts of over-simplified geometries are not\n // visible outside the current extent when panning\n\n if (this.maxExtent_) {\n context.save();\n this.clip(context, transform);\n }\n\n var builderTypes = opt_builderTypes ? opt_builderTypes : ORDER;\n var i, ii, j, jj, replays, replay;\n\n if (opt_declutterTree) {\n zs.reverse();\n }\n\n for (i = 0, ii = zs.length; i < ii; ++i) {\n var zIndexKey = zs[i].toString();\n replays = this.executorsByZIndex_[zIndexKey];\n\n for (j = 0, jj = builderTypes.length; j < jj; ++j) {\n var builderType = builderTypes[j];\n replay = replays[builderType];\n\n if (replay !== undefined) {\n replay.execute(context, contextScale, transform, viewRotation, snapToPixel, opt_declutterTree);\n }\n }\n }\n\n if (this.maxExtent_) {\n context.restore();\n }\n };\n\n return ExecutorGroup;\n}();\n/**\n * This cache is used to store arrays of indexes for calculated pixel circles\n * to increase performance.\n * It is a static property to allow each Replaygroup to access it.\n * @type {Object<number, Array<number>>}\n */\n\n\nvar circlePixelIndexArrayCache = {};\n/**\n * This methods creates an array with indexes of all pixels within a circle,\n * ordered by how close they are to the center.\n * A cache is used to increase performance.\n * @param {number} radius Radius.\n * @returns {Array<number>} An array with indexes within a circle.\n */\n\nfunction getPixelIndexArray(radius) {\n if (circlePixelIndexArrayCache[radius] !== undefined) {\n return circlePixelIndexArrayCache[radius];\n }\n\n var size = radius * 2 + 1;\n var maxDistanceSq = radius * radius;\n var distances = new Array(maxDistanceSq + 1);\n\n for (var i = 0; i <= radius; ++i) {\n for (var j = 0; j <= radius; ++j) {\n var distanceSq = i * i + j * j;\n\n if (distanceSq > maxDistanceSq) {\n break;\n }\n\n var distance = distances[distanceSq];\n\n if (!distance) {\n distance = [];\n distances[distanceSq] = distance;\n }\n\n distance.push(((radius + i) * size + (radius + j)) * 4 + 3);\n\n if (i > 0) {\n distance.push(((radius - i) * size + (radius + j)) * 4 + 3);\n }\n\n if (j > 0) {\n distance.push(((radius + i) * size + (radius - j)) * 4 + 3);\n\n if (i > 0) {\n distance.push(((radius - i) * size + (radius - j)) * 4 + 3);\n }\n }\n }\n }\n\n var pixelIndex = [];\n\n for (var i = 0, ii = distances.length; i < ii; ++i) {\n if (distances[i]) {\n pixelIndex.push.apply(pixelIndex, distances[i]);\n }\n }\n\n circlePixelIndexArrayCache[radius] = pixelIndex;\n return pixelIndex;\n}\n/* harmony default export */ var canvas_ExecutorGroup = (ExecutorGroup);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/Immediate.js\n/**\n * @module ol/render/canvas/Immediate\n */\n// FIXME test, especially polygons with holes and multipolygons\n// FIXME need to handle large thick features (where pixel size matters)\n// FIXME add offset and end to ol/geom/flat/transform~transform2D?\nvar Immediate_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * A concrete subclass of {@link module:ol/render/VectorContext} that implements\n * direct rendering of features and geometries to an HTML5 Canvas context.\n * Instances of this class are created internally by the library and\n * provided to application code as vectorContext member of the\n * {@link module:ol/render/Event~RenderEvent} object associated with postcompose, precompose and\n * render events emitted by layers and maps.\n */\n\nvar CanvasImmediateRenderer =\n/** @class */\nfunction (_super) {\n Immediate_extends(CanvasImmediateRenderer, _super);\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {import("../../transform.js").Transform} transform Transform.\n * @param {number} viewRotation View rotation.\n * @param {number=} opt_squaredTolerance Optional squared tolerance for simplification.\n * @param {import("../../proj.js").TransformFunction=} opt_userTransform Transform from user to view projection.\n */\n\n\n function CanvasImmediateRenderer(context, pixelRatio, extent, transform, viewRotation, opt_squaredTolerance, opt_userTransform) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {CanvasRenderingContext2D}\n */\n\n\n _this.context_ = context;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.extent_ = extent;\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.transform_ = transform;\n /**\n * @private\n * @type {number}\n */\n\n _this.viewRotation_ = viewRotation;\n /**\n * @private\n * @type {number}\n */\n\n _this.squaredTolerance_ = opt_squaredTolerance;\n /**\n * @private\n * @type {import("../../proj.js").TransformFunction}\n */\n\n _this.userTransform_ = opt_userTransform;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.contextFillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.contextStrokeState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").TextState}\n */\n\n _this.contextTextState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.fillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.strokeState_ = null;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLVideoElement|HTMLImageElement}\n */\n\n _this.image_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageAnchorX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageAnchorY_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageHeight_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOpacity_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOriginX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageOriginY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.imageRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.imageRotation_ = 0;\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n _this.imageScale_ = [0, 0];\n /**\n * @private\n * @type {number}\n */\n\n _this.imageWidth_ = 0;\n /**\n * @private\n * @type {string}\n */\n\n _this.text_ = \'\';\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetX_ = 0;\n /**\n * @private\n * @type {number}\n */\n\n _this.textOffsetY_ = 0;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.textRotateWithView_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.textRotation_ = 0;\n /**\n * @private\n * @type {import("../../size.js").Size}\n */\n\n _this.textScale_ = [0, 0];\n /**\n * @private\n * @type {?import("../canvas.js").FillState}\n */\n\n _this.textFillState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").StrokeState}\n */\n\n _this.textStrokeState_ = null;\n /**\n * @private\n * @type {?import("../canvas.js").TextState}\n */\n\n _this.textState_ = null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.pixelCoordinates_ = [];\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tmpLocalTransform_ = create();\n return _this;\n }\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.drawImages_ = function (flatCoordinates, offset, end, stride) {\n if (!this.image_) {\n return;\n }\n\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, 2, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var localTransform = this.tmpLocalTransform_;\n var alpha = context.globalAlpha;\n\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha * this.imageOpacity_;\n }\n\n var rotation = this.imageRotation_;\n\n if (this.imageRotateWithView_) {\n rotation += this.viewRotation_;\n }\n\n for (var i = 0, ii = pixelCoordinates.length; i < ii; i += 2) {\n var x = pixelCoordinates[i] - this.imageAnchorX_;\n var y = pixelCoordinates[i + 1] - this.imageAnchorY_;\n\n if (rotation !== 0 || this.imageScale_[0] != 1 || this.imageScale_[1] != 1) {\n var centerX = x + this.imageAnchorX_;\n var centerY = y + this.imageAnchorY_;\n compose(localTransform, centerX, centerY, 1, 1, rotation, -centerX, -centerY);\n context.setTransform.apply(context, localTransform);\n context.translate(centerX, centerY);\n context.scale(this.imageScale_[0], this.imageScale_[1]);\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, -this.imageAnchorX_, -this.imageAnchorY_, this.imageWidth_, this.imageHeight_);\n context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n context.drawImage(this.image_, this.imageOriginX_, this.imageOriginY_, this.imageWidth_, this.imageHeight_, x, y, this.imageWidth_, this.imageHeight_);\n }\n }\n\n if (this.imageOpacity_ != 1) {\n context.globalAlpha = alpha;\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.drawText_ = function (flatCoordinates, offset, end, stride) {\n if (!this.textState_ || this.text_ === \'\') {\n return;\n }\n\n if (this.textFillState_) {\n this.setContextFillState_(this.textFillState_);\n }\n\n if (this.textStrokeState_) {\n this.setContextStrokeState_(this.textStrokeState_);\n }\n\n this.setContextTextState_(this.textState_);\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n var context = this.context_;\n var rotation = this.textRotation_;\n\n if (this.textRotateWithView_) {\n rotation += this.viewRotation_;\n }\n\n for (; offset < end; offset += stride) {\n var x = pixelCoordinates[offset] + this.textOffsetX_;\n var y = pixelCoordinates[offset + 1] + this.textOffsetY_;\n\n if (rotation !== 0 || this.textScale_[0] != 1 || this.textScale_[1] != 1) {\n var localTransform = compose(this.tmpLocalTransform_, x, y, 1, 1, rotation, -x, -y);\n context.setTransform.apply(context, localTransform);\n context.translate(x, y);\n context.scale(this.textScale_[0], this.textScale_[1]);\n\n if (this.textStrokeState_) {\n context.strokeText(this.text_, 0, 0);\n }\n\n if (this.textFillState_) {\n context.fillText(this.text_, 0, 0);\n }\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n } else {\n if (this.textStrokeState_) {\n context.strokeText(this.text_, x, y);\n }\n\n if (this.textFillState_) {\n context.fillText(this.text_, x, y);\n }\n }\n }\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {boolean} close Close.\n * @private\n * @return {number} end End.\n */\n\n\n CanvasImmediateRenderer.prototype.moveToLineTo_ = function (flatCoordinates, offset, end, stride, close) {\n var context = this.context_;\n var pixelCoordinates = transform2D(flatCoordinates, offset, end, stride, this.transform_, this.pixelCoordinates_);\n context.moveTo(pixelCoordinates[0], pixelCoordinates[1]);\n var length = pixelCoordinates.length;\n\n if (close) {\n length -= 2;\n }\n\n for (var i = 2; i < length; i += 2) {\n context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);\n }\n\n if (close) {\n context.closePath();\n }\n\n return end;\n };\n /**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @private\n * @return {number} End.\n */\n\n\n CanvasImmediateRenderer.prototype.drawRings_ = function (flatCoordinates, offset, ends, stride) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, true);\n }\n\n return offset;\n };\n /**\n * Render a circle geometry into the canvas. Rendering is immediate and uses\n * the current fill and stroke styles.\n *\n * @param {import("../../geom/Circle.js").default} geometry Circle geometry.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawCircle = function (geometry) {\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.fillState_ || this.strokeState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var pixelCoordinates = transformGeom2D(geometry, this.transform_, this.pixelCoordinates_);\n var dx = pixelCoordinates[2] - pixelCoordinates[0];\n var dy = pixelCoordinates[3] - pixelCoordinates[1];\n var radius = Math.sqrt(dx * dx + dy * dy);\n var context = this.context_;\n context.beginPath();\n context.arc(pixelCoordinates[0], pixelCoordinates[1], radius, 0, 2 * Math.PI);\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(geometry.getCenter(), 0, 2, 2);\n }\n };\n /**\n * Set the rendering style. Note that since this is an immediate rendering API,\n * any `zIndex` on the provided style will be ignored.\n *\n * @param {import("../../style/Style.js").default} style The rendering style.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.setStyle = function (style) {\n this.setFillStrokeStyle(style.getFill(), style.getStroke());\n this.setImageStyle(style.getImage());\n this.setTextStyle(style.getText());\n };\n /**\n * @param {import("../../transform.js").Transform} transform Transform.\n */\n\n\n CanvasImmediateRenderer.prototype.setTransform = function (transform) {\n this.transform_ = transform;\n };\n /**\n * Render a geometry into the canvas. Call\n * {@link module:ol/render/canvas/Immediate#setStyle} first to set the rendering style.\n *\n * @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry The geometry to render.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawGeometry = function (geometry) {\n var type = geometry.getType();\n\n switch (type) {\n case geom_GeometryType.POINT:\n this.drawPoint(\n /** @type {import("../../geom/Point.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.LINE_STRING:\n this.drawLineString(\n /** @type {import("../../geom/LineString.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.POLYGON:\n this.drawPolygon(\n /** @type {import("../../geom/Polygon.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_POINT:\n this.drawMultiPoint(\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_LINE_STRING:\n this.drawMultiLineString(\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.MULTI_POLYGON:\n this.drawMultiPolygon(\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.GEOMETRY_COLLECTION:\n this.drawGeometryCollection(\n /** @type {import("../../geom/GeometryCollection.js").default} */\n geometry);\n break;\n\n case geom_GeometryType.CIRCLE:\n this.drawCircle(\n /** @type {import("../../geom/Circle.js").default} */\n geometry);\n break;\n\n default:\n }\n };\n /**\n * Render a feature into the canvas. Note that any `zIndex` on the provided\n * style will be ignored - features are rendered immediately in the order that\n * this method is called. If you need `zIndex` support, you should be using an\n * {@link module:ol/layer/Vector~VectorLayer} instead.\n *\n * @param {import("../../Feature.js").default} feature Feature.\n * @param {import("../../style/Style.js").default} style Style.\n * @api\n */\n\n\n CanvasImmediateRenderer.prototype.drawFeature = function (feature, style) {\n var geometry = style.getGeometryFunction()(feature);\n\n if (!geometry || !intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n this.setStyle(style);\n this.drawGeometry(geometry);\n };\n /**\n * Render a GeometryCollection to the canvas. Rendering is immediate and\n * uses the current styles appropriate for each geometry in the collection.\n *\n * @param {import("../../geom/GeometryCollection.js").default} geometry Geometry collection.\n */\n\n\n CanvasImmediateRenderer.prototype.drawGeometryCollection = function (geometry) {\n var geometries = geometry.getGeometriesArray();\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n this.drawGeometry(geometries[i]);\n }\n };\n /**\n * Render a Point geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/Point.js").default|import("../Feature.js").default} geometry Point geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/Point.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a MultiPoint geometry into the canvas. Rendering is immediate and\n * uses the current style.\n *\n * @param {import("../../geom/MultiPoint.js").default|import("../Feature.js").default} geometry MultiPoint geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiPoint = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiPoint.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var flatCoordinates = geometry.getFlatCoordinates();\n var stride = geometry.getStride();\n\n if (this.image_) {\n this.drawImages_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n\n if (this.text_ !== \'\') {\n this.drawText_(flatCoordinates, 0, flatCoordinates.length, stride);\n }\n };\n /**\n * Render a LineString into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/LineString.js").default|import("../Feature.js").default} geometry LineString geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/LineString.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n context.beginPath();\n this.moveToLineTo_(flatCoordinates, 0, flatCoordinates.length, geometry.getStride(), false);\n context.stroke();\n }\n\n if (this.text_ !== \'\') {\n var flatMidpoint = geometry.getFlatMidpoint();\n this.drawText_(flatMidpoint, 0, 2, 2);\n }\n };\n /**\n * Render a MultiLineString geometry into the canvas. Rendering is immediate\n * and uses the current style.\n *\n * @param {import("../../geom/MultiLineString.js").default|import("../Feature.js").default} geometry MultiLineString geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiLineString = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiLineString.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n var geometryExtent = geometry.getExtent();\n\n if (!intersects(this.extent_, geometryExtent)) {\n return;\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n var context = this.context_;\n var flatCoordinates = geometry.getFlatCoordinates();\n var offset = 0;\n var ends =\n /** @type {Array<number>} */\n geometry.getEnds();\n var stride = geometry.getStride();\n context.beginPath();\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n offset = this.moveToLineTo_(flatCoordinates, offset, ends[i], stride, false);\n }\n\n context.stroke();\n }\n\n if (this.text_ !== \'\') {\n var flatMidpoints = geometry.getFlatMidpoints();\n this.drawText_(flatMidpoints, 0, flatMidpoints.length, 2);\n }\n };\n /**\n * Render a Polygon geometry into the canvas. Rendering is immediate and uses\n * the current style.\n *\n * @param {import("../../geom/Polygon.js").default|import("../Feature.js").default} geometry Polygon geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/Polygon.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var context = this.context_;\n context.beginPath();\n this.drawRings_(geometry.getOrientedFlatCoordinates(), 0,\n /** @type {Array<number>} */\n geometry.getEnds(), geometry.getStride());\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n var flatInteriorPoint = geometry.getFlatInteriorPoint();\n this.drawText_(flatInteriorPoint, 0, 2, 2);\n }\n };\n /**\n * Render MultiPolygon geometry into the canvas. Rendering is immediate and\n * uses the current style.\n * @param {import("../../geom/MultiPolygon.js").default} geometry MultiPolygon geometry.\n */\n\n\n CanvasImmediateRenderer.prototype.drawMultiPolygon = function (geometry) {\n if (this.squaredTolerance_) {\n geometry =\n /** @type {import("../../geom/MultiPolygon.js").default} */\n geometry.simplifyTransformed(this.squaredTolerance_, this.userTransform_);\n }\n\n if (!intersects(this.extent_, geometry.getExtent())) {\n return;\n }\n\n if (this.strokeState_ || this.fillState_) {\n if (this.fillState_) {\n this.setContextFillState_(this.fillState_);\n }\n\n if (this.strokeState_) {\n this.setContextStrokeState_(this.strokeState_);\n }\n\n var context = this.context_;\n var flatCoordinates = geometry.getOrientedFlatCoordinates();\n var offset = 0;\n var endss = geometry.getEndss();\n var stride = geometry.getStride();\n context.beginPath();\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n offset = this.drawRings_(flatCoordinates, offset, ends, stride);\n }\n\n if (this.fillState_) {\n context.fill();\n }\n\n if (this.strokeState_) {\n context.stroke();\n }\n }\n\n if (this.text_ !== \'\') {\n var flatInteriorPoints = geometry.getFlatInteriorPoints();\n this.drawText_(flatInteriorPoints, 0, flatInteriorPoints.length, 2);\n }\n };\n /**\n * @param {import("../canvas.js").FillState} fillState Fill state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextFillState_ = function (fillState) {\n var context = this.context_;\n var contextFillState = this.contextFillState_;\n\n if (!contextFillState) {\n context.fillStyle = fillState.fillStyle;\n this.contextFillState_ = {\n fillStyle: fillState.fillStyle\n };\n } else {\n if (contextFillState.fillStyle != fillState.fillStyle) {\n contextFillState.fillStyle = fillState.fillStyle;\n context.fillStyle = fillState.fillStyle;\n }\n }\n };\n /**\n * @param {import("../canvas.js").StrokeState} strokeState Stroke state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextStrokeState_ = function (strokeState) {\n var context = this.context_;\n var contextStrokeState = this.contextStrokeState_;\n\n if (!contextStrokeState) {\n context.lineCap = strokeState.lineCap;\n\n if (context.setLineDash) {\n context.setLineDash(strokeState.lineDash);\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n\n context.lineJoin = strokeState.lineJoin;\n context.lineWidth = strokeState.lineWidth;\n context.miterLimit = strokeState.miterLimit;\n context.strokeStyle = strokeState.strokeStyle;\n this.contextStrokeState_ = {\n lineCap: strokeState.lineCap,\n lineDash: strokeState.lineDash,\n lineDashOffset: strokeState.lineDashOffset,\n lineJoin: strokeState.lineJoin,\n lineWidth: strokeState.lineWidth,\n miterLimit: strokeState.miterLimit,\n strokeStyle: strokeState.strokeStyle\n };\n } else {\n if (contextStrokeState.lineCap != strokeState.lineCap) {\n contextStrokeState.lineCap = strokeState.lineCap;\n context.lineCap = strokeState.lineCap;\n }\n\n if (context.setLineDash) {\n if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {\n context.setLineDash(contextStrokeState.lineDash = strokeState.lineDash);\n }\n\n if (contextStrokeState.lineDashOffset != strokeState.lineDashOffset) {\n contextStrokeState.lineDashOffset = strokeState.lineDashOffset;\n context.lineDashOffset = strokeState.lineDashOffset;\n }\n }\n\n if (contextStrokeState.lineJoin != strokeState.lineJoin) {\n contextStrokeState.lineJoin = strokeState.lineJoin;\n context.lineJoin = strokeState.lineJoin;\n }\n\n if (contextStrokeState.lineWidth != strokeState.lineWidth) {\n contextStrokeState.lineWidth = strokeState.lineWidth;\n context.lineWidth = strokeState.lineWidth;\n }\n\n if (contextStrokeState.miterLimit != strokeState.miterLimit) {\n contextStrokeState.miterLimit = strokeState.miterLimit;\n context.miterLimit = strokeState.miterLimit;\n }\n\n if (contextStrokeState.strokeStyle != strokeState.strokeStyle) {\n contextStrokeState.strokeStyle = strokeState.strokeStyle;\n context.strokeStyle = strokeState.strokeStyle;\n }\n }\n };\n /**\n * @param {import("../canvas.js").TextState} textState Text state.\n * @private\n */\n\n\n CanvasImmediateRenderer.prototype.setContextTextState_ = function (textState) {\n var context = this.context_;\n var contextTextState = this.contextTextState_;\n var textAlign = textState.textAlign ? textState.textAlign : defaultTextAlign;\n\n if (!contextTextState) {\n context.font = textState.font;\n context.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n context.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n this.contextTextState_ = {\n font: textState.font,\n textAlign: textAlign,\n textBaseline: textState.textBaseline\n };\n } else {\n if (contextTextState.font != textState.font) {\n contextTextState.font = textState.font;\n context.font = textState.font;\n }\n\n if (contextTextState.textAlign != textAlign) {\n contextTextState.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n context.textAlign =\n /** @type {CanvasTextAlign} */\n textAlign;\n }\n\n if (contextTextState.textBaseline != textState.textBaseline) {\n contextTextState.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n context.textBaseline =\n /** @type {CanvasTextBaseline} */\n textState.textBaseline;\n }\n }\n };\n /**\n * Set the fill and stroke style for subsequent draw operations. To clear\n * either fill or stroke styles, pass null for the appropriate parameter.\n *\n * @param {import("../../style/Fill.js").default} fillStyle Fill style.\n * @param {import("../../style/Stroke.js").default} strokeStyle Stroke style.\n */\n\n\n CanvasImmediateRenderer.prototype.setFillStrokeStyle = function (fillStyle, strokeStyle) {\n if (!fillStyle) {\n this.fillState_ = null;\n } else {\n var fillStyleColor = fillStyle.getColor();\n this.fillState_ = {\n fillStyle: asColorLike(fillStyleColor ? fillStyleColor : defaultFillStyle)\n };\n }\n\n if (!strokeStyle) {\n this.strokeState_ = null;\n } else {\n var strokeStyleColor = strokeStyle.getColor();\n var strokeStyleLineCap = strokeStyle.getLineCap();\n var strokeStyleLineDash = strokeStyle.getLineDash();\n var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();\n var strokeStyleLineJoin = strokeStyle.getLineJoin();\n var strokeStyleWidth = strokeStyle.getWidth();\n var strokeStyleMiterLimit = strokeStyle.getMiterLimit();\n this.strokeState_ = {\n lineCap: strokeStyleLineCap !== undefined ? strokeStyleLineCap : defaultLineCap,\n lineDash: strokeStyleLineDash ? strokeStyleLineDash : defaultLineDash,\n lineDashOffset: strokeStyleLineDashOffset ? strokeStyleLineDashOffset : defaultLineDashOffset,\n lineJoin: strokeStyleLineJoin !== undefined ? strokeStyleLineJoin : defaultLineJoin,\n lineWidth: this.pixelRatio_ * (strokeStyleWidth !== undefined ? strokeStyleWidth : defaultLineWidth),\n miterLimit: strokeStyleMiterLimit !== undefined ? strokeStyleMiterLimit : defaultMiterLimit,\n strokeStyle: asColorLike(strokeStyleColor ? strokeStyleColor : defaultStrokeStyle)\n };\n }\n };\n /**\n * Set the image style for subsequent draw operations. Pass null to remove\n * the image style.\n *\n * @param {import("../../style/Image.js").default} imageStyle Image style.\n */\n\n\n CanvasImmediateRenderer.prototype.setImageStyle = function (imageStyle) {\n if (!imageStyle) {\n this.image_ = null;\n } else {\n var imageSize = imageStyle.getSize();\n\n if (!imageSize) {\n this.image_ = null;\n } else {\n var imageAnchor = imageStyle.getAnchor(); // FIXME pixel ratio\n\n var imageImage = imageStyle.getImage(1);\n var imageOrigin = imageStyle.getOrigin();\n var imageScale = imageStyle.getScaleArray();\n this.imageAnchorX_ = imageAnchor[0];\n this.imageAnchorY_ = imageAnchor[1];\n this.imageHeight_ = imageSize[1];\n this.image_ = imageImage;\n this.imageOpacity_ = imageStyle.getOpacity();\n this.imageOriginX_ = imageOrigin[0];\n this.imageOriginY_ = imageOrigin[1];\n this.imageRotateWithView_ = imageStyle.getRotateWithView();\n this.imageRotation_ = imageStyle.getRotation();\n this.imageScale_ = [this.pixelRatio_ * imageScale[0], this.pixelRatio_ * imageScale[1]];\n this.imageWidth_ = imageSize[0];\n }\n }\n };\n /**\n * Set the text style for subsequent draw operations. Pass null to\n * remove the text style.\n *\n * @param {import("../../style/Text.js").default} textStyle Text style.\n */\n\n\n CanvasImmediateRenderer.prototype.setTextStyle = function (textStyle) {\n if (!textStyle) {\n this.text_ = \'\';\n } else {\n var textFillStyle = textStyle.getFill();\n\n if (!textFillStyle) {\n this.textFillState_ = null;\n } else {\n var textFillStyleColor = textFillStyle.getColor();\n this.textFillState_ = {\n fillStyle: asColorLike(textFillStyleColor ? textFillStyleColor : defaultFillStyle)\n };\n }\n\n var textStrokeStyle = textStyle.getStroke();\n\n if (!textStrokeStyle) {\n this.textStrokeState_ = null;\n } else {\n var textStrokeStyleColor = textStrokeStyle.getColor();\n var textStrokeStyleLineCap = textStrokeStyle.getLineCap();\n var textStrokeStyleLineDash = textStrokeStyle.getLineDash();\n var textStrokeStyleLineDashOffset = textStrokeStyle.getLineDashOffset();\n var textStrokeStyleLineJoin = textStrokeStyle.getLineJoin();\n var textStrokeStyleWidth = textStrokeStyle.getWidth();\n var textStrokeStyleMiterLimit = textStrokeStyle.getMiterLimit();\n this.textStrokeState_ = {\n lineCap: textStrokeStyleLineCap !== undefined ? textStrokeStyleLineCap : defaultLineCap,\n lineDash: textStrokeStyleLineDash ? textStrokeStyleLineDash : defaultLineDash,\n lineDashOffset: textStrokeStyleLineDashOffset ? textStrokeStyleLineDashOffset : defaultLineDashOffset,\n lineJoin: textStrokeStyleLineJoin !== undefined ? textStrokeStyleLineJoin : defaultLineJoin,\n lineWidth: textStrokeStyleWidth !== undefined ? textStrokeStyleWidth : defaultLineWidth,\n miterLimit: textStrokeStyleMiterLimit !== undefined ? textStrokeStyleMiterLimit : defaultMiterLimit,\n strokeStyle: asColorLike(textStrokeStyleColor ? textStrokeStyleColor : defaultStrokeStyle)\n };\n }\n\n var textFont = textStyle.getFont();\n var textOffsetX = textStyle.getOffsetX();\n var textOffsetY = textStyle.getOffsetY();\n var textRotateWithView = textStyle.getRotateWithView();\n var textRotation = textStyle.getRotation();\n var textScale = textStyle.getScaleArray();\n var textText = textStyle.getText();\n var textTextAlign = textStyle.getTextAlign();\n var textTextBaseline = textStyle.getTextBaseline();\n this.textState_ = {\n font: textFont !== undefined ? textFont : defaultFont,\n textAlign: textTextAlign !== undefined ? textTextAlign : defaultTextAlign,\n textBaseline: textTextBaseline !== undefined ? textTextBaseline : defaultTextBaseline\n };\n this.text_ = textText !== undefined ? textText : \'\';\n this.textOffsetX_ = textOffsetX !== undefined ? this.pixelRatio_ * textOffsetX : 0;\n this.textOffsetY_ = textOffsetY !== undefined ? this.pixelRatio_ * textOffsetY : 0;\n this.textRotateWithView_ = textRotateWithView !== undefined ? textRotateWithView : false;\n this.textRotation_ = textRotation !== undefined ? textRotation : 0;\n this.textScale_ = [this.pixelRatio_ * textScale[0], this.pixelRatio_ * textScale[1]];\n }\n };\n\n return CanvasImmediateRenderer;\n}(render_VectorContext);\n\n/* harmony default export */ var Immediate = (CanvasImmediateRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconAnchorUnits.js\n/**\n * @module ol/style/IconAnchorUnits\n */\n\n/**\n * Icon anchor units. One of \'fraction\', \'pixels\'.\n * @enum {string}\n */\n/* harmony default export */ var IconAnchorUnits = ({\n /**\n * Anchor is a fraction\n * @api\n */\n FRACTION: \'fraction\',\n\n /**\n * Anchor is in pixels\n * @api\n */\n PIXELS: \'pixels\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconOrigin.js\n/**\n * @module ol/style/IconOrigin\n */\n\n/**\n * Icon origin. One of \'bottom-left\', \'bottom-right\', \'top-left\', \'top-right\'.\n * @enum {string}\n */\n/* harmony default export */ var IconOrigin = ({\n /**\n * Origin is at bottom left\n * @api\n */\n BOTTOM_LEFT: \'bottom-left\',\n\n /**\n * Origin is at bottom right\n * @api\n */\n BOTTOM_RIGHT: \'bottom-right\',\n\n /**\n * Origin is at top left\n * @api\n */\n TOP_LEFT: \'top-left\',\n\n /**\n * Origin is at top right\n * @api\n */\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/ImageBase.js\nvar ImageBase_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/ImageBase\n */\n\n\n\n\n\n/**\n * @abstract\n */\n\nvar ImageBase =\n/** @class */\nfunction (_super) {\n ImageBase_extends(ImageBase, _super);\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./ImageState.js").default} state State.\n */\n\n\n function ImageBase(extent, resolution, pixelRatio, state) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {import("./extent.js").Extent}\n */\n\n\n _this.extent = extent;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @protected\n * @type {number|undefined}\n */\n\n _this.resolution = resolution;\n /**\n * @protected\n * @type {import("./ImageState.js").default}\n */\n\n _this.state = state;\n return _this;\n }\n /**\n * @protected\n */\n\n\n ImageBase.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @return {import("./extent.js").Extent} Extent.\n */\n\n\n ImageBase.prototype.getExtent = function () {\n return this.extent;\n };\n /**\n * @abstract\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n */\n\n\n ImageBase.prototype.getImage = function () {\n return util_abstract();\n };\n /**\n * @return {number} PixelRatio.\n */\n\n\n ImageBase.prototype.getPixelRatio = function () {\n return this.pixelRatio_;\n };\n /**\n * @return {number} Resolution.\n */\n\n\n ImageBase.prototype.getResolution = function () {\n return (\n /** @type {number} */\n this.resolution\n );\n };\n /**\n * @return {import("./ImageState.js").default} State.\n */\n\n\n ImageBase.prototype.getState = function () {\n return this.state;\n };\n /**\n * Load not yet loaded URI.\n * @abstract\n */\n\n\n ImageBase.prototype.load = function () {\n util_abstract();\n };\n\n return ImageBase;\n}(events_Target);\n\n/* harmony default export */ var ol_ImageBase = (ImageBase);\n;// CONCATENATED MODULE: ./node_modules/ol/Image.js\nvar Image_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Image\n */\n\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Image~Image} for the image and a\n * `{string}` for the src as arguments. It is supposed to make it so the\n * underlying image {@link module:ol/Image~Image#getImage} is assigned the\n * content specified by the src. If not specified, the default is\n *\n * function(image, src) {\n * image.getImage().src = src;\n * }\n *\n * Providing a custom `imageLoadFunction` can be useful to load images with\n * post requests or - in general - through XHR requests, where the src of the\n * image element would be set to a data URI when the content is loaded.\n *\n * @typedef {function(ImageWrapper, string): void} LoadFunction\n * @api\n */\n\nvar ImageWrapper =\n/** @class */\nfunction (_super) {\n Image_extends(ImageWrapper, _super);\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number|undefined} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {LoadFunction} imageLoadFunction Image load function.\n */\n\n\n function ImageWrapper(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {\n var _this = _super.call(this, extent, resolution, pixelRatio, ImageState.IDLE) || this;\n /**\n * @private\n * @type {string}\n */\n\n\n _this.src_ = src;\n /**\n * @private\n * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}\n */\n\n _this.image_ = new Image();\n\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n\n\n _this.unlisten_ = null;\n /**\n * @protected\n * @type {import("./ImageState.js").default}\n */\n\n _this.state = ImageState.IDLE;\n /**\n * @private\n * @type {LoadFunction}\n */\n\n _this.imageLoadFunction_ = imageLoadFunction;\n return _this;\n }\n /**\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n\n\n ImageWrapper.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.handleImageError_ = function () {\n this.state = ImageState.ERROR;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.handleImageLoad_ = function () {\n if (this.resolution === undefined) {\n this.resolution = getHeight(this.extent) / this.image_.height;\n }\n\n this.state = ImageState.LOADED;\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @api\n */\n\n\n ImageWrapper.prototype.load = function () {\n if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {\n this.state = ImageState.LOADING;\n this.changed();\n this.imageLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.\n */\n\n\n ImageWrapper.prototype.setImage = function (image) {\n this.image_ = image;\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n ImageWrapper.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return ImageWrapper;\n}(ol_ImageBase);\n/**\n * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image element.\n * @param {function():any} loadHandler Load callback function.\n * @param {function():any} errorHandler Error callback function.\n * @return {function():void} Callback to stop listening.\n */\n\n\nfunction listenImage(image, loadHandler, errorHandler) {\n var img =\n /** @type {HTMLImageElement} */\n image;\n\n if (img.src && IMAGE_DECODE) {\n var promise = img.decode();\n var listening_1 = true;\n\n var unlisten = function unlisten() {\n listening_1 = false;\n };\n\n promise.then(function () {\n if (listening_1) {\n loadHandler();\n }\n }).catch(function (error) {\n if (listening_1) {\n // FIXME: Unconditionally call errorHandler() when this bug is fixed upstream:\n // https://bugs.webkit.org/show_bug.cgi?id=198527\n if (error.name === \'EncodingError\' && error.message === \'Invalid image type.\') {\n loadHandler();\n } else {\n errorHandler();\n }\n }\n });\n return unlisten;\n }\n\n var listenerKeys = [listenOnce(img, EventType.LOAD, loadHandler), listenOnce(img, EventType.ERROR, errorHandler)];\n return function unlisten() {\n listenerKeys.forEach(unlistenByKey);\n };\n}\n/* harmony default export */ var ol_Image = ((/* unused pure expression or super */ null && (ImageWrapper)));\n;// CONCATENATED MODULE: ./node_modules/ol/style/IconImage.js\n/**\n * @module ol/style/IconImage\n */\nvar IconImage_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n/**\n * @type {CanvasRenderingContext2D}\n */\n\nvar taintedTestContext = null;\n\nvar IconImage =\n/** @class */\nfunction (_super) {\n IconImage_extends(IconImage, _super);\n /**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string|undefined} src Src.\n * @param {import("../size.js").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../ImageState.js").default} imageState Image state.\n * @param {import("../color.js").Color} color Color.\n */\n\n\n function IconImage(image, src, size, crossOrigin, imageState, color) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n\n _this.hitDetectionImage_ = null;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n _this.image_ = !image ? new Image() : image;\n\n if (crossOrigin !== null) {\n /** @type {HTMLImageElement} */\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {Object<number, HTMLCanvasElement>}\n */\n\n\n _this.canvas_ = {};\n /**\n * @private\n * @type {import("../color.js").Color}\n */\n\n _this.color_ = color;\n /**\n * @private\n * @type {?function():void}\n */\n\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import("../ImageState.js").default}\n */\n\n _this.imageState_ = imageState;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = size;\n /**\n * @private\n * @type {string|undefined}\n */\n\n _this.src_ = src;\n /**\n * @private\n */\n\n _this.tainted_;\n return _this;\n }\n /**\n * @private\n * @return {boolean} The image canvas is tainted.\n */\n\n\n IconImage.prototype.isTainted_ = function () {\n if (this.tainted_ === undefined && this.imageState_ === ImageState.LOADED) {\n if (!taintedTestContext) {\n taintedTestContext = createCanvasContext2D(1, 1);\n }\n\n taintedTestContext.drawImage(this.image_, 0, 0);\n\n try {\n taintedTestContext.getImageData(0, 0, 1, 1);\n this.tainted_ = false;\n } catch (e) {\n taintedTestContext = null;\n this.tainted_ = true;\n }\n }\n\n return this.tainted_ === true;\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.dispatchChangeEvent_ = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.handleImageError_ = function () {\n this.imageState_ = ImageState.ERROR;\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @private\n */\n\n\n IconImage.prototype.handleImageLoad_ = function () {\n this.imageState_ = ImageState.LOADED;\n\n if (this.size_) {\n this.image_.width = this.size_[0];\n this.image_.height = this.size_[1];\n } else {\n this.size_ = [this.image_.width, this.image_.height];\n }\n\n this.unlistenImage_();\n this.dispatchChangeEvent_();\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n */\n\n\n IconImage.prototype.getImage = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? this.canvas_[pixelRatio] : this.image_;\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Image or Canvas element.\n */\n\n\n IconImage.prototype.getPixelRatio = function (pixelRatio) {\n this.replaceColor_(pixelRatio);\n return this.canvas_[pixelRatio] ? pixelRatio : 1;\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n IconImage.prototype.getImageState = function () {\n return this.imageState_;\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n\n\n IconImage.prototype.getHitDetectionImage = function () {\n if (!this.hitDetectionImage_) {\n if (this.isTainted_()) {\n var width = this.size_[0];\n var height = this.size_[1];\n var context = createCanvasContext2D(width, height);\n context.fillRect(0, 0, width, height);\n this.hitDetectionImage_ = context.canvas;\n } else {\n this.hitDetectionImage_ = this.image_;\n }\n }\n\n return this.hitDetectionImage_;\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import("../size.js").Size} Image size.\n */\n\n\n IconImage.prototype.getSize = function () {\n return this.size_;\n };\n /**\n * @return {string|undefined} Image src.\n */\n\n\n IconImage.prototype.getSrc = function () {\n return this.src_;\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n IconImage.prototype.load = function () {\n if (this.imageState_ == ImageState.IDLE) {\n this.imageState_ = ImageState.LOADING;\n\n try {\n /** @type {HTMLImageElement} */\n this.image_.src = this.src_;\n } catch (e) {\n this.handleImageError_();\n }\n\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @private\n */\n\n\n IconImage.prototype.replaceColor_ = function (pixelRatio) {\n if (!this.color_ || this.canvas_[pixelRatio]) {\n return;\n }\n\n var canvas = document.createElement(\'canvas\');\n this.canvas_[pixelRatio] = canvas;\n canvas.width = Math.ceil(this.image_.width * pixelRatio);\n canvas.height = Math.ceil(this.image_.height * pixelRatio);\n var ctx = canvas.getContext(\'2d\');\n ctx.scale(pixelRatio, pixelRatio);\n ctx.drawImage(this.image_, 0, 0);\n ctx.globalCompositeOperation = \'multiply\'; // Internet Explorer 11 does not support the multiply operation.\n // If the canvas is tainted in Internet Explorer this still produces\n // a solid color image with the shape of the icon.\n\n if (ctx.globalCompositeOperation === \'multiply\' || this.isTainted_()) {\n ctx.fillStyle = asString(this.color_);\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.globalCompositeOperation = \'destination-in\';\n ctx.drawImage(this.image_, 0, 0);\n } else {\n var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n var data = imgData.data;\n var r = this.color_[0] / 255.0;\n var g = this.color_[1] / 255.0;\n var b = this.color_[2] / 255.0;\n var a = this.color_[3];\n\n for (var i = 0, ii = data.length; i < ii; i += 4) {\n data[i] *= r;\n data[i + 1] *= g;\n data[i + 2] *= b;\n data[i + 3] *= a;\n }\n\n ctx.putImageData(imgData, 0, 0);\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n IconImage.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return IconImage;\n}(events_Target);\n/**\n * @param {HTMLImageElement|HTMLCanvasElement} image Image.\n * @param {string} src Src.\n * @param {import("../size.js").Size} size Size.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("../ImageState.js").default} imageState Image state.\n * @param {import("../color.js").Color} color Color.\n * @return {IconImage} Icon image.\n */\n\n\nfunction IconImage_get(image, src, size, crossOrigin, imageState, color) {\n var iconImage = shared.get(src, crossOrigin, color);\n\n if (!iconImage) {\n iconImage = new IconImage(image, src, size, crossOrigin, imageState, color);\n shared.set(src, crossOrigin, color, iconImage);\n }\n\n return iconImage;\n}\n/* harmony default export */ var style_IconImage = ((/* unused pure expression or super */ null && (IconImage)));\n;// CONCATENATED MODULE: ./node_modules/ol/style/Icon.js\nvar Icon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/style/Icon\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {Array<number>} [anchor=[0.5, 0.5]] Anchor. Default value is the icon center.\n * @property {import("./IconOrigin.js").default} [anchorOrigin=\'top-left\'] Origin of the anchor: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {import("./IconAnchorUnits.js").default} [anchorXUnits=\'fraction\'] Units in which the anchor x value is\n * specified. A value of `\'fraction\'` indicates the x value is a fraction of the icon. A value of `\'pixels\'` indicates\n * the x value in pixels.\n * @property {import("./IconAnchorUnits.js").default} [anchorYUnits=\'fraction\'] Units in which the anchor y value is\n * specified. A value of `\'fraction\'` indicates the y value is a fraction of the icon. A value of `\'pixels\'` indicates\n * the y value in pixels.\n * @property {import("../color.js").Color|string} [color] Color to tint the icon. If not specified,\n * the icon will be left as is.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that you must provide a\n * `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {HTMLImageElement|HTMLCanvasElement} [img] Image object for the icon. If the `src` option is not provided then the\n * provided image must already be loaded. And in that case, it is required\n * to provide the size of the image, with the `imgSize` option.\n * @property {Array<number>} [offset=[0, 0]] Offset, which, together with the size and the offset origin, define the\n * sub-rectangle to use from the original icon image.\n * @property {Array<number>} [displacement=[0,0]] Displacement the icon\n * @property {import("./IconOrigin.js").default} [offsetOrigin=\'top-left\'] Origin of the offset: `bottom-left`, `bottom-right`,\n * `top-left` or `top-right`.\n * @property {number} [opacity=1] Opacity of the icon.\n * @property {number|import("../size.js").Size} [scale=1] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the icon with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {import("../size.js").Size} [size] Icon size in pixel. Can be used together with `offset` to define the\n * sub-rectangle to use from the origin (sprite) icon image.\n * @property {import("../size.js").Size} [imgSize] Image size in pixels. Only required if `img` is set and `src` is not, and\n * for SVG images in Internet Explorer 11. The provided `imgSize` needs to match the actual size of the image.\n * @property {string} [src] Image source URI.\n */\n\n/**\n * @classdesc\n * Set icon style for vector features.\n * @api\n */\n\nvar Icon =\n/** @class */\nfunction (_super) {\n Icon_extends(Icon, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function Icon(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n /**\n * @type {number}\n */\n\n var opacity = options.opacity !== undefined ? options.opacity : 1;\n /**\n * @type {number}\n */\n\n var rotation = options.rotation !== undefined ? options.rotation : 0;\n /**\n * @type {number|import("../size.js").Size}\n */\n\n var scale = options.scale !== undefined ? options.scale : 1;\n /**\n * @type {boolean}\n */\n\n var rotateWithView = options.rotateWithView !== undefined ? options.rotateWithView : false;\n _this = _super.call(this, {\n opacity: opacity,\n rotation: rotation,\n scale: scale,\n displacement: options.displacement !== undefined ? options.displacement : [0, 0],\n rotateWithView: rotateWithView\n }) || this;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.anchor_ = options.anchor !== undefined ? options.anchor : [0.5, 0.5];\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.normalizedAnchor_ = null;\n /**\n * @private\n * @type {import("./IconOrigin.js").default}\n */\n\n _this.anchorOrigin_ = options.anchorOrigin !== undefined ? options.anchorOrigin : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {import("./IconAnchorUnits.js").default}\n */\n\n _this.anchorXUnits_ = options.anchorXUnits !== undefined ? options.anchorXUnits : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {import("./IconAnchorUnits.js").default}\n */\n\n _this.anchorYUnits_ = options.anchorYUnits !== undefined ? options.anchorYUnits : IconAnchorUnits.FRACTION;\n /**\n * @private\n * @type {?string}\n */\n\n _this.crossOrigin_ = options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n var image = options.img !== undefined ? options.img : null;\n /**\n * @type {import("../size.js").Size}\n */\n\n var imgSize = options.imgSize !== undefined ? options.imgSize : null;\n /**\n * @type {string|undefined}\n */\n\n var src = options.src;\n asserts_assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time\n\n asserts_assert(!image || image && imgSize, 5); // `imgSize` must be set when `image` is provided\n\n if ((src === undefined || src.length === 0) && image) {\n src =\n /** @type {HTMLImageElement} */\n image.src || getUid(image);\n }\n\n asserts_assert(src !== undefined && src.length > 0, 6); // A defined and non-empty `src` or `image` must be provided\n\n /**\n * @type {import("../ImageState.js").default}\n */\n\n var imageState = options.src !== undefined ? ImageState.IDLE : ImageState.LOADED;\n /**\n * @private\n * @type {import("../color.js").Color}\n */\n\n _this.color_ = options.color !== undefined ? asArray(options.color) : null;\n /**\n * @private\n * @type {import("./IconImage.js").default}\n */\n\n _this.iconImage_ = IconImage_get(image,\n /** @type {string} */\n src, imgSize, _this.crossOrigin_, imageState, _this.color_);\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.offset_ = options.offset !== undefined ? options.offset : [0, 0];\n /**\n * @private\n * @type {import("./IconOrigin.js").default}\n */\n\n _this.offsetOrigin_ = options.offsetOrigin !== undefined ? options.offsetOrigin : IconOrigin.TOP_LEFT;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.origin_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n _this.size_ = options.size !== undefined ? options.size : null;\n return _this;\n }\n /**\n * Clones the style. The underlying Image/HTMLCanvasElement is not cloned.\n * @return {Icon} The cloned style.\n * @api\n */\n\n\n Icon.prototype.clone = function () {\n var scale = this.getScale();\n return new Icon({\n anchor: this.anchor_.slice(),\n anchorOrigin: this.anchorOrigin_,\n anchorXUnits: this.anchorXUnits_,\n anchorYUnits: this.anchorYUnits_,\n crossOrigin: this.crossOrigin_,\n color: this.color_ && this.color_.slice ? this.color_.slice() : this.color_ || undefined,\n src: this.getSrc(),\n offset: this.offset_.slice(),\n offsetOrigin: this.offsetOrigin_,\n size: this.size_ !== null ? this.size_.slice() : undefined,\n opacity: this.getOpacity(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView()\n });\n };\n /**\n * Get the anchor point in pixels. The anchor determines the center point for the\n * symbolizer.\n * @return {Array<number>} Anchor.\n * @api\n */\n\n\n Icon.prototype.getAnchor = function () {\n if (this.normalizedAnchor_) {\n return this.normalizedAnchor_;\n }\n\n var anchor = this.anchor_;\n var size = this.getSize();\n\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION || this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n if (!size) {\n return null;\n }\n\n anchor = this.anchor_.slice();\n\n if (this.anchorXUnits_ == IconAnchorUnits.FRACTION) {\n anchor[0] *= size[0];\n }\n\n if (this.anchorYUnits_ == IconAnchorUnits.FRACTION) {\n anchor[1] *= size[1];\n }\n }\n\n if (this.anchorOrigin_ != IconOrigin.TOP_LEFT) {\n if (!size) {\n return null;\n }\n\n if (anchor === this.anchor_) {\n anchor = this.anchor_.slice();\n }\n\n if (this.anchorOrigin_ == IconOrigin.TOP_RIGHT || this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[0] = -anchor[0] + size[0];\n }\n\n if (this.anchorOrigin_ == IconOrigin.BOTTOM_LEFT || this.anchorOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n anchor[1] = -anchor[1] + size[1];\n }\n }\n\n this.normalizedAnchor_ = anchor;\n return this.normalizedAnchor_;\n };\n /**\n * Set the anchor point. The anchor determines the center point for the\n * symbolizer.\n *\n * @param {Array<number>} anchor Anchor.\n * @api\n */\n\n\n Icon.prototype.setAnchor = function (anchor) {\n this.anchor_ = anchor;\n this.normalizedAnchor_ = null;\n };\n /**\n * Get the icon color.\n * @return {import("../color.js").Color} Color.\n * @api\n */\n\n\n Icon.prototype.getColor = function () {\n return this.color_;\n };\n /**\n * Get the image icon.\n * @param {number} pixelRatio Pixel ratio.\n * @return {HTMLImageElement|HTMLCanvasElement} Image or Canvas element.\n * @api\n */\n\n\n Icon.prototype.getImage = function (pixelRatio) {\n return this.iconImage_.getImage(pixelRatio);\n };\n /**\n * Get the pixel ratio.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} The pixel ration of the image.\n * @api\n */\n\n\n Icon.prototype.getPixelRatio = function (pixelRatio) {\n return this.iconImage_.getPixelRatio(pixelRatio);\n };\n /**\n * @return {import("../size.js").Size} Image size.\n */\n\n\n Icon.prototype.getImageSize = function () {\n return this.iconImage_.getSize();\n };\n /**\n * @return {import("../size.js").Size} Size of the hit-detection image.\n */\n\n\n Icon.prototype.getHitDetectionImageSize = function () {\n return this.getImageSize();\n };\n /**\n * @return {import("../ImageState.js").default} Image state.\n */\n\n\n Icon.prototype.getImageState = function () {\n return this.iconImage_.getImageState();\n };\n /**\n * @return {HTMLImageElement|HTMLCanvasElement} Image element.\n */\n\n\n Icon.prototype.getHitDetectionImage = function () {\n return this.iconImage_.getHitDetectionImage();\n };\n /**\n * Get the origin of the symbolizer.\n * @return {Array<number>} Origin.\n * @api\n */\n\n\n Icon.prototype.getOrigin = function () {\n if (this.origin_) {\n return this.origin_;\n }\n\n var offset = this.offset_;\n var displacement = this.getDisplacement();\n\n if (this.offsetOrigin_ != IconOrigin.TOP_LEFT) {\n var size = this.getSize();\n var iconImageSize = this.iconImage_.getSize();\n\n if (!size || !iconImageSize) {\n return null;\n }\n\n offset = offset.slice();\n\n if (this.offsetOrigin_ == IconOrigin.TOP_RIGHT || this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[0] = iconImageSize[0] - size[0] - offset[0];\n }\n\n if (this.offsetOrigin_ == IconOrigin.BOTTOM_LEFT || this.offsetOrigin_ == IconOrigin.BOTTOM_RIGHT) {\n offset[1] = iconImageSize[1] - size[1] - offset[1];\n }\n }\n\n offset[0] += displacement[0];\n offset[1] += displacement[1];\n this.origin_ = offset;\n return this.origin_;\n };\n /**\n * Get the image URL.\n * @return {string|undefined} Image src.\n * @api\n */\n\n\n Icon.prototype.getSrc = function () {\n return this.iconImage_.getSrc();\n };\n /**\n * Get the size of the icon (in pixels).\n * @return {import("../size.js").Size} Image size.\n * @api\n */\n\n\n Icon.prototype.getSize = function () {\n return !this.size_ ? this.iconImage_.getSize() : this.size_;\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n Icon.prototype.listenImageChange = function (listener) {\n this.iconImage_.addEventListener(EventType.CHANGE, listener);\n };\n /**\n * Load not yet loaded URI.\n * When rendering a feature with an icon style, the vector renderer will\n * automatically call this method. However, you might want to call this\n * method yourself for preloading or other purposes.\n * @api\n */\n\n\n Icon.prototype.load = function () {\n this.iconImage_.load();\n };\n /**\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n */\n\n\n Icon.prototype.unlistenImageChange = function (listener) {\n this.iconImage_.removeEventListener(EventType.CHANGE, listener);\n };\n\n return Icon;\n}(style_Image);\n\n/* harmony default export */ var style_Icon = (Icon);\n;// CONCATENATED MODULE: ./node_modules/ol/render/canvas/hitdetect.js\n/**\n * @module ol/render/canvas/hitdetect\n */\n\n\n\n\n\n\n\n/**\n * @param {import("../../size.js").Size} size Canvas size in css pixels.\n * @param {Array<import("../../transform.js").Transform>} transforms Transforms\n * for rendering features to all worlds of the viewport, from coordinates to css\n * pixels.\n * @param {Array<import("../../Feature.js").FeatureLike>} features\n * Features to consider for hit detection.\n * @param {import("../../style/Style.js").StyleFunction|undefined} styleFunction\n * Layer style function.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {ImageData} Hit detection image data.\n */\n\nfunction createHitDetectionImageData(size, transforms, features, styleFunction, extent, resolution, rotation) {\n var width = size[0] / 2;\n var height = size[1] / 2;\n var context = createCanvasContext2D(width, height);\n context.imageSmoothingEnabled = false;\n var canvas = context.canvas;\n var renderer = new Immediate(context, 0.5, extent, null, rotation);\n var featureCount = features.length; // Stretch hit detection index to use the whole available color range\n\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / featureCount);\n var featuresByZIndex = {};\n\n for (var i = 1; i <= featureCount; ++i) {\n var feature = features[i - 1];\n var featureStyleFunction = feature.getStyleFunction() || styleFunction;\n\n if (!styleFunction) {\n continue;\n }\n\n var styles = featureStyleFunction(feature, resolution);\n\n if (!styles) {\n continue;\n }\n\n if (!Array.isArray(styles)) {\n styles = [styles];\n }\n\n var index = i * indexFactor;\n var color = \'#\' + (\'000000\' + index.toString(16)).slice(-6);\n\n for (var j = 0, jj = styles.length; j < jj; ++j) {\n var originalStyle = styles[j];\n var style = originalStyle.clone();\n var fill = style.getFill();\n\n if (fill) {\n fill.setColor(color);\n }\n\n var stroke = style.getStroke();\n\n if (stroke) {\n stroke.setColor(color);\n }\n\n style.setText(undefined);\n var image = originalStyle.getImage();\n\n if (image) {\n var imgSize = image.getImageSize();\n\n if (!imgSize) {\n continue;\n }\n\n var canvas_1 = document.createElement(\'canvas\');\n canvas_1.width = imgSize[0];\n canvas_1.height = imgSize[1];\n var imgContext = canvas_1.getContext(\'2d\', {\n alpha: false\n });\n imgContext.fillStyle = color;\n var img = imgContext.canvas;\n imgContext.fillRect(0, 0, img.width, img.height);\n var width_1 = imgSize ? imgSize[0] : img.width;\n var height_1 = imgSize ? imgSize[1] : img.height;\n var iconContext = createCanvasContext2D(width_1, height_1);\n iconContext.drawImage(img, 0, 0);\n style.setImage(new style_Icon({\n img: img,\n imgSize: imgSize,\n anchor: image.getAnchor(),\n anchorXUnits: IconAnchorUnits.PIXELS,\n anchorYUnits: IconAnchorUnits.PIXELS,\n offset: image.getOrigin(),\n size: image.getSize(),\n opacity: image.getOpacity(),\n scale: image.getScale(),\n rotation: image.getRotation(),\n rotateWithView: image.getRotateWithView()\n }));\n }\n\n var zIndex = Number(style.getZIndex());\n var byGeometryType = featuresByZIndex[zIndex];\n\n if (!byGeometryType) {\n byGeometryType = {};\n featuresByZIndex[zIndex] = byGeometryType;\n byGeometryType[geom_GeometryType.POLYGON] = [];\n byGeometryType[geom_GeometryType.CIRCLE] = [];\n byGeometryType[geom_GeometryType.LINE_STRING] = [];\n byGeometryType[geom_GeometryType.POINT] = [];\n }\n\n var geometry = style.getGeometryFunction()(feature);\n\n if (geometry && intersects(extent, geometry.getExtent())) {\n byGeometryType[geometry.getType().replace(\'Multi\', \'\')].push(geometry, style);\n }\n }\n }\n\n var zIndexKeys = Object.keys(featuresByZIndex).map(Number).sort(numberSafeCompareFunction);\n\n for (var i = 0, ii = zIndexKeys.length; i < ii; ++i) {\n var byGeometryType = featuresByZIndex[zIndexKeys[i]];\n\n for (var type in byGeometryType) {\n var geomAndStyle = byGeometryType[type];\n\n for (var j = 0, jj = geomAndStyle.length; j < jj; j += 2) {\n renderer.setStyle(geomAndStyle[j + 1]);\n\n for (var k = 0, kk = transforms.length; k < kk; ++k) {\n renderer.setTransform(transforms[k]);\n renderer.drawGeometry(geomAndStyle[j]);\n }\n }\n }\n }\n\n return context.getImageData(0, 0, canvas.width, canvas.height);\n}\n/**\n * @param {import("../../pixel").Pixel} pixel Pixel coordinate on the hit\n * detection canvas in css pixels.\n * @param {Array<import("../../Feature").FeatureLike>} features Features. Has to\n * match the `features` array that was passed to `createHitDetectionImageData()`.\n * @param {ImageData} imageData Hit detection image data generated by\n * `createHitDetectionImageData()`.\n * @return {Array<import("../../Feature").FeatureLike>} features Features.\n */\n\nfunction hitDetect(pixel, features, imageData) {\n var resultFeatures = [];\n\n if (imageData) {\n var index = (Math.round(pixel[0] / 2) + Math.round(pixel[1] / 2) * imageData.width) * 4;\n var r = imageData.data[index];\n var g = imageData.data[index + 1];\n var b = imageData.data[index + 2];\n var i = b + 256 * (g + 256 * r);\n var indexFactor = Math.floor((256 * 256 * 256 - 1) / features.length);\n\n if (i && i % indexFactor === 0) {\n resultFeatures.push(features[i / indexFactor - 1]);\n }\n }\n\n return resultFeatures;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/vector.js\n/**\n * @module ol/renderer/vector\n */\n\n\n\n\n/**\n * Feature callback. The callback will be called with three arguments. The first\n * argument is one {@link module:ol/Feature feature} or {@link module:ol/render/Feature render feature}\n * at the pixel, the second is the {@link module:ol/layer/Layer layer} of the feature and will be null for\n * unmanaged layers. The third is the {@link module:ol/geom/SimpleGeometry} of the feature. For features\n * with a GeometryCollection geometry, it will be the first detected geometry from the collection.\n * @template T\n * @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default, import("../geom/SimpleGeometry.js").default): T} FeatureCallback\n */\n\n/**\n * Tolerance for geometry simplification in device pixels.\n * @type {number}\n */\n\nvar SIMPLIFY_TOLERANCE = 0.5;\n/**\n * @const\n * @type {Object<import("../geom/GeometryType.js").default,\n * function(import("../render/canvas/BuilderGroup.js").default, import("../geom/Geometry.js").default,\n * import("../style/Style.js").default, Object): void>}\n */\n\nvar GEOMETRY_RENDERERS = {\n \'Point\': renderPointGeometry,\n \'LineString\': renderLineStringGeometry,\n \'Polygon\': renderPolygonGeometry,\n \'MultiPoint\': renderMultiPointGeometry,\n \'MultiLineString\': renderMultiLineStringGeometry,\n \'MultiPolygon\': renderMultiPolygonGeometry,\n \'GeometryCollection\': renderGeometryCollectionGeometry,\n \'Circle\': renderCircleGeometry\n};\n/**\n * @param {import("../Feature.js").FeatureLike} feature1 Feature 1.\n * @param {import("../Feature.js").FeatureLike} feature2 Feature 2.\n * @return {number} Order.\n */\n\nfunction defaultOrder(feature1, feature2) {\n return parseInt(getUid(feature1), 10) - parseInt(getUid(feature2), 10);\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Squared pixel tolerance.\n */\n\nfunction getSquaredTolerance(resolution, pixelRatio) {\n var tolerance = getTolerance(resolution, pixelRatio);\n return tolerance * tolerance;\n}\n/**\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Pixel tolerance.\n */\n\nfunction getTolerance(resolution, pixelRatio) {\n return SIMPLIFY_TOLERANCE * resolution / pixelRatio;\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Builder group.\n * @param {import("../geom/Circle.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\nfunction renderCircleGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (fillStyle || strokeStyle) {\n var circleReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.CIRCLE);\n circleReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n circleReplay.drawCircle(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {function(import("../events/Event.js").default): void} listener Listener function.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Transform from user to view projection.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n * @return {boolean} `true` if style is loading.\n */\n\n\nfunction renderFeature(replayGroup, feature, style, squaredTolerance, listener, opt_transform, opt_declutterBuilderGroup) {\n var loading = false;\n var imageStyle = style.getImage();\n\n if (imageStyle) {\n var imageState = imageStyle.getImageState();\n\n if (imageState == ImageState.LOADED || imageState == ImageState.ERROR) {\n imageStyle.unlistenImageChange(listener);\n } else {\n if (imageState == ImageState.IDLE) {\n imageStyle.load();\n }\n\n imageState = imageStyle.getImageState();\n imageStyle.listenImageChange(listener);\n loading = true;\n }\n }\n\n renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup);\n return loading;\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../style/Style.js").default} style Style.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\nfunction renderFeatureInternal(replayGroup, feature, style, squaredTolerance, opt_transform, opt_declutterBuilderGroup) {\n var geometry = style.getGeometryFunction()(feature);\n\n if (!geometry) {\n return;\n }\n\n var simplifiedGeometry = geometry.simplifyTransformed(squaredTolerance, opt_transform);\n var renderer = style.getRenderer();\n\n if (renderer) {\n renderGeometry(replayGroup, simplifiedGeometry, style, feature);\n } else {\n var geometryRenderer = GEOMETRY_RENDERERS[simplifiedGeometry.getType()];\n geometryRenderer(replayGroup, simplifiedGeometry, style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../geom/Geometry.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n */\n\n\nfunction renderGeometry(replayGroup, geometry, style, feature) {\n if (geometry.getType() == geom_GeometryType.GEOMETRY_COLLECTION) {\n var geometries =\n /** @type {import("../geom/GeometryCollection.js").default} */\n geometry.getGeometries();\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n renderGeometry(replayGroup, geometries[i], style, feature);\n }\n\n return;\n }\n\n var replay = replayGroup.getBuilder(style.getZIndex(), BuilderType.DEFAULT);\n replay.drawCustom(\n /** @type {import("../geom/SimpleGeometry.js").default} */\n geometry, feature, style.getRenderer());\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} replayGroup Replay group.\n * @param {import("../geom/GeometryCollection.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderGeometryCollectionGeometry(replayGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var geometries = geometry.getGeometriesArray();\n var i, ii;\n\n for (i = 0, ii = geometries.length; i < ii; ++i) {\n var geometryRenderer = GEOMETRY_RENDERERS[geometries[i].getType()];\n geometryRenderer(replayGroup, geometries[i], style, feature, opt_declutterBuilderGroup);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/LineString.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.LINE_STRING);\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawLineString(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiLineString.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiLineStringGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var strokeStyle = style.getStroke();\n\n if (strokeStyle) {\n var lineStringReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.LINE_STRING);\n lineStringReplay.setFillStrokeStyle(null, strokeStyle);\n lineStringReplay.drawMultiLineString(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiPolygon.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (strokeStyle || fillStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.POLYGON);\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawMultiPolygon(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/Point.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import("../render/canvas.js").DeclutterImageWithText} */\n\n var declutterImageWithText;\n\n if (opt_declutterBuilderGroup) {\n builderGroup = opt_declutterBuilderGroup;\n declutterImageWithText = imageStyle && textStyle && textStyle.getText() ? {} : undefined;\n }\n\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n\n var imageReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.IMAGE);\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawPoint(geometry, feature);\n }\n\n if (textStyle && textStyle.getText()) {\n var textReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/MultiPoint.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderMultiPointGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var imageStyle = style.getImage();\n var textStyle = style.getText();\n /** @type {import("../render/canvas.js").DeclutterImageWithText} */\n\n var declutterImageWithText;\n\n if (opt_declutterBuilderGroup) {\n builderGroup = opt_declutterBuilderGroup;\n declutterImageWithText = imageStyle && textStyle && textStyle.getText() ? {} : undefined;\n }\n\n if (imageStyle) {\n if (imageStyle.getImageState() != ImageState.LOADED) {\n return;\n }\n\n var imageReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.IMAGE);\n imageReplay.setImageStyle(imageStyle, declutterImageWithText);\n imageReplay.drawMultiPoint(geometry, feature);\n }\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle, declutterImageWithText);\n textReplay.drawText(geometry, feature);\n }\n}\n/**\n * @param {import("../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../geom/Polygon.js").default|import("../render/Feature.js").default} geometry Geometry.\n * @param {import("../style/Style.js").default} style Style.\n * @param {import("../Feature.js").FeatureLike} feature Feature.\n * @param {import("../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n */\n\n\nfunction renderPolygonGeometry(builderGroup, geometry, style, feature, opt_declutterBuilderGroup) {\n var fillStyle = style.getFill();\n var strokeStyle = style.getStroke();\n\n if (fillStyle || strokeStyle) {\n var polygonReplay = builderGroup.getBuilder(style.getZIndex(), BuilderType.POLYGON);\n polygonReplay.setFillStrokeStyle(fillStyle, strokeStyle);\n polygonReplay.drawPolygon(geometry, feature);\n }\n\n var textStyle = style.getText();\n\n if (textStyle && textStyle.getText()) {\n var textReplay = (opt_declutterBuilderGroup || builderGroup).getBuilder(style.getZIndex(), BuilderType.TEXT);\n textReplay.setTextStyle(textStyle);\n textReplay.drawText(geometry, feature);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/VectorLayer.js\nvar VectorLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/VectorLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas renderer for vector layers.\n * @api\n */\n\nvar CanvasVectorLayerRenderer =\n/** @class */\nfunction (_super) {\n VectorLayer_extends(CanvasVectorLayerRenderer, _super);\n /**\n * @param {import("../../layer/Vector.js").default} vectorLayer Vector layer.\n */\n\n\n function CanvasVectorLayerRenderer(vectorLayer) {\n var _this = _super.call(this, vectorLayer) || this;\n /** @private */\n\n\n _this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);\n /**\n * @type {boolean}\n */\n\n _this.animatingOrInteracting_;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.dirty_ = false;\n /**\n * @type {ImageData}\n */\n\n _this.hitDetectionImageData_ = null;\n /**\n * @type {Array<import("../../Feature.js").default>}\n */\n\n _this.renderedFeatures_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedResolution_ = NaN;\n /**\n * @private\n * @type {import("../../extent.js").Extent}\n */\n\n _this.renderedExtent_ = createEmpty();\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRotation_;\n /**\n * @private\n * @type {import("../../coordinate").Coordinate}\n */\n\n _this.renderedCenter_ = null;\n /**\n * @private\n * @type {import("../../proj/Projection").default}\n */\n\n _this.renderedProjection_ = null;\n /**\n * @private\n * @type {function(import("../../Feature.js").default, import("../../Feature.js").default): number|null}\n */\n\n _this.renderedRenderOrder_ = null;\n /**\n * @private\n * @type {import("../../render/canvas/ExecutorGroup").default}\n */\n\n _this.replayGroup_ = null;\n /**\n * A new replay group had to be created by `prepareFrame()`\n * @type {boolean}\n */\n\n _this.replayGroupChanged = true;\n /**\n * @type {import("../../render/canvas/ExecutorGroup").default}\n */\n\n _this.declutterExecutorGroup = null;\n /**\n * Clipping to be performed by `renderFrame()`\n * @type {boolean}\n */\n\n _this.clipping = true;\n return _this;\n }\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasVectorLayerRenderer.prototype.useContainer = function (target, transform, opacity) {\n if (opacity < 1) {\n target = null;\n }\n\n _super.prototype.useContainer.call(this, target, transform, opacity);\n };\n /**\n * @param {ExecutorGroup} executorGroup Executor group.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("rbush").default=} opt_declutterTree Declutter tree.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderWorlds = function (executorGroup, frameState, opt_declutterTree) {\n var extent = frameState.extent;\n var viewState = frameState.viewState;\n var center = viewState.center;\n var resolution = viewState.resolution;\n var projection = viewState.projection;\n var rotation = viewState.rotation;\n var projectionExtent = projection.getExtent();\n var vectorSource = this.getLayer().getSource();\n var pixelRatio = frameState.pixelRatio;\n var viewHints = frameState.viewHints;\n var snapToPixel = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n var context = this.context;\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n var multiWorld = vectorSource.getWrapX() && projection.canWrapX();\n var worldWidth = multiWorld ? extent_getWidth(projectionExtent) : null;\n var endWorld = multiWorld ? Math.ceil((extent[2] - projectionExtent[2]) / worldWidth) + 1 : 1;\n var world = multiWorld ? Math.floor((extent[0] - projectionExtent[0]) / worldWidth) : 0;\n\n do {\n var transform = this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, world * worldWidth);\n executorGroup.execute(context, 1, transform, rotation, snapToPixel, undefined, opt_declutterTree);\n } while (++world < endWorld);\n };\n /**\n * Render declutter items for this layer\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderDeclutter = function (frameState) {\n if (this.declutterExecutorGroup) {\n this.renderWorlds(this.declutterExecutorGroup, frameState, frameState.declutterTree);\n }\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var pixelRatio = frameState.pixelRatio;\n var layerState = frameState.layerStatesArray[frameState.layerIndex]; // set forward and inverse pixel transforms\n\n makeScale(this.pixelTransform, 1 / pixelRatio, 1 / pixelRatio);\n makeInverse(this.inversePixelTransform, this.pixelTransform);\n var canvasTransform = transform_toString(this.pixelTransform);\n this.useContainer(target, canvasTransform, layerState.opacity);\n var context = this.context;\n var canvas = context.canvas;\n var replayGroup = this.replayGroup_;\n var declutterExecutorGroup = this.declutterExecutorGroup;\n\n if ((!replayGroup || replayGroup.isEmpty()) && (!declutterExecutorGroup || declutterExecutorGroup.isEmpty())) {\n if (!this.containerReused && canvas.width > 0) {\n canvas.width = 0;\n }\n\n return this.container;\n } // resize and clear\n\n\n var width = Math.round(frameState.size[0] * pixelRatio);\n var height = Math.round(frameState.size[1] * pixelRatio);\n\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n\n if (canvas.style.transform !== canvasTransform) {\n canvas.style.transform = canvasTransform;\n }\n } else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n\n this.preRender(context, frameState);\n var viewState = frameState.viewState;\n var projection = viewState.projection; // clipped rendering if layer extent is set\n\n var clipped = false;\n\n if (layerState.extent && this.clipping) {\n var layerExtent = fromUserExtent(layerState.extent, projection);\n clipped = !containsExtent(layerExtent, frameState.extent) && intersects(layerExtent, frameState.extent);\n\n if (clipped) {\n this.clipUnrotated(context, frameState, layerExtent);\n }\n }\n\n this.renderWorlds(replayGroup, frameState);\n\n if (clipped) {\n context.restore();\n }\n\n this.postRender(context, frameState);\n var opacity = layerState.opacity;\n var container = this.container;\n\n if (opacity !== parseFloat(container.style.opacity)) {\n container.style.opacity = opacity === 1 ? \'\' : String(opacity);\n }\n\n if (this.renderedRotation_ !== viewState.rotation) {\n this.renderedRotation_ = viewState.rotation;\n this.hitDetectionImageData_ = null;\n }\n\n return this.container;\n };\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.\n */\n\n\n CanvasVectorLayerRenderer.prototype.getFeatures = function (pixel) {\n return new Promise(\n /**\n * @param {function(Array<import("../../Feature").default|import("../../render/Feature").default>): void} resolve Resolver function.\n * @this {CanvasVectorLayerRenderer}\n */\n function (resolve) {\n if (!this.hitDetectionImageData_ && !this.animatingOrInteracting_) {\n var size = [this.context.canvas.width, this.context.canvas.height];\n apply(this.pixelTransform, size);\n var center = this.renderedCenter_;\n var resolution = this.renderedResolution_;\n var rotation = this.renderedRotation_;\n var projection = this.renderedProjection_;\n var extent = this.renderedExtent_;\n var layer = this.getLayer();\n var transforms = [];\n var width = size[0] / 2;\n var height = size[1] / 2;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, 0).slice());\n var source = layer.getSource();\n var projectionExtent = projection.getExtent();\n\n if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent)) {\n var startX = extent[0];\n var worldWidth = extent_getWidth(projectionExtent);\n var world = 0;\n var offsetX = void 0;\n\n while (startX < projectionExtent[0]) {\n --world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice());\n startX += worldWidth;\n }\n\n world = 0;\n startX = extent[2];\n\n while (startX > projectionExtent[2]) {\n ++world;\n offsetX = worldWidth * world;\n transforms.push(this.getRenderTransform(center, resolution, rotation, 0.5, width, height, offsetX).slice());\n startX -= worldWidth;\n }\n }\n\n this.hitDetectionImageData_ = createHitDetectionImageData(size, transforms, this.renderedFeatures_, layer.getStyleFunction(), extent, resolution, rotation);\n }\n\n resolve(hitDetect(pixel, this.renderedFeatures_, this.hitDetectionImageData_));\n }.bind(this));\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("../vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CanvasVectorLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n var _this = this;\n\n if (!this.replayGroup_) {\n return undefined;\n }\n\n var resolution = frameState.viewState.resolution;\n var rotation = frameState.viewState.rotation;\n var layer = this.getLayer();\n /** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */\n\n var features = {};\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {number} distanceSq The squared distance to the click position\n * @return {T|undefined} Callback result.\n */\n\n var featureCallback = function featureCallback(feature, geometry, distanceSq) {\n var key = getUid(feature);\n var match = features[key];\n\n if (!match) {\n if (distanceSq === 0) {\n features[key] = true;\n return callback(feature, layer, geometry);\n }\n\n matches.push(features[key] = {\n feature: feature,\n layer: layer,\n geometry: geometry,\n distanceSq: distanceSq,\n callback: callback\n });\n } else if (match !== true && distanceSq < match.distanceSq) {\n if (distanceSq === 0) {\n features[key] = true;\n matches.splice(matches.lastIndexOf(match), 1);\n return callback(feature, layer, geometry);\n }\n\n match.geometry = geometry;\n match.distanceSq = distanceSq;\n }\n\n return undefined;\n };\n\n var result;\n var executorGroups = [this.replayGroup_];\n\n if (this.declutterExecutorGroup) {\n executorGroups.push(this.declutterExecutorGroup);\n }\n\n executorGroups.some(function (executorGroup) {\n return result = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, executorGroup === _this.declutterExecutorGroup ? frameState.declutterTree.all().map(function (item) {\n return item.value;\n }) : null);\n });\n return result;\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n */\n\n\n CanvasVectorLayerRenderer.prototype.handleFontsChanged = function () {\n var layer = this.getLayer();\n\n if (layer.getVisible() && this.replayGroup_) {\n layer.changed();\n }\n };\n /**\n * Handle changes in image style state.\n * @param {import("../../events/Event.js").default} event Image style change event.\n * @private\n */\n\n\n CanvasVectorLayerRenderer.prototype.handleStyleImageChange_ = function (event) {\n this.renderIfReadyAndVisible();\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasVectorLayerRenderer.prototype.prepareFrame = function (frameState) {\n var vectorLayer = this.getLayer();\n var vectorSource = vectorLayer.getSource();\n\n if (!vectorSource) {\n return false;\n }\n\n var animating = frameState.viewHints[ViewHint.ANIMATING];\n var interacting = frameState.viewHints[ViewHint.INTERACTING];\n var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();\n var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();\n\n if (!this.dirty_ && !updateWhileAnimating && animating || !updateWhileInteracting && interacting) {\n this.animatingOrInteracting_ = true;\n return true;\n }\n\n this.animatingOrInteracting_ = false;\n var frameStateExtent = frameState.extent;\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var resolution = viewState.resolution;\n var pixelRatio = frameState.pixelRatio;\n var vectorLayerRevision = vectorLayer.getRevision();\n var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();\n var vectorLayerRenderOrder = vectorLayer.getRenderOrder();\n\n if (vectorLayerRenderOrder === undefined) {\n vectorLayerRenderOrder = defaultOrder;\n }\n\n var center = viewState.center.slice();\n var extent = buffer(frameStateExtent, vectorLayerRenderBuffer * resolution);\n var loadExtents = [extent.slice()];\n var projectionExtent = projection.getExtent();\n\n if (vectorSource.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, frameState.extent)) {\n // For the replay group, we need an extent that intersects the real world\n // (-180° to +180°). To support geometries in a coordinate range from -540°\n // to +540°, we add at least 1 world width on each side of the projection\n // extent. If the viewport is wider than the world, we need to add half of\n // the viewport width to make sure we cover the whole viewport.\n var worldWidth = extent_getWidth(projectionExtent);\n var gutter = Math.max(extent_getWidth(extent) / 2, worldWidth);\n extent[0] = projectionExtent[0] - gutter;\n extent[2] = projectionExtent[2] + gutter;\n coordinate_wrapX(center, projection);\n var loadExtent = wrapX(loadExtents[0], projection); // If the extent crosses the date line, we load data for both edges of the worlds\n\n if (loadExtent[0] < projectionExtent[0] && loadExtent[2] < projectionExtent[2]) {\n loadExtents.push([loadExtent[0] + worldWidth, loadExtent[1], loadExtent[2] + worldWidth, loadExtent[3]]);\n } else if (loadExtent[0] > projectionExtent[0] && loadExtent[2] > projectionExtent[2]) {\n loadExtents.push([loadExtent[0] - worldWidth, loadExtent[1], loadExtent[2] - worldWidth, loadExtent[3]]);\n }\n }\n\n if (!this.dirty_ && this.renderedResolution_ == resolution && this.renderedRevision_ == vectorLayerRevision && this.renderedRenderOrder_ == vectorLayerRenderOrder && containsExtent(this.renderedExtent_, extent)) {\n this.replayGroupChanged = false;\n return true;\n }\n\n this.replayGroup_ = null;\n this.dirty_ = false;\n var replayGroup = new canvas_BuilderGroup(getTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n var declutterBuilderGroup;\n\n if (this.getLayer().getDeclutter()) {\n declutterBuilderGroup = new canvas_BuilderGroup(getTolerance(resolution, pixelRatio), extent, resolution, pixelRatio);\n }\n\n var userProjection = getUserProjection();\n var userTransform;\n\n if (userProjection) {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n vectorSource.loadFeatures(toUserExtent(loadExtents[i], projection), resolution, userProjection);\n }\n\n userTransform = getTransformFromProjections(userProjection, projection);\n } else {\n for (var i = 0, ii = loadExtents.length; i < ii; ++i) {\n vectorSource.loadFeatures(loadExtents[i], resolution, projection);\n }\n }\n\n var squaredTolerance = getSquaredTolerance(resolution, pixelRatio);\n\n var render =\n /**\n * @param {import("../../Feature.js").default} feature Feature.\n * @this {CanvasVectorLayerRenderer}\n */\n function (feature) {\n var styles;\n var styleFunction = feature.getStyleFunction() || vectorLayer.getStyleFunction();\n\n if (styleFunction) {\n styles = styleFunction(feature, resolution);\n }\n\n if (styles) {\n var dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup, userTransform, declutterBuilderGroup);\n this.dirty_ = this.dirty_ || dirty;\n }\n }.bind(this);\n\n var userExtent = toUserExtent(extent, projection);\n /** @type {Array<import("../../Feature.js").default>} */\n\n var features = vectorSource.getFeaturesInExtent(userExtent);\n\n if (vectorLayerRenderOrder) {\n features.sort(vectorLayerRenderOrder);\n }\n\n for (var i = 0, ii = features.length; i < ii; ++i) {\n render(features[i]);\n }\n\n this.renderedFeatures_ = features;\n var replayGroupInstructions = replayGroup.finish();\n var executorGroup = new canvas_ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), replayGroupInstructions, vectorLayer.getRenderBuffer());\n\n if (declutterBuilderGroup) {\n this.declutterExecutorGroup = new canvas_ExecutorGroup(extent, resolution, pixelRatio, vectorSource.getOverlaps(), declutterBuilderGroup.finish(), vectorLayer.getRenderBuffer());\n }\n\n this.renderedResolution_ = resolution;\n this.renderedRevision_ = vectorLayerRevision;\n this.renderedRenderOrder_ = vectorLayerRenderOrder;\n this.renderedExtent_ = extent;\n this.renderedCenter_ = center;\n this.renderedProjection_ = projection;\n this.replayGroup_ = executorGroup;\n this.hitDetectionImageData_ = null;\n this.replayGroupChanged = true;\n return true;\n };\n /**\n * @param {import("../../Feature.js").default} feature Feature.\n * @param {number} squaredTolerance Squared render tolerance.\n * @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.\n * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group.\n * @param {import("../../proj.js").TransformFunction=} opt_transform Transform from user to view projection.\n * @param {import("../../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder for decluttering.\n * @return {boolean} `true` if an image is loading.\n */\n\n\n CanvasVectorLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_transform, opt_declutterBuilderGroup) {\n if (!styles) {\n return false;\n }\n\n var loading = false;\n\n if (Array.isArray(styles)) {\n for (var i = 0, ii = styles.length; i < ii; ++i) {\n loading = renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup) || loading;\n }\n } else {\n loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, opt_transform, opt_declutterBuilderGroup);\n }\n\n return loading;\n };\n\n return CanvasVectorLayerRenderer;\n}(canvas_Layer);\n\n/* harmony default export */ var canvas_VectorLayer = (CanvasVectorLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Vector.js\nvar Vector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Vector\n */\n\n\n\n\n/**\n * @classdesc\n * Vector data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @extends {BaseVectorLayer<import("../source/Vector.js").default>}\n * @api\n */\n\nvar VectorLayer =\n/** @class */\nfunction (_super) {\n Vector_extends(VectorLayer, _super);\n /**\n * @param {import("./BaseVector.js").Options=} opt_options Options.\n */\n\n\n function VectorLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n */\n\n\n VectorLayer.prototype.createRenderer = function () {\n return new canvas_VectorLayer(this);\n };\n\n return VectorLayer;\n}(BaseVector);\n\n/* harmony default export */ var Vector = (VectorLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/structs/RBush.js\n/**\n * @module ol/structs/RBush\n */\n\n\n\n\n/**\n * @typedef {Object} Entry\n * @property {number} minX\n * @property {number} minY\n * @property {number} maxX\n * @property {number} maxY\n * @property {Object} [value]\n */\n\n/**\n * @classdesc\n * Wrapper around the RBush by Vladimir Agafonkin.\n * See https://github.com/mourner/rbush.\n *\n * @template T\n */\n\nvar RBush =\n/** @class */\nfunction () {\n /**\n * @param {number=} opt_maxEntries Max entries.\n */\n function RBush(opt_maxEntries) {\n /**\n * @private\n */\n this.rbush_ = new (rbush_min_default())(opt_maxEntries);\n /**\n * A mapping between the objects added to this rbush wrapper\n * and the objects that are actually added to the internal rbush.\n * @private\n * @type {Object<string, Entry>}\n */\n\n this.items_ = {};\n }\n /**\n * Insert a value into the RBush.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {T} value Value.\n */\n\n\n RBush.prototype.insert = function (extent, value) {\n /** @type {Entry} */\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value\n };\n this.rbush_.insert(item);\n this.items_[getUid(value)] = item;\n };\n /**\n * Bulk-insert values into the RBush.\n * @param {Array<import("../extent.js").Extent>} extents Extents.\n * @param {Array<T>} values Values.\n */\n\n\n RBush.prototype.load = function (extents, values) {\n var items = new Array(values.length);\n\n for (var i = 0, l = values.length; i < l; i++) {\n var extent = extents[i];\n var value = values[i];\n /** @type {Entry} */\n\n var item = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3],\n value: value\n };\n items[i] = item;\n this.items_[getUid(value)] = item;\n }\n\n this.rbush_.load(items);\n };\n /**\n * Remove a value from the RBush.\n * @param {T} value Value.\n * @return {boolean} Removed.\n */\n\n\n RBush.prototype.remove = function (value) {\n var uid = getUid(value); // get the object in which the value was wrapped when adding to the\n // internal rbush. then use that object to do the removal.\n\n var item = this.items_[uid];\n delete this.items_[uid];\n return this.rbush_.remove(item) !== null;\n };\n /**\n * Update the extent of a value in the RBush.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {T} value Value.\n */\n\n\n RBush.prototype.update = function (extent, value) {\n var item = this.items_[getUid(value)];\n var bbox = [item.minX, item.minY, item.maxX, item.maxY];\n\n if (!extent_equals(bbox, extent)) {\n this.remove(value);\n this.insert(extent, value);\n }\n };\n /**\n * Return all values in the RBush.\n * @return {Array<T>} All.\n */\n\n\n RBush.prototype.getAll = function () {\n var items = this.rbush_.all();\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Return all values in the given extent.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<T>} All in extent.\n */\n\n\n RBush.prototype.getInExtent = function (extent) {\n /** @type {Entry} */\n var bbox = {\n minX: extent[0],\n minY: extent[1],\n maxX: extent[2],\n maxY: extent[3]\n };\n var items = this.rbush_.search(bbox);\n return items.map(function (item) {\n return item.value;\n });\n };\n /**\n * Calls a callback function with each value in the tree.\n * If the callback returns a truthy value, this value is returned without\n * checking the rest of the tree.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEach = function (callback) {\n return this.forEach_(this.getAll(), callback);\n };\n /**\n * Calls a callback function with each value in the provided extent.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(T): *} callback Callback.\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEachInExtent = function (extent, callback) {\n return this.forEach_(this.getInExtent(extent), callback);\n };\n /**\n * @param {Array<T>} values Values.\n * @param {function(T): *} callback Callback.\n * @private\n * @return {*} Callback return value.\n */\n\n\n RBush.prototype.forEach_ = function (values, callback) {\n var result;\n\n for (var i = 0, l = values.length; i < l; i++) {\n result = callback(values[i]);\n\n if (result) {\n return result;\n }\n }\n\n return result;\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n RBush.prototype.isEmpty = function () {\n return obj_isEmpty(this.items_);\n };\n /**\n * Remove all values from the RBush.\n */\n\n\n RBush.prototype.clear = function () {\n this.rbush_.clear();\n this.items_ = {};\n };\n /**\n * @param {import("../extent.js").Extent=} opt_extent Extent.\n * @return {import("../extent.js").Extent} Extent.\n */\n\n\n RBush.prototype.getExtent = function (opt_extent) {\n var data = this.rbush_.toJSON();\n return createOrUpdate(data.minX, data.minY, data.maxX, data.maxY, opt_extent);\n };\n /**\n * @param {RBush} rbush R-Tree.\n */\n\n\n RBush.prototype.concat = function (rbush) {\n this.rbush_.load(rbush.rbush_.all());\n\n for (var i in rbush.items_) {\n this.items_[i] = rbush.items_[i];\n }\n };\n\n return RBush;\n}();\n\n/* harmony default export */ var structs_RBush = (RBush);\n;// CONCATENATED MODULE: ./node_modules/ol/source/Source.js\nvar Source_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/Source\n */\n\n\n\n\n\n\n/**\n * A function that returns a string or an array of strings representing source\n * attributions.\n *\n * @typedef {function(import("../PluggableMap.js").FrameState): (string|Array<string>)} Attribution\n */\n\n/**\n * A type that can be used to provide attribution information for data sources.\n *\n * It represents either\n * * a simple string (e.g. `\'© Acme Inc.\'`)\n * * an array of simple strings (e.g. `[\'© Acme Inc.\', \'© Bacme Inc.\']`)\n * * a function that returns a string or array of strings ({@link module:ol/source/Source~Attribution})\n *\n * @typedef {string|Array<string>|Attribution} AttributionLike\n */\n\n/**\n * @typedef {Object} Options\n * @property {AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {import("./State.js").default} [state=\'ready\']\n * @property {boolean} [wrapX=false]\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for {@link module:ol/layer/Layer~Layer} sources.\n *\n * A generic `change` event is triggered when the state of the source changes.\n * @abstract\n * @api\n */\n\nvar Source =\n/** @class */\nfunction (_super) {\n Source_extends(Source, _super);\n /**\n * @param {Options} options Source options.\n */\n\n\n function Source(options) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../proj/Projection.js").default}\n */\n\n\n _this.projection_ = proj_get(options.projection);\n /**\n * @private\n * @type {?Attribution}\n */\n\n _this.attributions_ = adaptAttributions(options.attributions);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.attributionsCollapsible_ = options.attributionsCollapsible !== undefined ? options.attributionsCollapsible : true;\n /**\n * This source is currently loading data. Sources that defer loading to the\n * map\'s tile queue never set this to `true`.\n * @type {boolean}\n */\n\n _this.loading = false;\n /**\n * @private\n * @type {import("./State.js").default}\n */\n\n _this.state_ = options.state !== undefined ? options.state : State.READY;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.wrapX_ = options.wrapX !== undefined ? options.wrapX : false;\n return _this;\n }\n /**\n * Get the attribution function for the source.\n * @return {?Attribution} Attribution function.\n */\n\n\n Source.prototype.getAttributions = function () {\n return this.attributions_;\n };\n /**\n * @return {boolean} Attributions are collapsible.\n */\n\n\n Source.prototype.getAttributionsCollapsible = function () {\n return this.attributionsCollapsible_;\n };\n /**\n * Get the projection of the source.\n * @return {import("../proj/Projection.js").default} Projection.\n * @api\n */\n\n\n Source.prototype.getProjection = function () {\n return this.projection_;\n };\n /**\n * @abstract\n * @return {Array<number>|undefined} Resolutions.\n */\n\n\n Source.prototype.getResolutions = function () {\n return util_abstract();\n };\n /**\n * Get the state of the source, see {@link module:ol/source/State~State} for possible states.\n * @return {import("./State.js").default} State.\n * @api\n */\n\n\n Source.prototype.getState = function () {\n return this.state_;\n };\n /**\n * @return {boolean|undefined} Wrap X.\n */\n\n\n Source.prototype.getWrapX = function () {\n return this.wrapX_;\n };\n /**\n * @return {Object|undefined} Context options.\n */\n\n\n Source.prototype.getContextOptions = function () {\n return undefined;\n };\n /**\n * Refreshes the source. The source will be cleared, and data from the server will be reloaded.\n * @api\n */\n\n\n Source.prototype.refresh = function () {\n this.changed();\n };\n /**\n * Set the attributions of the source.\n * @param {AttributionLike|undefined} attributions Attributions.\n * Can be passed as `string`, `Array<string>`, {@link module:ol/source/Source~Attribution},\n * or `undefined`.\n * @api\n */\n\n\n Source.prototype.setAttributions = function (attributions) {\n this.attributions_ = adaptAttributions(attributions);\n this.changed();\n };\n /**\n * Set the state of the source.\n * @param {import("./State.js").default} state State.\n */\n\n\n Source.prototype.setState = function (state) {\n this.state_ = state;\n this.changed();\n };\n\n return Source;\n}(ol_Object);\n/**\n * Turns the attributions option into an attributions function.\n * @param {AttributionLike|undefined} attributionLike The attribution option.\n * @return {?Attribution} An attribution function (or null).\n */\n\n\nfunction adaptAttributions(attributionLike) {\n if (!attributionLike) {\n return null;\n }\n\n if (Array.isArray(attributionLike)) {\n return function (frameState) {\n return attributionLike;\n };\n }\n\n if (typeof attributionLike === \'function\') {\n return attributionLike;\n }\n\n return function (frameState) {\n return [attributionLike];\n };\n}\n\n/* harmony default export */ var source_Source = (Source);\n;// CONCATENATED MODULE: ./node_modules/ol/source/VectorEventType.js\n/**\n * @module ol/source/VectorEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var VectorEventType = ({\n /**\n * Triggered when a feature is added to the source.\n * @event module:ol/source/Vector.VectorSourceEvent#addfeature\n * @api\n */\n ADDFEATURE: \'addfeature\',\n\n /**\n * Triggered when a feature is updated.\n * @event module:ol/source/Vector.VectorSourceEvent#changefeature\n * @api\n */\n CHANGEFEATURE: \'changefeature\',\n\n /**\n * Triggered when the clear method is called on the source.\n * @event module:ol/source/Vector.VectorSourceEvent#clear\n * @api\n */\n CLEAR: \'clear\',\n\n /**\n * Triggered when a feature is removed from the source.\n * See {@link module:ol/source/Vector#clear source.clear()} for exceptions.\n * @event module:ol/source/Vector.VectorSourceEvent#removefeature\n * @api\n */\n REMOVEFEATURE: \'removefeature\',\n\n /**\n * Triggered when features starts loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadstart\n * @api\n */\n FEATURESLOADSTART: \'featuresloadstart\',\n\n /**\n * Triggered when features finishes loading.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloadend\n * @api\n */\n FEATURESLOADEND: \'featuresloadend\',\n\n /**\n * Triggered if feature loading results in an error.\n * @event module:ol/source/Vector.VectorSourceEvent#featuresloaderror\n * @api\n */\n FEATURESLOADERROR: \'featuresloaderror\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/loadingstrategy.js\n/**\n * @module ol/loadingstrategy\n */\n\n/**\n * Strategy function for loading all features with a single request.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n * @api\n */\nfunction loadingstrategy_all(extent, resolution) {\n return [[-Infinity, -Infinity, Infinity, Infinity]];\n}\n/**\n * Strategy function for loading features based on the view\'s extent and\n * resolution.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n * @api\n */\n\nfunction bbox(extent, resolution) {\n return [extent];\n}\n/**\n * Creates a strategy function for loading features based on a tile grid.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {function(import("./extent.js").Extent, number): Array<import("./extent.js").Extent>} Loading strategy.\n * @api\n */\n\nfunction tile(tileGrid) {\n return (\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array<import("./extent.js").Extent>} Extents.\n */\n function (extent, resolution) {\n var z = tileGrid.getZForResolution(resolution);\n var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n /** @type {Array<import("./extent.js").Extent>} */\n\n var extents = [];\n /** @type {import("./tilecoord.js").TileCoord} */\n\n var tileCoord = [z, 0, 0];\n\n for (tileCoord[1] = tileRange.minX; tileCoord[1] <= tileRange.maxX; ++tileCoord[1]) {\n for (tileCoord[2] = tileRange.minY; tileCoord[2] <= tileRange.maxY; ++tileCoord[2]) {\n extents.push(tileGrid.getTileCoordExtent(tileCoord));\n }\n }\n\n return extents;\n }\n );\n}\n;// CONCATENATED MODULE: ./node_modules/ol/format/FormatType.js\n/**\n * @module ol/format/FormatType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var FormatType = ({\n ARRAY_BUFFER: \'arraybuffer\',\n JSON: \'json\',\n TEXT: \'text\',\n XML: \'xml\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/featureloader.js\n/**\n * @module ol/featureloader\n */\n\n\n/**\n *\n * @type {boolean}\n * @private\n */\n\nvar withCredentials = false;\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * load features.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area to be loaded,\n * a `{number}` representing the resolution (map units per pixel), an\n * {@link module:ol/proj/Projection} for the projection and success and failure callbacks as\n * arguments. `this` within the function is bound to the\n * {@link module:ol/source/Vector} it\'s called from.\n *\n * The function is responsible for loading the features and adding them to the\n * source.\n * @typedef {function(this:(import("./source/Vector").default|import("./VectorTile.js").default),\n * import("./extent.js").Extent,\n * number,\n * import("./proj/Projection.js").default,\n * function(Array<import("./Feature.js").default>): void=,\n * function(): void=): void} FeatureLoader\n * @api\n */\n\n/**\n * {@link module:ol/source/Vector} sources use a function of this type to\n * get the url to load features from.\n *\n * This function takes an {@link module:ol/extent~Extent} representing the area\n * to be loaded, a `{number}` representing the resolution (map units per pixel)\n * and an {@link module:ol/proj/Projection} for the projection as\n * arguments and returns a `{string}` representing the URL.\n * @typedef {function(import("./extent.js").Extent, number, import("./proj/Projection.js").default): string} FeatureUrlFunction\n * @api\n */\n\n/**\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {function(Array<import("./Feature.js").default>, import("./proj/Projection.js").default): void} success Success\n * Function called with the loaded features and optionally with the data projection.\n * @param {function(): void} failure Failure\n * Function called when loading failed.\n */\n\nfunction loadFeaturesXhr(url, format, extent, resolution, projection, success, failure) {\n var xhr = new XMLHttpRequest();\n xhr.open(\'GET\', typeof url === \'function\' ? url(extent, resolution, projection) : url, true);\n\n if (format.getType() == FormatType.ARRAY_BUFFER) {\n xhr.responseType = \'arraybuffer\';\n }\n\n xhr.withCredentials = withCredentials;\n /**\n * @param {Event} event Event.\n * @private\n */\n\n xhr.onload = function (event) {\n // status will be 0 for file:// urls\n if (!xhr.status || xhr.status >= 200 && xhr.status < 300) {\n var type = format.getType();\n /** @type {Document|Node|Object|string|undefined} */\n\n var source = void 0;\n\n if (type == FormatType.JSON || type == FormatType.TEXT) {\n source = xhr.responseText;\n } else if (type == FormatType.XML) {\n source = xhr.responseXML;\n\n if (!source) {\n source = new DOMParser().parseFromString(xhr.responseText, \'application/xml\');\n }\n } else if (type == FormatType.ARRAY_BUFFER) {\n source =\n /** @type {ArrayBuffer} */\n xhr.response;\n }\n\n if (source) {\n success(\n /** @type {Array<import("./Feature.js").default>} */\n format.readFeatures(source, {\n extent: extent,\n featureProjection: projection\n }), format.readProjection(source));\n } else {\n failure();\n }\n } else {\n failure();\n }\n };\n /**\n * @private\n */\n\n\n xhr.onerror = failure;\n xhr.send();\n}\n/**\n * Create an XHR feature loader for a `url` and `format`. The feature loader\n * loads features (with XHR), parses the features, and adds them to the\n * vector source.\n * @param {string|FeatureUrlFunction} url Feature URL service.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @return {FeatureLoader} The feature loader.\n * @api\n */\n\nfunction xhr(url, format) {\n /**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @param {function(): void=} success Success\n * Function called when loading succeeded.\n * @param {function(): void=} failure Failure\n * Function called when loading failed.\n * @this {import("./source/Vector").default}\n */\n return function (extent, resolution, projection, success, failure) {\n var source =\n /** @type {import("./source/Vector").default} */\n this;\n loadFeaturesXhr(url, format, extent, resolution, projection,\n /**\n * @param {Array<import("./Feature.js").default>} features The loaded features.\n * @param {import("./proj/Projection.js").default} dataProjection Data\n * projection.\n */\n function (features, dataProjection) {\n if (success !== undefined) {\n success(features);\n }\n\n source.addFeatures(features);\n },\n /* FIXME handle error */\n failure ? failure : VOID);\n };\n}\n/**\n * Setter for the withCredentials configuration for the XHR.\n *\n * @param {boolean} xhrWithCredentials The value of withCredentials to set.\n * Compare https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/\n * @api\n */\n\nfunction setWithCredentials(xhrWithCredentials) {\n withCredentials = xhrWithCredentials;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/Vector.js\n/**\n * @module ol/source/Vector\n */\nvar source_Vector_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/extent~Extent} and a resolution as arguments, and\n * returns an array of {@link module:ol/extent~Extent} with the extents to load. Usually this\n * is one of the standard {@link module:ol/loadingstrategy} strategies.\n *\n * @typedef {function(import("../extent.js").Extent, number): Array<import("../extent.js").Extent>} LoadingStrategy\n * @api\n */\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Vector} instances are instances of this\n * type.\n * @template {import("../geom/Geometry.js").default} Geometry\n */\n\nvar VectorSourceEvent =\n/** @class */\nfunction (_super) {\n source_Vector_extends(VectorSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import("../Feature.js").default<Geometry>=} opt_feature Feature.\n * @param {Array<import("../Feature.js").default<Geometry>>=} opt_features Features.\n */\n\n\n function VectorSourceEvent(type, opt_feature, opt_features) {\n var _this = _super.call(this, type) || this;\n /**\n * The added or removed feature for the `ADDFEATURE` and `REMOVEFEATURE` events, `undefined` otherwise.\n * @type {import("../Feature.js").default<Geometry>|undefined}\n * @api\n */\n\n\n _this.feature = opt_feature;\n /**\n * The loaded features for the `FEATURESLOADED` event, `undefined` otherwise.\n * @type {Array<import("../Feature.js").default<Geometry>>|undefined}\n * @api\n */\n\n _this.features = opt_features;\n return _this;\n }\n\n return VectorSourceEvent;\n}(Event);\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {Array<import("../Feature.js").default>|Collection<import("../Feature.js").default>} [features]\n * Features. If provided as {@link module:ol/Collection}, the features in the source\n * and the collection will stay in sync.\n * @property {import("../format/Feature.js").default} [format] The feature format used by the XHR\n * feature loader when `url` is set. Required if `url` is set, otherwise ignored.\n * @property {import("../featureloader.js").FeatureLoader} [loader]\n * The loader function used to load features, from a remote source for example.\n * If this is not set and `url` is set, the source will create and use an XHR\n * feature loader.\n *\n * Example:\n *\n * ```js\n * import {Vector} from \'ol/source\';\n * import {GeoJSON} from \'ol/format\';\n * import {bbox} from \'ol/loadingstrategy\';\n *\n * var vectorSource = new Vector({\n * format: new GeoJSON(),\n * loader: function(extent, resolution, projection) {\n * var proj = projection.getCode();\n * var url = \'https://ahocevar.com/geoserver/wfs?service=WFS&\' +\n * \'version=1.1.0&request=GetFeature&typename=osm:water_areas&\' +\n * \'outputFormat=application/json&srsname=\' + proj + \'&\' +\n * \'bbox=\' + extent.join(\',\') + \',\' + proj;\n * var xhr = new XMLHttpRequest();\n * xhr.open(\'GET\', url);\n * var onError = function() {\n * vectorSource.removeLoadedExtent(extent);\n * }\n * xhr.onerror = onError;\n * xhr.onload = function() {\n * if (xhr.status == 200) {\n * vectorSource.addFeatures(\n * vectorSource.getFormat().readFeatures(xhr.responseText));\n * } else {\n * onError();\n * }\n * }\n * xhr.send();\n * },\n * strategy: bbox\n * });\n * ```\n * @property {boolean} [overlaps=true] This source may have overlapping geometries.\n * Setting this to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {LoadingStrategy} [strategy] The loading strategy to use.\n * By default an {@link module:ol/loadingstrategy~all}\n * strategy is used, a one-off strategy which loads all features at once.\n * @property {string|import("../featureloader.js").FeatureUrlFunction} [url]\n * Setting this option instructs the source to load features using an XHR loader\n * (see {@link module:ol/featureloader~xhr}). Use a `string` and an\n * {@link module:ol/loadingstrategy~all} for a one-off download of all features from\n * the given URL. Use a {@link module:ol/featureloader~FeatureUrlFunction} to generate the url with\n * other loading strategies.\n * Requires `format` to be set as well.\n * When default XHR feature loader is provided, the features will\n * be transformed from the data projection to the view projection\n * during parsing. If your remote data source does not advertise its projection\n * properly, this transformation will be incorrect. For some formats, the\n * default projection (usually EPSG:4326) can be overridden by setting the\n * dataProjection constructor option on the format.\n * Note that if a source contains non-feature data, such as a GeoJSON geometry\n * or a KML NetworkLink, these will be ignored. Use a custom loader to load these.\n * @property {boolean} [useSpatialIndex=true]\n * By default, an RTree is used as spatial index. When features are removed and\n * added frequently, and the total number of features is low, setting this to\n * `false` may improve performance.\n *\n * Note that\n * {@link module:ol/source/Vector~VectorSource#getFeaturesInExtent},\n * {@link module:ol/source/Vector~VectorSource#getClosestFeatureToCoordinate} and\n * {@link module:ol/source/Vector~VectorSource#getExtent} cannot be used when `useSpatialIndex` is\n * set to `false`, and {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent} will loop\n * through all features.\n *\n * When set to `false`, the features will be maintained in an\n * {@link module:ol/Collection}, which can be retrieved through\n * {@link module:ol/source/Vector~VectorSource#getFeaturesCollection}.\n * @property {boolean} [wrapX=true] Wrap the world horizontally. For vector editing across the\n * -180° and 180° meridians to work properly, this should be set to `false`. The\n * resulting geometry coordinates will then exceed the world bounds.\n */\n\n/**\n * @classdesc\n * Provides a source of features for vector layers. Vector features provided\n * by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for\n * vector data that is optimized for rendering.\n *\n * @fires VectorSourceEvent\n * @api\n * @template {import("../geom/Geometry.js").default} Geometry\n */\n\nvar VectorSource =\n/** @class */\nfunction (_super) {\n source_Vector_extends(VectorSource, _super);\n /**\n * @param {Options=} opt_options Vector source options.\n */\n\n\n function VectorSource(opt_options) {\n var _this = this;\n\n var options = opt_options || {};\n _this = _super.call(this, {\n attributions: options.attributions,\n projection: undefined,\n state: State.READY,\n wrapX: options.wrapX !== undefined ? options.wrapX : true\n }) || this;\n /**\n * @private\n * @type {import("../featureloader.js").FeatureLoader}\n */\n\n _this.loader_ = VOID;\n /**\n * @private\n * @type {import("../format/Feature.js").default|undefined}\n */\n\n _this.format_ = options.format;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overlaps_ = options.overlaps === undefined ? true : options.overlaps;\n /**\n * @private\n * @type {string|import("../featureloader.js").FeatureUrlFunction|undefined}\n */\n\n _this.url_ = options.url;\n\n if (options.loader !== undefined) {\n _this.loader_ = options.loader;\n } else if (_this.url_ !== undefined) {\n asserts_assert(_this.format_, 7); // `format` must be set when `url` is set\n // create a XHR feature loader for "url" and "format"\n\n _this.loader_ = xhr(_this.url_,\n /** @type {import("../format/Feature.js").default} */\n _this.format_);\n }\n /**\n * @private\n * @type {LoadingStrategy}\n */\n\n\n _this.strategy_ = options.strategy !== undefined ? options.strategy : loadingstrategy_all;\n var useSpatialIndex = options.useSpatialIndex !== undefined ? options.useSpatialIndex : true;\n /**\n * @private\n * @type {RBush<import("../Feature.js").default<Geometry>>}\n */\n\n _this.featuresRtree_ = useSpatialIndex ? new structs_RBush() : null;\n /**\n * @private\n * @type {RBush<{extent: import("../extent.js").Extent}>}\n */\n\n _this.loadedExtentsRtree_ = new structs_RBush();\n /**\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.nullGeometryFeatures_ = {};\n /**\n * A lookup of features by id (the return from feature.getId()).\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.idIndex_ = {};\n /**\n * A lookup of features by uid (using getUid(feature)).\n * @private\n * @type {!Object<string, import("../Feature.js").default<Geometry>>}\n */\n\n _this.uidIndex_ = {};\n /**\n * @private\n * @type {Object<string, Array<import("../events.js").EventsKey>>}\n */\n\n _this.featureChangeKeys_ = {};\n /**\n * @private\n * @type {Collection<import("../Feature.js").default<Geometry>>}\n */\n\n _this.featuresCollection_ = null;\n var collection, features;\n\n if (Array.isArray(options.features)) {\n features = options.features;\n } else if (options.features) {\n collection = options.features;\n features = collection.getArray();\n }\n\n if (!useSpatialIndex && collection === undefined) {\n collection = new ol_Collection(features);\n }\n\n if (features !== undefined) {\n _this.addFeaturesInternal(features);\n }\n\n if (collection !== undefined) {\n _this.bindFeaturesCollection_(collection);\n }\n\n return _this;\n }\n /**\n * Add a single feature to the source. If you want to add a batch of features\n * at once, call {@link module:ol/source/Vector~VectorSource#addFeatures #addFeatures()}\n * instead. A feature will not be added to the source if feature with\n * the same id is already there. The reason for this behavior is to avoid\n * feature duplication when using bbox or tile loading strategies.\n * Note: this also applies if an {@link module:ol/Collection} is used for features,\n * meaning that if a feature with a duplicate id is added in the collection, it will\n * be removed from it right away.\n * @param {import("../Feature.js").default<Geometry>} feature Feature to add.\n * @api\n */\n\n\n VectorSource.prototype.addFeature = function (feature) {\n this.addFeatureInternal(feature);\n this.changed();\n };\n /**\n * Add a feature without firing a `change` event.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @protected\n */\n\n\n VectorSource.prototype.addFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n\n if (!this.addToIndex_(featureKey, feature)) {\n if (this.featuresCollection_) {\n this.featuresCollection_.remove(feature);\n }\n\n return;\n }\n\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n\n if (geometry) {\n var extent = geometry.getExtent();\n\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n } else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, feature));\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @private\n */\n\n\n VectorSource.prototype.setupChangeEvents_ = function (featureKey, feature) {\n this.featureChangeKeys_[featureKey] = [listen(feature, EventType.CHANGE, this.handleFeatureChange_, this), listen(feature, ObjectEventType.PROPERTYCHANGE, this.handleFeatureChange_, this)];\n };\n /**\n * @param {string} featureKey Unique identifier for the feature.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @return {boolean} The feature is "valid", in the sense that it is also a\n * candidate for insertion into the Rtree.\n * @private\n */\n\n\n VectorSource.prototype.addToIndex_ = function (featureKey, feature) {\n var valid = true;\n var id = feature.getId();\n\n if (id !== undefined) {\n if (!(id.toString() in this.idIndex_)) {\n this.idIndex_[id.toString()] = feature;\n } else {\n valid = false;\n }\n }\n\n if (valid) {\n asserts_assert(!(featureKey in this.uidIndex_), 30); // The passed `feature` was already added to the source\n\n this.uidIndex_[featureKey] = feature;\n }\n\n return valid;\n };\n /**\n * Add a batch of features to the source.\n * @param {Array<import("../Feature.js").default<Geometry>>} features Features to add.\n * @api\n */\n\n\n VectorSource.prototype.addFeatures = function (features) {\n this.addFeaturesInternal(features);\n this.changed();\n };\n /**\n * Add features without firing a `change` event.\n * @param {Array<import("../Feature.js").default<Geometry>>} features Features.\n * @protected\n */\n\n\n VectorSource.prototype.addFeaturesInternal = function (features) {\n var extents = [];\n var newFeatures = [];\n var geometryFeatures = [];\n\n for (var i = 0, length_1 = features.length; i < length_1; i++) {\n var feature = features[i];\n var featureKey = getUid(feature);\n\n if (this.addToIndex_(featureKey, feature)) {\n newFeatures.push(feature);\n }\n }\n\n for (var i = 0, length_2 = newFeatures.length; i < length_2; i++) {\n var feature = newFeatures[i];\n var featureKey = getUid(feature);\n this.setupChangeEvents_(featureKey, feature);\n var geometry = feature.getGeometry();\n\n if (geometry) {\n var extent = geometry.getExtent();\n extents.push(extent);\n geometryFeatures.push(feature);\n } else {\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n }\n\n if (this.featuresRtree_) {\n this.featuresRtree_.load(extents, geometryFeatures);\n }\n\n for (var i = 0, length_3 = newFeatures.length; i < length_3; i++) {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.ADDFEATURE, newFeatures[i]));\n }\n };\n /**\n * @param {!Collection<import("../Feature.js").default<Geometry>>} collection Collection.\n * @private\n */\n\n\n VectorSource.prototype.bindFeaturesCollection_ = function (collection) {\n var modifyingCollection = false;\n this.addEventListener(VectorEventType.ADDFEATURE,\n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.push(evt.feature);\n modifyingCollection = false;\n }\n });\n this.addEventListener(VectorEventType.REMOVEFEATURE,\n /**\n * @param {VectorSourceEvent<Geometry>} evt The vector source event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n collection.remove(evt.feature);\n modifyingCollection = false;\n }\n });\n collection.addEventListener(CollectionEventType.ADD,\n /**\n * @param {import("../Collection.js").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.addFeature(\n /** @type {import("../Feature.js").default<Geometry>} */\n evt.element);\n modifyingCollection = false;\n }\n }.bind(this));\n collection.addEventListener(CollectionEventType.REMOVE,\n /**\n * @param {import("../Collection.js").CollectionEvent} evt The collection event\n */\n function (evt) {\n if (!modifyingCollection) {\n modifyingCollection = true;\n this.removeFeature(\n /** @type {import("../Feature.js").default<Geometry>} */\n evt.element);\n modifyingCollection = false;\n }\n }.bind(this));\n this.featuresCollection_ = collection;\n };\n /**\n * Remove all features from the source.\n * @param {boolean=} opt_fast Skip dispatching of {@link module:ol/source/Vector.VectorSourceEvent#removefeature} events.\n * @api\n */\n\n\n VectorSource.prototype.clear = function (opt_fast) {\n if (opt_fast) {\n for (var featureId in this.featureChangeKeys_) {\n var keys = this.featureChangeKeys_[featureId];\n keys.forEach(unlistenByKey);\n }\n\n if (!this.featuresCollection_) {\n this.featureChangeKeys_ = {};\n this.idIndex_ = {};\n this.uidIndex_ = {};\n }\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.forEach(this.removeFeatureInternal.bind(this));\n\n for (var id in this.nullGeometryFeatures_) {\n this.removeFeatureInternal(this.nullGeometryFeatures_[id]);\n }\n }\n }\n\n if (this.featuresCollection_) {\n this.featuresCollection_.clear();\n }\n\n if (this.featuresRtree_) {\n this.featuresRtree_.clear();\n }\n\n this.nullGeometryFeatures_ = {};\n var clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);\n this.dispatchEvent(clearEvent);\n this.changed();\n };\n /**\n * Iterate through all features on the source, calling the provided callback\n * with each one. If the callback returns any "truthy" value, iteration will\n * stop and the function will return the same value.\n * Note: this function only iterate through the feature that have a defined geometry.\n *\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * on the source. Return a truthy value to stop iteration.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeature = function (callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEach(callback);\n } else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometries contain the provided\n * coordinate, calling the callback with each feature. If the callback returns\n * a "truthy" value, iteration will stop and the function will return the same\n * value.\n *\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose goemetry contains the provided coordinate.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n */\n\n\n VectorSource.prototype.forEachFeatureAtCoordinateDirect = function (coordinate, callback) {\n var extent = [coordinate[0], coordinate[1], coordinate[0], coordinate[1]];\n return this.forEachFeatureInExtent(extent, function (feature) {\n var geometry = feature.getGeometry();\n\n if (geometry.intersectsCoordinate(coordinate)) {\n return callback(feature);\n } else {\n return undefined;\n }\n });\n };\n /**\n * Iterate through all features whose bounding box intersects the provided\n * extent (note that the feature\'s geometry may not intersect the extent),\n * calling the callback with each feature. If the callback returns a "truthy"\n * value, iteration will stop and the function will return the same value.\n *\n * If you are interested in features whose geometry intersects an extent, call\n * the {@link module:ol/source/Vector~VectorSource#forEachFeatureIntersectingExtent #forEachFeatureIntersectingExtent()} method instead.\n *\n * When `useSpatialIndex` is set to false, this method will loop through all\n * features, equivalent to {@link module:ol/source/Vector~VectorSource#forEachFeature #forEachFeature()}.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose bounding box intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeatureInExtent = function (extent, callback) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.forEachInExtent(extent, callback);\n } else if (this.featuresCollection_) {\n this.featuresCollection_.forEach(callback);\n }\n };\n /**\n * Iterate through all features whose geometry intersects the provided extent,\n * calling the callback with each feature. If the callback returns a "truthy"\n * value, iteration will stop and the function will return the same value.\n *\n * If you only want to test for bounding box intersection, call the\n * {@link module:ol/source/Vector~VectorSource#forEachFeatureInExtent #forEachFeatureInExtent()} method instead.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {function(import("../Feature.js").default<Geometry>): T} callback Called with each feature\n * whose geometry intersects the provided extent.\n * @return {T|undefined} The return value from the last call to the callback.\n * @template T\n * @api\n */\n\n\n VectorSource.prototype.forEachFeatureIntersectingExtent = function (extent, callback) {\n return this.forEachFeatureInExtent(extent,\n /**\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @return {T|undefined} The return value from the last call to the callback.\n */\n function (feature) {\n var geometry = feature.getGeometry();\n\n if (geometry.intersectsExtent(extent)) {\n var result = callback(feature);\n\n if (result) {\n return result;\n }\n }\n });\n };\n /**\n * Get the features collection associated with this source. Will be `null`\n * unless the source was configured with `useSpatialIndex` set to `false`, or\n * with an {@link module:ol/Collection} as `features`.\n * @return {Collection<import("../Feature.js").default<Geometry>>} The collection of features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesCollection = function () {\n return this.featuresCollection_;\n };\n /**\n * Get all features on the source in random order.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeatures = function () {\n var features;\n\n if (this.featuresCollection_) {\n features = this.featuresCollection_.getArray();\n } else if (this.featuresRtree_) {\n features = this.featuresRtree_.getAll();\n\n if (!obj_isEmpty(this.nullGeometryFeatures_)) {\n array_extend(features, getValues(this.nullGeometryFeatures_));\n }\n }\n\n return (\n /** @type {Array<import("../Feature.js").default<Geometry>>} */\n features\n );\n };\n /**\n * Get all features whose geometry intersects the provided coordinate.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesAtCoordinate = function (coordinate) {\n var features = [];\n this.forEachFeatureAtCoordinateDirect(coordinate, function (feature) {\n features.push(feature);\n });\n return features;\n };\n /**\n * Get all features whose bounding box intersects the provided extent. Note that this returns an array of\n * all features intersecting the given extent in random order (so it may include\n * features whose geometries do not intersect the extent).\n *\n * When `useSpatialIndex` is set to false, this method will return all\n * features.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<import("../Feature.js").default<Geometry>>} Features.\n * @api\n */\n\n\n VectorSource.prototype.getFeaturesInExtent = function (extent) {\n if (this.featuresRtree_) {\n return this.featuresRtree_.getInExtent(extent);\n } else if (this.featuresCollection_) {\n return this.featuresCollection_.getArray();\n } else {\n return [];\n }\n };\n /**\n * Get the closest feature to the provided coordinate.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {function(import("../Feature.js").default<Geometry>):boolean=} opt_filter Feature filter function.\n * The filter function will receive one argument, the {@link module:ol/Feature feature}\n * and it should return a boolean value. By default, no filtering is made.\n * @return {import("../Feature.js").default<Geometry>} Closest feature.\n * @api\n */\n\n\n VectorSource.prototype.getClosestFeatureToCoordinate = function (coordinate, opt_filter) {\n // Find the closest feature using branch and bound. We start searching an\n // infinite extent, and find the distance from the first feature found. This\n // becomes the closest feature. We then compute a smaller extent which any\n // closer feature must intersect. We continue searching with this smaller\n // extent, trying to find a closer feature. Every time we find a closer\n // feature, we update the extent being searched so that any even closer\n // feature must intersect it. We continue until we run out of features.\n var x = coordinate[0];\n var y = coordinate[1];\n var closestFeature = null;\n var closestPoint = [NaN, NaN];\n var minSquaredDistance = Infinity;\n var extent = [-Infinity, -Infinity, Infinity, Infinity];\n var filter = opt_filter ? opt_filter : TRUE;\n this.featuresRtree_.forEachInExtent(extent,\n /**\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n */\n function (feature) {\n if (filter(feature)) {\n var geometry = feature.getGeometry();\n var previousMinSquaredDistance = minSquaredDistance;\n minSquaredDistance = geometry.closestPointXY(x, y, closestPoint, minSquaredDistance);\n\n if (minSquaredDistance < previousMinSquaredDistance) {\n closestFeature = feature; // This is sneaky. Reduce the extent that it is currently being\n // searched while the R-Tree traversal using this same extent object\n // is still in progress. This is safe because the new extent is\n // strictly contained by the old extent.\n\n var minDistance = Math.sqrt(minSquaredDistance);\n extent[0] = x - minDistance;\n extent[1] = y - minDistance;\n extent[2] = x + minDistance;\n extent[3] = y + minDistance;\n }\n }\n });\n return closestFeature;\n };\n /**\n * Get the extent of the features currently in the source.\n *\n * This method is not available when the source is configured with\n * `useSpatialIndex` set to `false`.\n * @param {import("../extent.js").Extent=} opt_extent Destination extent. If provided, no new extent\n * will be created. Instead, that extent\'s coordinates will be overwritten.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n VectorSource.prototype.getExtent = function (opt_extent) {\n return this.featuresRtree_.getExtent(opt_extent);\n };\n /**\n * Get a feature by its identifier (the value returned by feature.getId()).\n * Note that the index treats string and numeric identifiers as the same. So\n * `source.getFeatureById(2)` will return a feature with id `\'2\'` or `2`.\n *\n * @param {string|number} id Feature identifier.\n * @return {import("../Feature.js").default<Geometry>} The feature (or `null` if not found).\n * @api\n */\n\n\n VectorSource.prototype.getFeatureById = function (id) {\n var feature = this.idIndex_[id.toString()];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get a feature by its internal unique identifier (using `getUid`).\n *\n * @param {string} uid Feature identifier.\n * @return {import("../Feature.js").default<Geometry>} The feature (or `null` if not found).\n */\n\n\n VectorSource.prototype.getFeatureByUid = function (uid) {\n var feature = this.uidIndex_[uid];\n return feature !== undefined ? feature : null;\n };\n /**\n * Get the format associated with this source.\n *\n * @return {import("../format/Feature.js").default|undefined} The feature format.\n * @api\n */\n\n\n VectorSource.prototype.getFormat = function () {\n return this.format_;\n };\n /**\n * @return {boolean} The source can have overlapping geometries.\n */\n\n\n VectorSource.prototype.getOverlaps = function () {\n return this.overlaps_;\n };\n /**\n * Get the url associated with this source.\n *\n * @return {string|import("../featureloader.js").FeatureUrlFunction|undefined} The url.\n * @api\n */\n\n\n VectorSource.prototype.getUrl = function () {\n return this.url_;\n };\n /**\n * @param {Event} event Event.\n * @private\n */\n\n\n VectorSource.prototype.handleFeatureChange_ = function (event) {\n var feature =\n /** @type {import("../Feature.js").default<Geometry>} */\n event.target;\n var featureKey = getUid(feature);\n var geometry = feature.getGeometry();\n\n if (!geometry) {\n if (!(featureKey in this.nullGeometryFeatures_)) {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n\n this.nullGeometryFeatures_[featureKey] = feature;\n }\n } else {\n var extent = geometry.getExtent();\n\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n\n if (this.featuresRtree_) {\n this.featuresRtree_.insert(extent, feature);\n }\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.update(extent, feature);\n }\n }\n }\n\n var id = feature.getId();\n\n if (id !== undefined) {\n var sid = id.toString();\n\n if (this.idIndex_[sid] !== feature) {\n this.removeFromIdIndex_(feature);\n this.idIndex_[sid] = feature;\n }\n } else {\n this.removeFromIdIndex_(feature);\n this.uidIndex_[featureKey] = feature;\n }\n\n this.changed();\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.CHANGEFEATURE, feature));\n };\n /**\n * Returns true if the feature is contained within the source.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @return {boolean} Has feature.\n * @api\n */\n\n\n VectorSource.prototype.hasFeature = function (feature) {\n var id = feature.getId();\n\n if (id !== undefined) {\n return id in this.idIndex_;\n } else {\n return getUid(feature) in this.uidIndex_;\n }\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n VectorSource.prototype.isEmpty = function () {\n return this.featuresRtree_.isEmpty() && obj_isEmpty(this.nullGeometryFeatures_);\n };\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n VectorSource.prototype.loadFeatures = function (extent, resolution, projection) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var extentsToLoad = this.strategy_(extent, resolution);\n this.loading = false;\n\n var _loop_1 = function _loop_1(i, ii) {\n var extentToLoad = extentsToLoad[i];\n var alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,\n /**\n * @param {{extent: import("../extent.js").Extent}} object Object.\n * @return {boolean} Contains.\n */\n function (object) {\n return containsExtent(object.extent, extentToLoad);\n });\n\n if (!alreadyLoaded) {\n this_1.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADSTART));\n this_1.loader_.call(this_1, extentToLoad, resolution, projection, function (features) {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADEND, undefined, features));\n }.bind(this_1), function () {\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.FEATURESLOADERROR));\n }.bind(this_1));\n loadedExtentsRtree.insert(extentToLoad, {\n extent: extentToLoad.slice()\n });\n this_1.loading = this_1.loader_ !== VOID;\n }\n };\n\n var this_1 = this;\n\n for (var i = 0, ii = extentsToLoad.length; i < ii; ++i) {\n _loop_1(i, ii);\n }\n };\n\n VectorSource.prototype.refresh = function () {\n this.clear(true);\n this.loadedExtentsRtree_.clear();\n\n _super.prototype.refresh.call(this);\n };\n /**\n * Remove an extent from the list of loaded extents.\n * @param {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n\n VectorSource.prototype.removeLoadedExtent = function (extent) {\n var loadedExtentsRtree = this.loadedExtentsRtree_;\n var obj;\n loadedExtentsRtree.forEachInExtent(extent, function (object) {\n if (extent_equals(object.extent, extent)) {\n obj = object;\n return true;\n }\n });\n\n if (obj) {\n loadedExtentsRtree.remove(obj);\n }\n };\n /**\n * Remove a single feature from the source. If you want to remove all features\n * at once, use the {@link module:ol/source/Vector~VectorSource#clear #clear()} method\n * instead.\n * @param {import("../Feature.js").default<Geometry>} feature Feature to remove.\n * @api\n */\n\n\n VectorSource.prototype.removeFeature = function (feature) {\n var featureKey = getUid(feature);\n\n if (featureKey in this.nullGeometryFeatures_) {\n delete this.nullGeometryFeatures_[featureKey];\n } else {\n if (this.featuresRtree_) {\n this.featuresRtree_.remove(feature);\n }\n }\n\n this.removeFeatureInternal(feature);\n this.changed();\n };\n /**\n * Remove feature without firing a `change` event.\n * @param {import("../Feature.js").default<Geometry>} feature Feature.\n * @protected\n */\n\n\n VectorSource.prototype.removeFeatureInternal = function (feature) {\n var featureKey = getUid(feature);\n this.featureChangeKeys_[featureKey].forEach(unlistenByKey);\n delete this.featureChangeKeys_[featureKey];\n var id = feature.getId();\n\n if (id !== undefined) {\n delete this.idIndex_[id.toString()];\n }\n\n delete this.uidIndex_[featureKey];\n this.dispatchEvent(new VectorSourceEvent(VectorEventType.REMOVEFEATURE, feature));\n };\n /**\n * Remove a feature from the id index. Called internally when the feature id\n * may have changed.\n * @param {import("../Feature.js").default<Geometry>} feature The feature.\n * @return {boolean} Removed the feature from the index.\n * @private\n */\n\n\n VectorSource.prototype.removeFromIdIndex_ = function (feature) {\n var removed = false;\n\n for (var id in this.idIndex_) {\n if (this.idIndex_[id] === feature) {\n delete this.idIndex_[id];\n removed = true;\n break;\n }\n }\n\n return removed;\n };\n /**\n * Set the new loader of the source. The next render cycle will use the\n * new loader.\n * @param {import("../featureloader.js").FeatureLoader} loader The loader to set.\n * @api\n */\n\n\n VectorSource.prototype.setLoader = function (loader) {\n this.loader_ = loader;\n };\n /**\n * Points the source to a new url. The next render cycle will use the new url.\n * @param {string|import("../featureloader.js").FeatureUrlFunction} url Url.\n * @api\n */\n\n\n VectorSource.prototype.setUrl = function (url) {\n asserts_assert(this.format_, 7); // `format` must be set when `url` is set\n\n this.setLoader(xhr(url, this.format_));\n };\n\n return VectorSource;\n}(source_Source);\n\n/* harmony default export */ var source_Vector = (VectorSource);\n// EXTERNAL MODULE: ./node_modules/mapbox-to-css-font/index.js\nvar mapbox_to_css_font = __webpack_require__(5978);\nvar mapbox_to_css_font_default = /*#__PURE__*/__webpack_require__.n(mapbox_to_css_font);\n;// CONCATENATED MODULE: ./node_modules/ol/style/Text.js\n/**\n * @module ol/style/Text\n */\n\n\n\n/**\n * The default fill color to use if no fill was set at construction time; a\n * blackish `#333`.\n *\n * @const {string}\n */\n\nvar DEFAULT_FILL_COLOR = \'#333\';\n/**\n * @typedef {Object} Options\n * @property {string} [font] Font style as CSS \'font\' value, see:\n * https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font. Default is \'10px sans-serif\'\n * @property {number} [maxAngle=Math.PI/4] When `placement` is set to `\'line\'`, allow a maximum angle between adjacent characters.\n * The expected value is in radians, and the default is 45° (`Math.PI / 4`).\n * @property {number} [offsetX=0] Horizontal text offset in pixels. A positive will shift the text right.\n * @property {number} [offsetY=0] Vertical text offset in pixels. A positive will shift the text down.\n * @property {boolean} [overflow=false] For polygon labels or when `placement` is set to `\'line\'`, allow text to exceed\n * the width of the polygon at the label position or the length of the path that it follows.\n * @property {import("./TextPlacement.js").default|string} [placement=\'point\'] Text placement.\n * @property {number|import("../size.js").Size} [scale] Scale.\n * @property {boolean} [rotateWithView=false] Whether to rotate the text with the view.\n * @property {number} [rotation=0] Rotation in radians (positive rotation clockwise).\n * @property {string} [text] Text content.\n * @property {string} [textAlign] Text alignment. Possible values: \'left\', \'right\', \'center\', \'end\' or \'start\'.\n * Default is \'center\' for `placement: \'point\'`. For `placement: \'line\'`, the default is to let the renderer choose a\n * placement where `maxAngle` is not exceeded.\n * @property {string} [textBaseline=\'middle\'] Text base line. Possible values: \'bottom\', \'top\', \'middle\', \'alphabetic\',\n * \'hanging\', \'ideographic\'.\n * @property {import("./Fill.js").default} [fill] Fill style. If none is provided, we\'ll use a dark fill-style (#333).\n * @property {import("./Stroke.js").default} [stroke] Stroke style.\n * @property {import("./Fill.js").default} [backgroundFill] Fill style for the text background when `placement` is\n * `\'point\'`. Default is no fill.\n * @property {import("./Stroke.js").default} [backgroundStroke] Stroke style for the text background when `placement`\n * is `\'point\'`. Default is no stroke.\n * @property {Array<number>} [padding=[0, 0, 0, 0]] Padding in pixels around the text for decluttering and background. The order of\n * values in the array is `[top, right, bottom, left]`.\n */\n\n/**\n * @classdesc\n * Set text style for vector features.\n * @api\n */\n\nvar Text =\n/** @class */\nfunction () {\n /**\n * @param {Options=} opt_options Options.\n */\n function Text(opt_options) {\n var options = opt_options || {};\n /**\n * @private\n * @type {string|undefined}\n */\n\n this.font_ = options.font;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.rotation_ = options.rotation;\n /**\n * @private\n * @type {boolean|undefined}\n */\n\n this.rotateWithView_ = options.rotateWithView;\n /**\n * @private\n * @type {number|import("../size.js").Size|undefined}\n */\n\n this.scale_ = options.scale;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n this.scaleArray_ = toSize(options.scale !== undefined ? options.scale : 1);\n /**\n * @private\n * @type {string|undefined}\n */\n\n this.text_ = options.text;\n /**\n * @private\n * @type {string|undefined}\n */\n\n this.textAlign_ = options.textAlign;\n /**\n * @private\n * @type {string|undefined}\n */\n\n this.textBaseline_ = options.textBaseline;\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n this.fill_ = options.fill !== undefined ? options.fill : new style_Fill({\n color: DEFAULT_FILL_COLOR\n });\n /**\n * @private\n * @type {number}\n */\n\n this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;\n /**\n * @private\n * @type {import("./TextPlacement.js").default|string}\n */\n\n this.placement_ = options.placement !== undefined ? options.placement : TextPlacement.POINT;\n /**\n * @private\n * @type {boolean}\n */\n\n this.overflow_ = !!options.overflow;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n this.stroke_ = options.stroke !== undefined ? options.stroke : null;\n /**\n * @private\n * @type {number}\n */\n\n this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;\n /**\n * @private\n * @type {number}\n */\n\n this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;\n /**\n * @private\n * @type {import("./Fill.js").default}\n */\n\n this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;\n /**\n * @private\n * @type {import("./Stroke.js").default}\n */\n\n this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.padding_ = options.padding === undefined ? null : options.padding;\n }\n /**\n * Clones the style.\n * @return {Text} The cloned style.\n * @api\n */\n\n\n Text.prototype.clone = function () {\n var scale = this.getScale();\n return new Text({\n font: this.getFont(),\n placement: this.getPlacement(),\n maxAngle: this.getMaxAngle(),\n overflow: this.getOverflow(),\n rotation: this.getRotation(),\n rotateWithView: this.getRotateWithView(),\n scale: Array.isArray(scale) ? scale.slice() : scale,\n text: this.getText(),\n textAlign: this.getTextAlign(),\n textBaseline: this.getTextBaseline(),\n fill: this.getFill() ? this.getFill().clone() : undefined,\n stroke: this.getStroke() ? this.getStroke().clone() : undefined,\n offsetX: this.getOffsetX(),\n offsetY: this.getOffsetY(),\n backgroundFill: this.getBackgroundFill() ? this.getBackgroundFill().clone() : undefined,\n backgroundStroke: this.getBackgroundStroke() ? this.getBackgroundStroke().clone() : undefined,\n padding: this.getPadding()\n });\n };\n /**\n * Get the `overflow` configuration.\n * @return {boolean} Let text overflow the length of the path they follow.\n * @api\n */\n\n\n Text.prototype.getOverflow = function () {\n return this.overflow_;\n };\n /**\n * Get the font name.\n * @return {string|undefined} Font.\n * @api\n */\n\n\n Text.prototype.getFont = function () {\n return this.font_;\n };\n /**\n * Get the maximum angle between adjacent characters.\n * @return {number} Angle in radians.\n * @api\n */\n\n\n Text.prototype.getMaxAngle = function () {\n return this.maxAngle_;\n };\n /**\n * Get the label placement.\n * @return {import("./TextPlacement.js").default|string} Text placement.\n * @api\n */\n\n\n Text.prototype.getPlacement = function () {\n return this.placement_;\n };\n /**\n * Get the x-offset for the text.\n * @return {number} Horizontal text offset.\n * @api\n */\n\n\n Text.prototype.getOffsetX = function () {\n return this.offsetX_;\n };\n /**\n * Get the y-offset for the text.\n * @return {number} Vertical text offset.\n * @api\n */\n\n\n Text.prototype.getOffsetY = function () {\n return this.offsetY_;\n };\n /**\n * Get the fill style for the text.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n Text.prototype.getFill = function () {\n return this.fill_;\n };\n /**\n * Determine whether the text rotates with the map.\n * @return {boolean|undefined} Rotate with map.\n * @api\n */\n\n\n Text.prototype.getRotateWithView = function () {\n return this.rotateWithView_;\n };\n /**\n * Get the text rotation.\n * @return {number|undefined} Rotation.\n * @api\n */\n\n\n Text.prototype.getRotation = function () {\n return this.rotation_;\n };\n /**\n * Get the text scale.\n * @return {number|import("../size.js").Size|undefined} Scale.\n * @api\n */\n\n\n Text.prototype.getScale = function () {\n return this.scale_;\n };\n /**\n * Get the symbolizer scale array.\n * @return {import("../size.js").Size} Scale array.\n */\n\n\n Text.prototype.getScaleArray = function () {\n return this.scaleArray_;\n };\n /**\n * Get the stroke style for the text.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n Text.prototype.getStroke = function () {\n return this.stroke_;\n };\n /**\n * Get the text to be rendered.\n * @return {string|undefined} Text.\n * @api\n */\n\n\n Text.prototype.getText = function () {\n return this.text_;\n };\n /**\n * Get the text alignment.\n * @return {string|undefined} Text align.\n * @api\n */\n\n\n Text.prototype.getTextAlign = function () {\n return this.textAlign_;\n };\n /**\n * Get the text baseline.\n * @return {string|undefined} Text baseline.\n * @api\n */\n\n\n Text.prototype.getTextBaseline = function () {\n return this.textBaseline_;\n };\n /**\n * Get the background fill style for the text.\n * @return {import("./Fill.js").default} Fill style.\n * @api\n */\n\n\n Text.prototype.getBackgroundFill = function () {\n return this.backgroundFill_;\n };\n /**\n * Get the background stroke style for the text.\n * @return {import("./Stroke.js").default} Stroke style.\n * @api\n */\n\n\n Text.prototype.getBackgroundStroke = function () {\n return this.backgroundStroke_;\n };\n /**\n * Get the padding for the text.\n * @return {Array<number>} Padding.\n * @api\n */\n\n\n Text.prototype.getPadding = function () {\n return this.padding_;\n };\n /**\n * Set the `overflow` property.\n *\n * @param {boolean} overflow Let text overflow the path that it follows.\n * @api\n */\n\n\n Text.prototype.setOverflow = function (overflow) {\n this.overflow_ = overflow;\n };\n /**\n * Set the font.\n *\n * @param {string|undefined} font Font.\n * @api\n */\n\n\n Text.prototype.setFont = function (font) {\n this.font_ = font;\n };\n /**\n * Set the maximum angle between adjacent characters.\n *\n * @param {number} maxAngle Angle in radians.\n * @api\n */\n\n\n Text.prototype.setMaxAngle = function (maxAngle) {\n this.maxAngle_ = maxAngle;\n };\n /**\n * Set the x offset.\n *\n * @param {number} offsetX Horizontal text offset.\n * @api\n */\n\n\n Text.prototype.setOffsetX = function (offsetX) {\n this.offsetX_ = offsetX;\n };\n /**\n * Set the y offset.\n *\n * @param {number} offsetY Vertical text offset.\n * @api\n */\n\n\n Text.prototype.setOffsetY = function (offsetY) {\n this.offsetY_ = offsetY;\n };\n /**\n * Set the text placement.\n *\n * @param {import("./TextPlacement.js").default|string} placement Placement.\n * @api\n */\n\n\n Text.prototype.setPlacement = function (placement) {\n this.placement_ = placement;\n };\n /**\n * Set whether to rotate the text with the view.\n *\n * @param {boolean} rotateWithView Rotate with map.\n * @api\n */\n\n\n Text.prototype.setRotateWithView = function (rotateWithView) {\n this.rotateWithView_ = rotateWithView;\n };\n /**\n * Set the fill.\n *\n * @param {import("./Fill.js").default} fill Fill style.\n * @api\n */\n\n\n Text.prototype.setFill = function (fill) {\n this.fill_ = fill;\n };\n /**\n * Set the rotation.\n *\n * @param {number|undefined} rotation Rotation.\n * @api\n */\n\n\n Text.prototype.setRotation = function (rotation) {\n this.rotation_ = rotation;\n };\n /**\n * Set the scale.\n *\n * @param {number|import("../size.js").Size|undefined} scale Scale.\n * @api\n */\n\n\n Text.prototype.setScale = function (scale) {\n this.scale_ = scale;\n this.scaleArray_ = toSize(scale !== undefined ? scale : 1);\n };\n /**\n * Set the stroke.\n *\n * @param {import("./Stroke.js").default} stroke Stroke style.\n * @api\n */\n\n\n Text.prototype.setStroke = function (stroke) {\n this.stroke_ = stroke;\n };\n /**\n * Set the text.\n *\n * @param {string|undefined} text Text.\n * @api\n */\n\n\n Text.prototype.setText = function (text) {\n this.text_ = text;\n };\n /**\n * Set the text alignment.\n *\n * @param {string|undefined} textAlign Text align.\n * @api\n */\n\n\n Text.prototype.setTextAlign = function (textAlign) {\n this.textAlign_ = textAlign;\n };\n /**\n * Set the text baseline.\n *\n * @param {string|undefined} textBaseline Text baseline.\n * @api\n */\n\n\n Text.prototype.setTextBaseline = function (textBaseline) {\n this.textBaseline_ = textBaseline;\n };\n /**\n * Set the background fill.\n *\n * @param {import("./Fill.js").default} fill Fill style.\n * @api\n */\n\n\n Text.prototype.setBackgroundFill = function (fill) {\n this.backgroundFill_ = fill;\n };\n /**\n * Set the background stroke.\n *\n * @param {import("./Stroke.js").default} stroke Stroke style.\n * @api\n */\n\n\n Text.prototype.setBackgroundStroke = function (stroke) {\n this.backgroundStroke_ = stroke;\n };\n /**\n * Set the padding (`[top, right, bottom, left]`).\n *\n * @param {!Array<number>} padding Padding.\n * @api\n */\n\n\n Text.prototype.setPadding = function (padding) {\n this.padding_ = padding;\n };\n\n return Text;\n}();\n\n/* harmony default export */ var style_Text = (Text);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/interpolate.js\n/**\n * @module ol/geom/flat/interpolate\n */\n\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} fraction Fraction.\n * @param {Array<number>=} opt_dest Destination.\n * @param {number=} opt_dimension Destination dimension (default is `2`)\n * @return {Array<number>} Destination.\n */\n\nfunction interpolatePoint(flatCoordinates, offset, end, stride, fraction, opt_dest, opt_dimension) {\n var o, t;\n var n = (end - offset) / stride;\n\n if (n === 1) {\n o = offset;\n } else if (n === 2) {\n o = offset;\n t = fraction;\n } else if (n !== 0) {\n var x1 = flatCoordinates[offset];\n var y1 = flatCoordinates[offset + 1];\n var length_1 = 0;\n var cumulativeLengths = [0];\n\n for (var i = offset + stride; i < end; i += stride) {\n var x2 = flatCoordinates[i];\n var y2 = flatCoordinates[i + 1];\n length_1 += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n cumulativeLengths.push(length_1);\n x1 = x2;\n y1 = y2;\n }\n\n var target = fraction * length_1;\n var index = binarySearch(cumulativeLengths, target);\n\n if (index < 0) {\n t = (target - cumulativeLengths[-index - 2]) / (cumulativeLengths[-index - 1] - cumulativeLengths[-index - 2]);\n o = offset + (-index - 2) * stride;\n } else {\n o = offset + index * stride;\n }\n }\n\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var dest = opt_dest ? opt_dest : new Array(dimension);\n\n for (var i = 0; i < dimension; ++i) {\n dest[i] = o === undefined ? NaN : t === undefined ? flatCoordinates[o + i] : lerp(flatCoordinates[o + i], flatCoordinates[o + stride + i], t);\n }\n\n return dest;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @return {import("../../coordinate.js").Coordinate} Coordinate.\n */\n\nfunction lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, extrapolate) {\n if (end == offset) {\n return null;\n }\n\n var coordinate;\n\n if (m < flatCoordinates[offset + stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(offset, offset + stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n } else if (flatCoordinates[end - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(end - stride, end);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n } // FIXME use O(1) search\n\n\n if (m == flatCoordinates[offset + stride - 1]) {\n return flatCoordinates.slice(offset, offset + stride);\n }\n\n var lo = offset / stride;\n var hi = end / stride;\n\n while (lo < hi) {\n var mid = lo + hi >> 1;\n\n if (m < flatCoordinates[(mid + 1) * stride - 1]) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n\n var m0 = flatCoordinates[lo * stride - 1];\n\n if (m == m0) {\n return flatCoordinates.slice((lo - 1) * stride, (lo - 1) * stride + stride);\n }\n\n var m1 = flatCoordinates[(lo + 1) * stride - 1];\n var t = (m - m0) / (m1 - m0);\n coordinate = [];\n\n for (var i = 0; i < stride - 1; ++i) {\n coordinate.push(lerp(flatCoordinates[(lo - 1) * stride + i], flatCoordinates[lo * stride + i], t));\n }\n\n coordinate.push(m);\n return coordinate;\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<number>} ends Ends.\n * @param {number} stride Stride.\n * @param {number} m M.\n * @param {boolean} extrapolate Extrapolate.\n * @param {boolean} interpolate Interpolate.\n * @return {import("../../coordinate.js").Coordinate} Coordinate.\n */\n\nfunction lineStringsCoordinateAtM(flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {\n if (interpolate) {\n return lineStringCoordinateAtM(flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);\n }\n\n var coordinate;\n\n if (m < flatCoordinates[stride - 1]) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(0, stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n }\n\n if (flatCoordinates[flatCoordinates.length - 1] < m) {\n if (extrapolate) {\n coordinate = flatCoordinates.slice(flatCoordinates.length - stride);\n coordinate[stride - 1] = m;\n return coordinate;\n } else {\n return null;\n }\n }\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n\n if (offset == end) {\n continue;\n }\n\n if (m < flatCoordinates[offset + stride - 1]) {\n return null;\n } else if (m <= flatCoordinates[end - 1]) {\n return lineStringCoordinateAtM(flatCoordinates, offset, end, stride, m, false);\n }\n\n offset = end;\n }\n\n return null;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/geom/flat/center.js\n/**\n * @module ol/geom/flat/center\n */\n\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {Array<Array<number>>} endss Endss.\n * @param {number} stride Stride.\n * @return {Array<number>} Flat centers.\n */\n\nfunction center_linearRingss(flatCoordinates, offset, endss, stride) {\n var flatCenters = [];\n var extent = createEmpty();\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i];\n extent = createOrUpdateFromFlatCoordinates(flatCoordinates, offset, ends[0], stride);\n flatCenters.push((extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2);\n offset = ends[ends.length - 1];\n }\n\n return flatCenters;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/render/Feature.js\n/**\n * @module ol/render/Feature\n */\n\n\n\n\n\n\n\n\n\n/**\n * @type {import("../transform.js").Transform}\n */\n\nvar Feature_tmpTransform = create();\n/**\n * Lightweight, read-only, {@link module:ol/Feature~Feature} and {@link module:ol/geom/Geometry~Geometry} like\n * structure, optimized for vector tile rendering and styling. Geometry access\n * through the API is limited to getting the type and extent of the geometry.\n */\n\nvar RenderFeature =\n/** @class */\nfunction () {\n /**\n * @param {import("../geom/GeometryType.js").default} type Geometry type.\n * @param {Array<number>} flatCoordinates Flat coordinates. These always need\n * to be right-handed for polygons.\n * @param {Array<number>|Array<Array<number>>} ends Ends or Endss.\n * @param {Object<string, *>} properties Properties.\n * @param {number|string|undefined} id Feature id.\n */\n function RenderFeature(type, flatCoordinates, ends, properties, id) {\n /**\n * @private\n * @type {import("../extent.js").Extent|undefined}\n */\n this.extent_;\n /**\n * @private\n * @type {number|string|undefined}\n */\n\n this.id_ = id;\n /**\n * @private\n * @type {import("../geom/GeometryType.js").default}\n */\n\n this.type_ = type;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatCoordinates_ = flatCoordinates;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatInteriorPoints_ = null;\n /**\n * @private\n * @type {Array<number>}\n */\n\n this.flatMidpoints_ = null;\n /**\n * @private\n * @type {Array<number>|Array<Array<number>>}\n */\n\n this.ends_ = ends;\n /**\n * @private\n * @type {Object<string, *>}\n */\n\n this.properties_ = properties;\n }\n /**\n * Get a feature property by its key.\n * @param {string} key Key\n * @return {*} Value for the requested key.\n * @api\n */\n\n\n RenderFeature.prototype.get = function (key) {\n return this.properties_[key];\n };\n /**\n * Get the extent of this feature\'s geometry.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n RenderFeature.prototype.getExtent = function () {\n if (!this.extent_) {\n this.extent_ = this.type_ === geom_GeometryType.POINT ? createOrUpdateFromCoordinate(this.flatCoordinates_) : createOrUpdateFromFlatCoordinates(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2);\n }\n\n return this.extent_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n RenderFeature.prototype.getFlatInteriorPoint = function () {\n if (!this.flatInteriorPoints_) {\n var flatCenter = getCenter(this.getExtent());\n this.flatInteriorPoints_ = getInteriorPointOfArray(this.flatCoordinates_, 0,\n /** @type {Array<number>} */\n this.ends_, 2, flatCenter, 0);\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n RenderFeature.prototype.getFlatInteriorPoints = function () {\n if (!this.flatInteriorPoints_) {\n var flatCenters = center_linearRingss(this.flatCoordinates_, 0,\n /** @type {Array<Array<number>>} */\n this.ends_, 2);\n this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(this.flatCoordinates_, 0,\n /** @type {Array<Array<number>>} */\n this.ends_, 2, flatCenters);\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * @return {Array<number>} Flat midpoint.\n */\n\n\n RenderFeature.prototype.getFlatMidpoint = function () {\n if (!this.flatMidpoints_) {\n this.flatMidpoints_ = interpolatePoint(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, 0.5);\n }\n\n return this.flatMidpoints_;\n };\n /**\n * @return {Array<number>} Flat midpoints.\n */\n\n\n RenderFeature.prototype.getFlatMidpoints = function () {\n if (!this.flatMidpoints_) {\n this.flatMidpoints_ = [];\n var flatCoordinates = this.flatCoordinates_;\n var offset = 0;\n var ends =\n /** @type {Array<number>} */\n this.ends_;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var midpoint = interpolatePoint(flatCoordinates, offset, end, 2, 0.5);\n array_extend(this.flatMidpoints_, midpoint);\n offset = end;\n }\n }\n\n return this.flatMidpoints_;\n };\n /**\n * Get the feature identifier. This is a stable identifier for the feature and\n * is set when reading data from a remote source.\n * @return {number|string|undefined} Id.\n * @api\n */\n\n\n RenderFeature.prototype.getId = function () {\n return this.id_;\n };\n /**\n * @return {Array<number>} Flat coordinates.\n */\n\n\n RenderFeature.prototype.getOrientedFlatCoordinates = function () {\n return this.flatCoordinates_;\n };\n /**\n * For API compatibility with {@link module:ol/Feature~Feature}, this method is useful when\n * determining the geometry type in style function (see {@link #getType}).\n * @return {RenderFeature} Feature.\n * @api\n */\n\n\n RenderFeature.prototype.getGeometry = function () {\n return this;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {RenderFeature} Simplified geometry.\n */\n\n\n RenderFeature.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n return this;\n };\n /**\n * Get a transformed and simplified version of the geometry.\n * @abstract\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../proj.js").TransformFunction} [opt_transform] Optional transform function.\n * @return {RenderFeature} Simplified geometry.\n */\n\n\n RenderFeature.prototype.simplifyTransformed = function (squaredTolerance, opt_transform) {\n return this;\n };\n /**\n * Get the feature properties.\n * @return {Object<string, *>} Feature properties.\n * @api\n */\n\n\n RenderFeature.prototype.getProperties = function () {\n return this.properties_;\n };\n /**\n * @return {number} Stride.\n */\n\n\n RenderFeature.prototype.getStride = function () {\n return 2;\n };\n /**\n * @return {undefined}\n */\n\n\n RenderFeature.prototype.getStyleFunction = function () {\n return undefined;\n };\n /**\n * Get the type of this feature\'s geometry.\n * @return {import("../geom/GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n RenderFeature.prototype.getType = function () {\n return this.type_;\n };\n /**\n * Transform geometry coordinates from tile pixel space to projected.\n *\n * @param {import("../proj.js").ProjectionLike} projection The data projection\n */\n\n\n RenderFeature.prototype.transform = function (projection) {\n projection = proj_get(projection);\n var pixelExtent = projection.getExtent();\n var projectedExtent = projection.getWorldExtent();\n\n if (pixelExtent && projectedExtent) {\n var scale = getHeight(projectedExtent) / getHeight(pixelExtent);\n compose(Feature_tmpTransform, projectedExtent[0], projectedExtent[3], scale, -scale, 0, 0, 0);\n transform2D(this.flatCoordinates_, 0, this.flatCoordinates_.length, 2, Feature_tmpTransform, this.flatCoordinates_);\n }\n };\n /**\n * @return {Array<number>|Array<Array<number>>} Ends or endss.\n */\n\n\n RenderFeature.prototype.getEnds = function () {\n return this.ends_;\n };\n\n return RenderFeature;\n}();\n\nRenderFeature.prototype.getEndss = RenderFeature.prototype.getEnds;\n/**\n * @return {Array<number>} Flat coordinates.\n */\n\nRenderFeature.prototype.getFlatCoordinates = RenderFeature.prototype.getOrientedFlatCoordinates;\n/* harmony default export */ var Feature = (RenderFeature);\n// EXTERNAL MODULE: ./node_modules/@mapbox/mapbox-gl-style-spec/dist/index.es.js\nvar index_es = __webpack_require__(3022);\n;// CONCATENATED MODULE: ./node_modules/ol-mapbox-style/dist/util.js\n\n\n\n/**\n * Polyfill for Object.assign(). Assigns enumerable and own properties from\n * one or more source objects to a target object.\n * See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign.\n *\n * @param {!Object} target The target object.\n * @param {...Object} var_sources The source object(s).\n * @return {!Object} The modified target object.\n */\n\nvar util_assign = typeof Object.assign === \'function\' ? Object.assign : function (target, var_sources) {\n if (target === undefined || target === null) {\n throw new TypeError(\'Cannot convert undefined or null to object\');\n }\n\n var output = Object(target);\n\n for (var i = 1, ii = arguments.length; i < ii; ++i) {\n var source = arguments[i];\n\n if (source !== undefined && source !== null) {\n for (var key in source) {\n if (source.hasOwnProperty(key)) {\n output[key] = source[key];\n }\n }\n }\n }\n\n return output;\n};\nfunction deg2rad(degrees) {\n return degrees * Math.PI / 180;\n}\nvar defaultResolutions = function () {\n var resolutions = [];\n\n for (var res = 78271.51696402048; resolutions.length <= 24; res /= 2) {\n resolutions.push(res);\n }\n\n return resolutions;\n}();\n/**\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @return {HTMLCanvasElement} Canvas.\n */\n\nfunction createCanvas(width, height) {\n if (typeof WorkerGlobalScope !== \'undefined\' && self instanceof WorkerGlobalScope && typeof OffscreenCanvas !== \'undefined\') {\n // eslint-disable-line\n return (\n /** @type {?} */\n new OffscreenCanvas(width, height)\n );\n } else {\n var canvas = document.createElement(\'canvas\');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n}\nfunction getZoomForResolution(resolution, resolutions) {\n var i = 0;\n var ii = resolutions.length;\n\n for (; i < ii; ++i) {\n var candidate = resolutions[i];\n\n if (candidate < resolution && i + 1 < ii) {\n var zoomFactor = resolutions[i] / resolutions[i + 1];\n return i + Math.log(resolutions[i] / resolution) / Math.log(zoomFactor);\n }\n }\n\n return ii - 1;\n}\nvar hairSpacePool = Array(256).join("\\u200A");\nfunction applyLetterSpacing(text, letterSpacing) {\n if (letterSpacing >= 0.05) {\n var textWithLetterSpacing = \'\';\n var lines = text.split(\'\\n\');\n var joinSpaceString = hairSpacePool.slice(0, Math.round(letterSpacing / 0.1));\n\n for (var l = 0, ll = lines.length; l < ll; ++l) {\n if (l > 0) {\n textWithLetterSpacing += \'\\n\';\n }\n\n textWithLetterSpacing += lines[l].split(\'\').join(joinSpaceString);\n }\n\n return textWithLetterSpacing;\n }\n\n return text;\n}\nvar util_measureContext;\n\nfunction getMeasureContext() {\n if (!util_measureContext) {\n util_measureContext = createCanvas(1, 1).getContext(\'2d\');\n }\n\n return util_measureContext;\n}\n\nfunction util_measureText(text, letterSpacing) {\n return getMeasureContext().measureText(text).width + (text.length - 1) * letterSpacing;\n}\n\nvar measureCache = {};\n\nif (labelCache) {\n // Only available when using ES modules\n listen(labelCache, EventType.CLEAR, function () {\n measureCache = {};\n });\n}\n\nfunction wrapText(text, font, em, letterSpacing) {\n if (text.indexOf(\'\\n\') !== -1) {\n var hardLines = text.split(\'\\n\');\n var lines = [];\n\n for (var i = 0, ii = hardLines.length; i < ii; ++i) {\n lines.push(wrapText(hardLines[i], font, em, letterSpacing));\n }\n\n return lines.join(\'\\n\');\n }\n\n var key = em + \',\' + font + \',\' + text + \',\' + letterSpacing;\n var wrappedText = measureCache[key];\n\n if (!wrappedText) {\n var words = text.split(\' \');\n\n if (words.length > 1) {\n var ctx = getMeasureContext();\n ctx.font = font;\n var oneEm = ctx.measureText(\'M\').width;\n var maxWidth = oneEm * em;\n var line = \'\';\n var lines = []; // Pass 1 - wrap lines to not exceed maxWidth\n\n for (var i = 0, ii = words.length; i < ii; ++i) {\n var word = words[i];\n var testLine = line + (line ? \' \' : \'\') + word;\n\n if (util_measureText(testLine, letterSpacing) <= maxWidth) {\n line = testLine;\n } else {\n if (line) {\n lines.push(line);\n }\n\n line = word;\n }\n }\n\n if (line) {\n lines.push(line);\n } // Pass 2 - add lines with a width of less than 30% of maxWidth to the previous or next line\n\n\n for (var i = 0, ii = lines.length; i < ii && ii > 1; ++i) {\n var line_1 = lines[i];\n\n if (util_measureText(line_1, letterSpacing) < maxWidth * 0.35) {\n var prevWidth = i > 0 ? util_measureText(lines[i - 1], letterSpacing) : Infinity;\n var nextWidth = i < ii - 1 ? util_measureText(lines[i + 1], letterSpacing) : Infinity;\n lines.splice(i, 1);\n ii -= 1;\n\n if (prevWidth < nextWidth) {\n lines[i - 1] += \' \' + line_1;\n i -= 1;\n } else {\n lines[i] = line_1 + \' \' + lines[i];\n }\n }\n } // Pass 3 - try to fill 80% of maxWidth for each line\n\n\n for (var i = 0, ii = lines.length - 1; i < ii; ++i) {\n var line_2 = lines[i];\n var next = lines[i + 1];\n\n if (util_measureText(line_2, letterSpacing) > maxWidth * 0.7 && util_measureText(next, letterSpacing) < maxWidth * 0.6) {\n var lineWords = line_2.split(\' \');\n var lastWord = lineWords.pop();\n\n if (util_measureText(lastWord, letterSpacing) < maxWidth * 0.2) {\n lines[i] = lineWords.join(\' \');\n lines[i + 1] = lastWord + \' \' + next;\n }\n\n ii -= 1;\n }\n }\n\n wrappedText = lines.join(\'\\n\');\n } else {\n wrappedText = text;\n }\n\n wrappedText = applyLetterSpacing(wrappedText, letterSpacing);\n measureCache[key] = wrappedText;\n }\n\n return wrappedText;\n}\n;// CONCATENATED MODULE: ./node_modules/ol-mapbox-style/dist/stylefunction.js\n/*\nol-mapbox-style - Use Mapbox Style objects with OpenLayers\nCopyright 2016-present ol-mapbox-style contributors\nLicense: https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE\n*/\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {import("ol/layer/Vector").default} VectorLayer\n * @typedef {import("ol/layer/VectorTile").default} VectorTileLayer\n * @typedef {import("ol/style/Style").StyleFunction} StyleFunction\n */\n\nvar isFunction = index_es/* function.isFunction */.ZI.isFunction;\nvar convertFunction = index_es/* function.convertFunction */.ZI.convertFunction;\nvar isExpression = index_es/* expression.isExpression */.th.isExpression;\nvar createPropertyExpression = index_es/* expression.createPropertyExpression */.th.createPropertyExpression;\nvar types = {\n \'Point\': 1,\n \'MultiPoint\': 1,\n \'LineString\': 2,\n \'MultiLineString\': 2,\n \'Polygon\': 3,\n \'MultiPolygon\': 3\n};\nvar stylefunction_anchor = {\n \'center\': [0.5, 0.5],\n \'left\': [0, 0.5],\n \'right\': [1, 0.5],\n \'top\': [0.5, 0],\n \'bottom\': [0.5, 1],\n \'top-left\': [0, 0],\n \'top-right\': [1, 0],\n \'bottom-left\': [0, 1],\n \'bottom-right\': [1, 1]\n};\n\nvar expressionData = function expressionData(rawExpression, propertySpec) {\n var compiledExpression = createPropertyExpression(rawExpression, propertySpec);\n\n if (compiledExpression.result === \'error\') {\n throw new Error(compiledExpression.value.map(function (err) {\n return err.key + ": " + err.message;\n }).join(\', \'));\n }\n\n return compiledExpression.value;\n};\n\nvar emptyObj = {};\nvar zoomObj = {\n zoom: 0\n};\n/** @private */\n\nvar functionCache = {};\nvar renderFeatureCoordinates, stylefunction_renderFeature;\n/**\n * @private\n * @param {Object} layer Gl object layer.\n * @param {string} layoutOrPaint \'layout\' or \'paint\'.\n * @param {string} property Feature property.\n * @param {number} zoom Zoom.\n * @param {Object} feature Gl feature.\n * @return {?} Value.\n */\n\nfunction getValue(layer, layoutOrPaint, property, zoom, feature) {\n var layerId = layer.id;\n\n if (!functionCache[layerId]) {\n functionCache[layerId] = {};\n }\n\n var functions = functionCache[layerId];\n\n if (!functions[property]) {\n var value_1 = (layer[layoutOrPaint] || emptyObj)[property];\n var propertySpec = index_es/* latest */.pA[layoutOrPaint + "_" + layer.type][property];\n\n if (value_1 === undefined) {\n value_1 = propertySpec.default;\n }\n\n var isExpr = isExpression(value_1);\n\n if (!isExpr && isFunction(value_1)) {\n value_1 = convertFunction(value_1, propertySpec);\n isExpr = true;\n }\n\n if (isExpr) {\n var compiledExpression = expressionData(value_1, propertySpec);\n functions[property] = compiledExpression.evaluate.bind(compiledExpression);\n } else {\n if (propertySpec.type == \'color\') {\n value_1 = index_es/* Color.parse */.Il.parse(value_1);\n }\n\n functions[property] = function () {\n return value_1;\n };\n }\n }\n\n zoomObj.zoom = zoom;\n return functions[property](zoomObj, feature);\n}\n/** @private */\n\nvar filterCache = {};\n/**\n * @private\n * @param {string} layerId Layer id.\n * @param {?} filter Filter.\n * @param {Object} feature Feature.\n * @param {number} zoom Zoom.\n * @return {boolean} Filter result.\n */\n\nfunction evaluateFilter(layerId, filter, feature, zoom) {\n if (!(layerId in filterCache)) {\n filterCache[layerId] = (0,index_es/* featureFilter */.TE)(filter).filter;\n }\n\n zoomObj.zoom = zoom;\n return filterCache[layerId](zoomObj, feature);\n}\n/**\n * @private\n * @param {?} color Color.\n * @param {number} opacity Opacity.\n * @return {string} Color.\n */\n\n\nfunction colorWithOpacity(color, opacity) {\n if (color) {\n if (color.a === 0 || opacity === 0) {\n return undefined;\n }\n\n var a = color.a;\n opacity = opacity === undefined ? 1 : opacity;\n return \'rgba(\' + Math.round(color.r * 255 / a) + \',\' + Math.round(color.g * 255 / a) + \',\' + Math.round(color.b * 255 / a) + \',\' + a * opacity + \')\';\n }\n\n return color;\n}\n\nvar templateRegEx = /^([^]*)\\{(.*)\\}([^]*)$/;\n/**\n * @private\n * @param {string} text Text.\n * @param {Object} properties Properties.\n * @return {string} Text.\n */\n\nfunction fromTemplate(text, properties) {\n var parts;\n\n do {\n parts = text.match(templateRegEx);\n\n if (parts) {\n var value = properties[parts[2]] || \'\';\n text = parts[1] + value + parts[3];\n }\n } while (parts);\n\n return text;\n}\n\nvar recordLayer = false;\n/**\n * ```js\n * import {recordStyleLayer} from \'ol-mapbox-style/dist/stylefunction\';\n * ```\n * Turns recording of the Mapbox Style\'s `layer` on and off. When turned on,\n * the layer that a rendered feature belongs to will be set as the feature\'s\n * `mapbox-layer` property.\n * @param {boolean} [record=false] Recording of the style layer is on.\n */\n\nfunction recordStyleLayer(record) {\n recordLayer = record;\n}\n/**\n * ```js\n * import stylefunction from \'ol-mapbox-style/dist/stylefunction\';\n * ```\n * Creates a style function from the `glStyle` object for all layers that use\n * the specified `source`, which needs to be a `"type": "vector"` or\n * `"type": "geojson"` source and applies it to the specified OpenLayers layer.\n *\n * Two additional properties will be set on the provided layer:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document\'s source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document\'s layers that are\n * included in the OpenLayers layer.\n *\n * This function also works in a web worker. In worker mode, the main thread needs\n * to listen to messages from the worker and respond with another message to make\n * sure that sprite image loading works:\n *\n * ```js\n * worker.addEventListener(\'message\', event => {\n * if (event.data.action === \'loadImage\') {\n * const image = new Image();\n * image.crossOrigin = \'anonymous\';\n * image.addEventListener(\'load\', function() {\n * createImageBitmap(image, 0, 0, image.width, image.height).then(imageBitmap => {\n * worker.postMessage({\n * action: \'imageLoaded\',\n * image: imageBitmap,\n * src: event.data.src\n * }, [imageBitmap]);\n * });\n * });\n * image.src = event.data.src;\n * }\n * });\n * ```\n *\n * @param {VectorLayer|VectorTileLayer} olLayer OpenLayers layer to\n * apply the style to. In addition to the style, the layer will get two\n * properties: `mapbox-source` will be the `id` of the `glStyle`\'s source used\n * for the layer, and `mapbox-layers` will be an array of the `id`s of the\n * `glStyle`\'s layers.\n * @param {string|Object} glStyle Mapbox Style object.\n * @param {string|Array<string>} source `source` key or an array of layer `id`s\n * from the Mapbox Style object. When a `source` key is provided, all layers for\n * the specified source will be included in the style function. When layer `id`s\n * are provided, they must be from layers that use the same source.\n * @param {Array<number>} [resolutions=[78271.51696402048, 39135.75848201024,\n 19567.87924100512, 9783.93962050256, 4891.96981025128, 2445.98490512564,\n 1222.99245256282, 611.49622628141, 305.748113140705, 152.8740565703525,\n 76.43702828517625, 38.21851414258813, 19.109257071294063, 9.554628535647032,\n 4.777314267823516, 2.388657133911758, 1.194328566955879, 0.5971642834779395,\n 0.29858214173896974, 0.14929107086948487, 0.07464553543474244]]\n * Resolutions for mapping resolution to zoom level.\n * @param {Object} [spriteData=undefined] Sprite data from the url specified in\n * the Mapbox Style object\'s `sprite` property. Only required if a `sprite`\n * property is specified in the Mapbox Style object.\n * @param {Object} [spriteImageUrl=undefined] Sprite image url for the sprite\n * specified in the Mapbox Style object\'s `sprite` property. Only required if a\n * `sprite` property is specified in the Mapbox Style object.\n * @param {function(Array<string>):Array<string>} [getFonts=undefined] Function that\n * receives a font stack as arguments, and returns a (modified) font stack that\n * is available. Font names are the names used in the Mapbox Style object. If\n * not provided, the font stack will be used as-is. This function can also be\n * used for loading web fonts.\n * @return {StyleFunction} Style function for use in\n * `ol.layer.Vector` or `ol.layer.VectorTile`.\n */\n\n/* harmony default export */ function stylefunction(olLayer, glStyle, source, resolutions, spriteData, spriteImageUrl, getFonts) {\n if (resolutions === void 0) {\n resolutions = defaultResolutions;\n }\n\n if (typeof glStyle == \'string\') {\n glStyle = JSON.parse(glStyle);\n }\n\n if (glStyle.version != 8) {\n throw new Error(\'glStyle version 8 required.\');\n }\n\n var spriteImage, spriteImgSize;\n\n if (spriteImageUrl) {\n if (typeof Image !== \'undefined\') {\n var img_1 = new Image();\n img_1.crossOrigin = \'anonymous\';\n\n img_1.onload = function () {\n spriteImage = img_1;\n spriteImgSize = [img_1.width, img_1.height];\n olLayer.changed();\n img_1.onload = null;\n };\n\n img_1.src = spriteImageUrl;\n } else if (typeof WorkerGlobalScope !== \'undefined\' && self instanceof WorkerGlobalScope) {\n //eslint-disable-line\n var worker =\n /** @type {*} */\n self; // Main thread needs to handle \'loadImage\' and dispatch \'imageLoaded\'\n\n worker.postMessage({\n action: \'loadImage\',\n src: spriteImageUrl\n });\n worker.addEventListener(\'message\', function handler(event) {\n if (event.data.action === \'imageLoaded\' && event.data.src === spriteImageUrl) {\n spriteImage = event.data.image;\n spriteImgSize = [spriteImage.width, spriteImage.height];\n }\n });\n }\n }\n\n var allLayers = (0,index_es/* derefLayers */.eG)(glStyle.layers);\n var layersBySourceLayer = {};\n var mapboxLayers = [];\n var mapboxSource;\n\n for (var i = 0, ii = allLayers.length; i < ii; ++i) {\n var layer = allLayers[i];\n var layerId = layer.id;\n\n if (typeof source == \'string\' && layer.source == source || source.indexOf(layerId) !== -1) {\n var sourceLayer = layer[\'source-layer\'];\n\n if (!mapboxSource) {\n mapboxSource = layer.source;\n var source_1 = glStyle.sources[mapboxSource];\n\n if (!source_1) {\n throw new Error("Source \\"" + mapboxSource + "\\" is not defined");\n }\n\n var type = source_1.type;\n\n if (type !== \'vector\' && type !== \'geojson\') {\n throw new Error("Source \\"" + mapboxSource + "\\" is not of type \\"vector\\" or \\"geojson\\", but \\"" + type + "\\"");\n }\n }\n\n var layers = layersBySourceLayer[sourceLayer];\n\n if (!layers) {\n layers = layersBySourceLayer[sourceLayer] = [];\n }\n\n layers.push({\n layer: layer,\n index: i\n });\n mapboxLayers.push(layerId);\n } // TODO revisit when diffing gets added\n\n\n delete functionCache[layerId];\n delete filterCache[layerId];\n }\n\n var textHalo = new style_Stroke();\n var textColor = new style_Fill();\n var iconImageCache = {};\n var patternCache = {};\n var styles = [];\n\n var styleFunction = function styleFunction(feature, resolution) {\n var properties = feature.getProperties();\n var layers = layersBySourceLayer[properties.layer];\n\n if (!layers) {\n return;\n }\n\n var zoom = resolutions.indexOf(resolution);\n\n if (zoom == -1) {\n zoom = getZoomForResolution(resolution, resolutions);\n }\n\n var type = types[feature.getGeometry().getType()];\n var f = {\n properties: properties,\n type: type\n };\n var stylesLength = -1;\n var featureBelongsToLayer;\n\n var _loop_1 = function _loop_1(i, ii) {\n var layerData = layers[i];\n var layer = layerData.layer;\n var layerId = layer.id;\n var layout = layer.layout || emptyObj;\n var paint = layer.paint || emptyObj;\n\n if (layout.visibility === \'none\' || \'minzoom\' in layer && zoom < layer.minzoom || \'maxzoom\' in layer && zoom >= layer.maxzoom) {\n return "continue";\n }\n\n var filter = layer.filter;\n\n if (!filter || evaluateFilter(layerId, filter, f, zoom)) {\n featureBelongsToLayer = layer;\n var color = void 0,\n opacity = void 0,\n fill = void 0,\n stroke = void 0,\n strokeColor = void 0,\n style = void 0;\n var index = layerData.index;\n\n if (type == 3 && (layer.type == \'fill\' || layer.type == \'fill-extrusion\')) {\n opacity = getValue(layer, \'paint\', layer.type + \'-opacity\', zoom, f);\n\n if (layer.type + \'-pattern\' in paint) {\n var fillIcon = getValue(layer, \'paint\', layer.type + \'-pattern\', zoom, f);\n\n if (fillIcon) {\n var icon_1 = typeof fillIcon === \'string\' ? fromTemplate(fillIcon, properties) : fillIcon.toString();\n\n if (spriteImage && spriteData && spriteData[icon_1]) {\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !style.getFill() || style.getStroke() || style.getText()) {\n style = styles[stylesLength] = new style_Style({\n fill: new style_Fill()\n });\n }\n\n fill = style.getFill();\n style.setZIndex(index);\n var icon_cache_key = icon_1 + \'.\' + opacity;\n var pattern = patternCache[icon_cache_key];\n\n if (!pattern) {\n var spriteImageData = spriteData[icon_1];\n var canvas = createCanvas(spriteImageData.width, spriteImageData.height);\n var ctx =\n /** @type {CanvasRenderingContext2D} */\n canvas.getContext(\'2d\');\n ctx.globalAlpha = opacity;\n ctx.drawImage(spriteImage, spriteImageData.x, spriteImageData.y, spriteImageData.width, spriteImageData.height, 0, 0, spriteImageData.width, spriteImageData.height);\n pattern = ctx.createPattern(canvas, \'repeat\');\n patternCache[icon_cache_key] = pattern;\n }\n\n fill.setColor(pattern);\n }\n }\n } else {\n color = colorWithOpacity(getValue(layer, \'paint\', layer.type + \'-color\', zoom, f), opacity);\n\n if (color) {\n if (layer.type + \'-outline-color\' in paint) {\n strokeColor = colorWithOpacity(getValue(layer, \'paint\', layer.type + \'-outline-color\', zoom, f), opacity);\n }\n\n if (!strokeColor) {\n strokeColor = color;\n }\n\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !(style.getFill() && style.getStroke()) || style.getText()) {\n style = styles[stylesLength] = new style_Style({\n fill: new style_Fill(),\n stroke: new style_Stroke()\n });\n }\n\n fill = style.getFill();\n fill.setColor(color);\n stroke = style.getStroke();\n stroke.setColor(strokeColor);\n stroke.setWidth(1);\n style.setZIndex(index);\n }\n }\n }\n\n if (type != 1 && layer.type == \'line\') {\n color = !(\'line-pattern\' in paint) && \'line-color\' in paint ? colorWithOpacity(getValue(layer, \'paint\', \'line-color\', zoom, f), getValue(layer, \'paint\', \'line-opacity\', zoom, f)) : undefined;\n var width_1 = getValue(layer, \'paint\', \'line-width\', zoom, f);\n\n if (color && width_1 > 0) {\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !style.getStroke() || style.getFill() || style.getText()) {\n style = styles[stylesLength] = new style_Style({\n stroke: new style_Stroke()\n });\n }\n\n stroke = style.getStroke();\n stroke.setLineCap(getValue(layer, \'layout\', \'line-cap\', zoom, f));\n stroke.setLineJoin(getValue(layer, \'layout\', \'line-join\', zoom, f));\n stroke.setMiterLimit(getValue(layer, \'layout\', \'line-miter-limit\', zoom, f));\n stroke.setColor(color);\n stroke.setWidth(width_1);\n stroke.setLineDash(paint[\'line-dasharray\'] ? getValue(layer, \'paint\', \'line-dasharray\', zoom, f).map(function (x) {\n return x * width_1;\n }) : null);\n style.setZIndex(index);\n }\n }\n\n var hasImage = false;\n var text = null;\n var placementAngle = 0;\n var icon = void 0,\n iconImg = void 0,\n skipLabel = void 0;\n\n if ((type == 1 || type == 2) && \'icon-image\' in layout) {\n var iconImage = getValue(layer, \'layout\', \'icon-image\', zoom, f);\n\n if (iconImage) {\n icon = typeof iconImage === \'string\' ? fromTemplate(iconImage, properties) : iconImage.toString();\n var styleGeom = undefined;\n\n if (spriteImage && spriteData && spriteData[icon]) {\n var iconRotationAlignment = getValue(layer, \'layout\', \'icon-rotation-alignment\', zoom, f);\n\n if (type == 2) {\n var geom = feature.getGeometry(); // ol package and ol-debug.js only\n\n if (geom.getFlatMidpoint || geom.getFlatMidpoints) {\n var extent = geom.getExtent();\n var size = Math.sqrt(Math.max(Math.pow((extent[2] - extent[0]) / resolution, 2), Math.pow((extent[3] - extent[1]) / resolution, 2)));\n\n if (size > 150) {\n //FIXME Do not hard-code a size of 150\n var midpoint = geom.getType() === \'MultiLineString\' ? geom.getFlatMidpoints() : geom.getFlatMidpoint();\n\n if (!stylefunction_renderFeature) {\n renderFeatureCoordinates = [NaN, NaN];\n stylefunction_renderFeature = new Feature(\'Point\', renderFeatureCoordinates, [], {}, null);\n }\n\n styleGeom = stylefunction_renderFeature;\n renderFeatureCoordinates[0] = midpoint[0];\n renderFeatureCoordinates[1] = midpoint[1];\n var placement = getValue(layer, \'layout\', \'symbol-placement\', zoom, f);\n\n if (placement === \'line\' && iconRotationAlignment === \'map\') {\n var stride = geom.getStride();\n var coordinates = geom.getFlatCoordinates();\n\n for (var i_1 = 0, ii_1 = coordinates.length - stride; i_1 < ii_1; i_1 += stride) {\n var x1 = coordinates[i_1];\n var y1 = coordinates[i_1 + 1];\n var x2 = coordinates[i_1 + stride];\n var y2 = coordinates[i_1 + stride + 1];\n var minX = Math.min(x1, x2);\n var minY = Math.min(y1, y2);\n var maxX = Math.max(x1, x2);\n var maxY = Math.max(y1, y2);\n\n if (midpoint[0] >= minX && midpoint[0] <= maxX && midpoint[1] >= minY && midpoint[1] <= maxY) {\n placementAngle = Math.atan2(y1 - y2, x2 - x1);\n break;\n }\n }\n }\n }\n }\n }\n\n if (type !== 2 || styleGeom) {\n var iconSize = getValue(layer, \'layout\', \'icon-size\', zoom, f);\n var iconColor = paint[\'icon-color\'] !== undefined ? getValue(layer, \'paint\', \'icon-color\', zoom, f) : null;\n\n if (!iconColor || iconColor.a !== 0) {\n var icon_cache_key = icon + \'.\' + iconSize;\n\n if (iconColor !== null) {\n icon_cache_key += \'.\' + iconColor;\n }\n\n iconImg = iconImageCache[icon_cache_key];\n\n if (!iconImg) {\n var spriteImageData = spriteData[icon];\n\n if (iconColor !== null) {\n // cut out the sprite and color it\n var canvas = createCanvas(spriteImageData.width, spriteImageData.height);\n var ctx =\n /** @type {CanvasRenderingContext2D} */\n canvas.getContext(\'2d\');\n ctx.drawImage(spriteImage, spriteImageData.x, spriteImageData.y, spriteImageData.width, spriteImageData.height, 0, 0, spriteImageData.width, spriteImageData.height);\n var data = ctx.getImageData(0, 0, canvas.width, canvas.height);\n\n for (var c = 0, cc = data.data.length; c < cc; c += 4) {\n var a = iconColor.a;\n\n if (a !== 0) {\n data.data[c] = iconColor.r * 255 / a;\n data.data[c + 1] = iconColor.g * 255 / a;\n data.data[c + 2] = iconColor.b * 255 / a;\n }\n\n data.data[c + 3] = a;\n }\n\n ctx.putImageData(data, 0, 0);\n iconImg = iconImageCache[icon_cache_key] = new style_Icon({\n img: canvas,\n imgSize: [canvas.width, canvas.height],\n scale: iconSize / spriteImageData.pixelRatio\n });\n } else {\n iconImg = iconImageCache[icon_cache_key] = new style_Icon({\n img: spriteImage,\n imgSize: spriteImgSize,\n size: [spriteImageData.width, spriteImageData.height],\n offset: [spriteImageData.x, spriteImageData.y],\n rotateWithView: iconRotationAlignment === \'map\',\n scale: iconSize / spriteImageData.pixelRatio\n });\n }\n }\n }\n\n if (iconImg) {\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !style.getImage() || style.getFill() || style.getStroke()) {\n style = styles[stylesLength] = new style_Style();\n }\n\n style.setGeometry(styleGeom);\n iconImg.setRotation(placementAngle + deg2rad(getValue(layer, \'layout\', \'icon-rotate\', zoom, f)));\n iconImg.setOpacity(getValue(layer, \'paint\', \'icon-opacity\', zoom, f));\n iconImg.setAnchor(stylefunction_anchor[getValue(layer, \'layout\', \'icon-anchor\', zoom, f)]);\n style.setImage(iconImg);\n text = style.getText();\n style.setText(undefined);\n style.setZIndex(index);\n hasImage = true;\n skipLabel = false;\n }\n } else {\n skipLabel = true;\n }\n }\n }\n }\n\n if (type == 1 && \'circle-radius\' in paint) {\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !style.getImage() || style.getFill() || style.getStroke()) {\n style = styles[stylesLength] = new style_Style();\n }\n\n var circleRadius = getValue(layer, \'paint\', \'circle-radius\', zoom, f);\n var circleStrokeColor = colorWithOpacity(getValue(layer, \'paint\', \'circle-stroke-color\', zoom, f), getValue(layer, \'paint\', \'circle-stroke-opacity\', zoom, f));\n var circleColor = colorWithOpacity(getValue(layer, \'paint\', \'circle-color\', zoom, f), getValue(layer, \'paint\', \'circle-opacity\', zoom, f));\n var circleStrokeWidth = getValue(layer, \'paint\', \'circle-stroke-width\', zoom, f);\n var cache_key = circleRadius + \'.\' + circleStrokeColor + \'.\' + circleColor + \'.\' + circleStrokeWidth;\n iconImg = iconImageCache[cache_key];\n\n if (!iconImg) {\n iconImg = iconImageCache[cache_key] = new Circle({\n radius: circleRadius,\n stroke: circleStrokeColor && circleStrokeWidth > 0 ? new style_Stroke({\n width: circleStrokeWidth,\n color: circleStrokeColor\n }) : undefined,\n fill: circleColor ? new style_Fill({\n color: circleColor\n }) : undefined\n });\n }\n\n style.setImage(iconImg);\n text = style.getText();\n style.setText(undefined);\n style.setGeometry(undefined);\n style.setZIndex(index);\n hasImage = true;\n }\n\n var label = void 0;\n\n if (\'text-field\' in layout) {\n var textField = getValue(layer, \'layout\', \'text-field\', zoom, f).toString();\n label = fromTemplate(textField, properties).trim();\n opacity = getValue(layer, \'paint\', \'text-opacity\', zoom, f);\n }\n\n if (label && opacity && !skipLabel) {\n if (!hasImage) {\n ++stylesLength;\n style = styles[stylesLength];\n\n if (!style || !style.getText() || style.getFill() || style.getStroke()) {\n style = styles[stylesLength] = new style_Style();\n }\n\n style.setImage(undefined);\n style.setGeometry(undefined);\n }\n\n if (!style.getText()) {\n style.setText(text || new style_Text({\n padding: [2, 2, 2, 2]\n }));\n }\n\n text = style.getText();\n var textSize = Math.round(getValue(layer, \'layout\', \'text-size\', zoom, f));\n var fontArray = getValue(layer, \'layout\', \'text-font\', zoom, f);\n var textLineHeight = getValue(layer, \'layout\', \'text-line-height\', zoom, f);\n var font = mapbox_to_css_font_default()(getFonts ? getFonts(fontArray) : fontArray, textSize, textLineHeight);\n var textTransform = layout[\'text-transform\'];\n\n if (textTransform == \'uppercase\') {\n label = label.toUpperCase();\n } else if (textTransform == \'lowercase\') {\n label = label.toLowerCase();\n }\n\n var maxTextWidth = getValue(layer, \'layout\', \'text-max-width\', zoom, f);\n var letterSpacing = getValue(layer, \'layout\', \'text-letter-spacing\', zoom, f);\n var wrappedLabel = type == 2 ? applyLetterSpacing(label, letterSpacing) : wrapText(label, font, maxTextWidth, letterSpacing);\n text.setText(wrappedLabel);\n text.setFont(font);\n text.setRotation(deg2rad(getValue(layer, \'layout\', \'text-rotate\', zoom, f)));\n var textAnchor = getValue(layer, \'layout\', \'text-anchor\', zoom, f);\n var placement = hasImage || type == 1 ? \'point\' : getValue(layer, \'layout\', \'symbol-placement\', zoom, f);\n text.setPlacement(placement);\n var textHaloWidth = getValue(layer, \'paint\', \'text-halo-width\', zoom, f);\n var textOffset = getValue(layer, \'layout\', \'text-offset\', zoom, f);\n var textTranslate = getValue(layer, \'paint\', \'text-translate\', zoom, f); // Text offset has to take halo width and line height into account\n\n var vOffset = 0;\n var hOffset = 0;\n\n if (placement == \'point\') {\n var textAlign = \'center\';\n\n if (textAnchor.indexOf(\'left\') !== -1) {\n textAlign = \'left\';\n hOffset = textHaloWidth;\n } else if (textAnchor.indexOf(\'right\') !== -1) {\n textAlign = \'right\';\n hOffset = -textHaloWidth;\n }\n\n text.setTextAlign(textAlign);\n var textRotationAlignment = getValue(layer, \'layout\', \'text-rotation-alignment\', zoom, f);\n text.setRotateWithView(textRotationAlignment == \'map\');\n } else {\n text.setMaxAngle(deg2rad(getValue(layer, \'layout\', \'text-max-angle\', zoom, f)) * label.length / wrappedLabel.length);\n text.setTextAlign();\n text.setRotateWithView(false);\n }\n\n var textBaseline = \'middle\';\n\n if (textAnchor.indexOf(\'bottom\') == 0) {\n textBaseline = \'bottom\';\n vOffset = -textHaloWidth - 0.5 * (textLineHeight - 1) * textSize;\n } else if (textAnchor.indexOf(\'top\') == 0) {\n textBaseline = \'top\';\n vOffset = textHaloWidth + 0.5 * (textLineHeight - 1) * textSize;\n }\n\n text.setTextBaseline(textBaseline);\n text.setOffsetX(textOffset[0] * textSize + hOffset + textTranslate[0]);\n text.setOffsetY(textOffset[1] * textSize + vOffset + textTranslate[1]);\n textColor.setColor(colorWithOpacity(getValue(layer, \'paint\', \'text-color\', zoom, f), opacity));\n text.setFill(textColor);\n var haloColor = colorWithOpacity(getValue(layer, \'paint\', \'text-halo-color\', zoom, f), opacity);\n\n if (haloColor) {\n textHalo.setColor(haloColor); // spec here : https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-symbol-text-halo-width\n // Halo width must be doubled because it is applied around the center of the text outline\n\n textHaloWidth *= 2; // 1/4 of text size (spec) x 2\n\n var halfTextSize = 0.5 * textSize;\n textHalo.setWidth(textHaloWidth <= halfTextSize ? textHaloWidth : halfTextSize);\n text.setStroke(textHalo);\n } else {\n text.setStroke(undefined);\n }\n\n var textPadding = getValue(layer, \'layout\', \'text-padding\', zoom, f);\n var padding = text.getPadding();\n\n if (textPadding !== padding[0]) {\n padding[0] = padding[1] = padding[2] = padding[3] = textPadding;\n }\n\n style.setZIndex(index);\n }\n }\n };\n\n for (var i = 0, ii = layers.length; i < ii; ++i) {\n _loop_1(i, ii);\n }\n\n if (stylesLength > -1) {\n styles.length = stylesLength + 1;\n\n if (recordLayer) {\n if (typeof feature.set === \'function\') {\n // ol/Feature\n feature.set(\'mapbox-layer\', featureBelongsToLayer);\n } else {\n // ol/render/Feature\n feature.getProperties()[\'mapbox-layer\'] = featureBelongsToLayer;\n }\n }\n\n return styles;\n }\n };\n\n olLayer.setStyle(styleFunction);\n olLayer.set(\'mapbox-source\', mapboxSource);\n olLayer.set(\'mapbox-layers\', mapboxLayers);\n return styleFunction;\n}\n\n// EXTERNAL MODULE: ./node_modules/webfont-matcher/lib/fonts/google.js\nvar google = __webpack_require__(4239);\nvar google_default = /*#__PURE__*/__webpack_require__.n(google);\n;// CONCATENATED MODULE: ./node_modules/ol/TileRange.js\n/**\n * @module ol/TileRange\n */\n\n/**\n * A representation of a contiguous block of tiles. A tile range is specified\n * by its min/max tile coordinates and is inclusive of coordinates.\n */\nvar TileRange =\n/** @class */\nfunction () {\n /**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n */\n function TileRange(minX, maxX, minY, maxY) {\n /**\n * @type {number}\n */\n this.minX = minX;\n /**\n * @type {number}\n */\n\n this.maxX = maxX;\n /**\n * @type {number}\n */\n\n this.minY = minY;\n /**\n * @type {number}\n */\n\n this.maxY = maxY;\n }\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {boolean} Contains tile coordinate.\n */\n\n\n TileRange.prototype.contains = function (tileCoord) {\n return this.containsXY(tileCoord[1], tileCoord[2]);\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Contains.\n */\n\n\n TileRange.prototype.containsTileRange = function (tileRange) {\n return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX && this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;\n };\n /**\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @return {boolean} Contains coordinate.\n */\n\n\n TileRange.prototype.containsXY = function (x, y) {\n return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Equals.\n */\n\n\n TileRange.prototype.equals = function (tileRange) {\n return this.minX == tileRange.minX && this.minY == tileRange.minY && this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n */\n\n\n TileRange.prototype.extend = function (tileRange) {\n if (tileRange.minX < this.minX) {\n this.minX = tileRange.minX;\n }\n\n if (tileRange.maxX > this.maxX) {\n this.maxX = tileRange.maxX;\n }\n\n if (tileRange.minY < this.minY) {\n this.minY = tileRange.minY;\n }\n\n if (tileRange.maxY > this.maxY) {\n this.maxY = tileRange.maxY;\n }\n };\n /**\n * @return {number} Height.\n */\n\n\n TileRange.prototype.getHeight = function () {\n return this.maxY - this.minY + 1;\n };\n /**\n * @return {import("./size.js").Size} Size.\n */\n\n\n TileRange.prototype.getSize = function () {\n return [this.getWidth(), this.getHeight()];\n };\n /**\n * @return {number} Width.\n */\n\n\n TileRange.prototype.getWidth = function () {\n return this.maxX - this.minX + 1;\n };\n /**\n * @param {TileRange} tileRange Tile range.\n * @return {boolean} Intersects.\n */\n\n\n TileRange.prototype.intersects = function (tileRange) {\n return this.minX <= tileRange.maxX && this.maxX >= tileRange.minX && this.minY <= tileRange.maxY && this.maxY >= tileRange.minY;\n };\n\n return TileRange;\n}();\n/**\n * @param {number} minX Minimum X.\n * @param {number} maxX Maximum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxY Maximum Y.\n * @param {TileRange=} tileRange TileRange.\n * @return {TileRange} Tile range.\n */\n\n\nfunction TileRange_createOrUpdate(minX, maxX, minY, maxY, tileRange) {\n if (tileRange !== undefined) {\n tileRange.minX = minX;\n tileRange.maxX = maxX;\n tileRange.minY = minY;\n tileRange.maxY = maxY;\n return tileRange;\n } else {\n return new TileRange(minX, maxX, minY, maxY);\n }\n}\n/* harmony default export */ var ol_TileRange = (TileRange);\n;// CONCATENATED MODULE: ./node_modules/ol/tilecoord.js\n/**\n * @module ol/tilecoord\n */\n\n/**\n * An array of three numbers representing the location of a tile in a tile\n * grid. The order is `z` (zoom level), `x` (column), and `y` (row).\n * @typedef {Array<number>} TileCoord\n * @api\n */\n\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {TileCoord=} opt_tileCoord Tile coordinate.\n * @return {TileCoord} Tile coordinate.\n */\nfunction tilecoord_createOrUpdate(z, x, y, opt_tileCoord) {\n if (opt_tileCoord !== undefined) {\n opt_tileCoord[0] = z;\n opt_tileCoord[1] = x;\n opt_tileCoord[2] = y;\n return opt_tileCoord;\n } else {\n return [z, x, y];\n }\n}\n/**\n * @param {number} z Z.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {string} Key.\n */\n\nfunction getKeyZXY(z, x, y) {\n return z + \'/\' + x + \'/\' + y;\n}\n/**\n * Get the key for a tile coord.\n * @param {TileCoord} tileCoord The tile coord.\n * @return {string} Key.\n */\n\nfunction tilecoord_getKey(tileCoord) {\n return getKeyZXY(tileCoord[0], tileCoord[1], tileCoord[2]);\n}\n/**\n * Get a tile coord given a key.\n * @param {string} key The tile coord key.\n * @return {TileCoord} The tile coord.\n */\n\nfunction fromKey(key) {\n return key.split(\'/\').map(Number);\n}\n/**\n * @param {TileCoord} tileCoord Tile coord.\n * @return {number} Hash.\n */\n\nfunction hash(tileCoord) {\n return (tileCoord[1] << tileCoord[0]) + tileCoord[2];\n}\n/**\n * @param {TileCoord} tileCoord Tile coordinate.\n * @param {!import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {boolean} Tile coordinate is within extent and zoom level range.\n */\n\nfunction withinExtentAndZ(tileCoord, tileGrid) {\n var z = tileCoord[0];\n var x = tileCoord[1];\n var y = tileCoord[2];\n\n if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {\n return false;\n }\n\n var tileRange = tileGrid.getFullTileRange(z);\n\n if (!tileRange) {\n return true;\n } else {\n return tileRange.containsXY(x, y);\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid/TileGrid.js\n/**\n * @module ol/tilegrid/TileGrid\n */\n\n\n\n\n\n\n\n\n/**\n * @private\n * @type {import("../tilecoord.js").TileCoord}\n */\n\nvar tmpTileCoord = [0, 0, 0];\n/**\n * @typedef {Object} Options\n * @property {import("../extent.js").Extent} [extent] Extent for the tile grid. No tiles outside this\n * extent will be requested by {@link module:ol/source/Tile} sources. When no `origin` or\n * `origins` are configured, the `origin` will be set to the top-left corner of the extent.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {import("../coordinate.js").Coordinate} [origin] The tile grid origin, i.e. where the `x`\n * and `y` axes meet (`[z, 0, 0]`). Tile coordinates increase left to right and downwards. If not\n * specified, `extent` or `origins` must be provided.\n * @property {Array<import("../coordinate.js").Coordinate>} [origins] Tile grid origins, i.e. where\n * the `x` and `y` axes meet (`[z, 0, 0]`), for each zoom level. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * origin. Tile coordinates increase left to right and downwards. If not specified, `extent` or\n * `origin` must be provided.\n * @property {!Array<number>} resolutions Resolutions. The array index of each resolution needs\n * to match the zoom level. This means that even if a `minZoom` is configured, the resolutions\n * array will have a length of `maxZoom + 1`.\n * @property {Array<import("../size.js").Size>} [sizes] Number of tile rows and columns\n * of the grid for each zoom level. If specified the values\n * define each zoom level\'s extent together with the `origin` or `origins`.\n * A grid `extent` can be configured in addition, and will further limit the extent\n * for which tile requests are made by sources. If the bottom-left corner of\n * an extent is used as `origin` or `origins`, then the `y` value must be\n * negative because OpenLayers tile coordinates use the top left as the origin.\n * @property {number|import("../size.js").Size} [tileSize] Tile size.\n * Default is `[256, 256]`.\n * @property {Array<import("../size.js").Size>} [tileSizes] Tile sizes. If given, the array length\n * should match the length of the `resolutions` array, i.e. each resolution can have a different\n * tile size.\n */\n\n/**\n * @classdesc\n * Base class for setting the grid pattern for sources accessing tiled-image\n * servers.\n * @api\n */\n\nvar TileGrid =\n/** @class */\nfunction () {\n /**\n * @param {Options} options Tile grid options.\n */\n function TileGrid(options) {\n /**\n * @protected\n * @type {number}\n */\n this.minZoom = options.minZoom !== undefined ? options.minZoom : 0;\n /**\n * @private\n * @type {!Array<number>}\n */\n\n this.resolutions_ = options.resolutions;\n asserts_assert(isSorted(this.resolutions_, function (a, b) {\n return b - a;\n }, true), 17); // `resolutions` must be sorted in descending order\n // check if we\'ve got a consistent zoom factor and origin\n\n var zoomFactor;\n\n if (!options.origins) {\n for (var i = 0, ii = this.resolutions_.length - 1; i < ii; ++i) {\n if (!zoomFactor) {\n zoomFactor = this.resolutions_[i] / this.resolutions_[i + 1];\n } else {\n if (this.resolutions_[i] / this.resolutions_[i + 1] !== zoomFactor) {\n zoomFactor = undefined;\n break;\n }\n }\n }\n }\n /**\n * @private\n * @type {number|undefined}\n */\n\n\n this.zoomFactor_ = zoomFactor;\n /**\n * @protected\n * @type {number}\n */\n\n this.maxZoom = this.resolutions_.length - 1;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n this.origin_ = options.origin !== undefined ? options.origin : null;\n /**\n * @private\n * @type {Array<import("../coordinate.js").Coordinate>}\n */\n\n this.origins_ = null;\n\n if (options.origins !== undefined) {\n this.origins_ = options.origins;\n asserts_assert(this.origins_.length == this.resolutions_.length, 20); // Number of `origins` and `resolutions` must be equal\n }\n\n var extent = options.extent;\n\n if (extent !== undefined && !this.origin_ && !this.origins_) {\n this.origin_ = getTopLeft(extent);\n }\n\n asserts_assert(!this.origin_ && this.origins_ || this.origin_ && !this.origins_, 18); // Either `origin` or `origins` must be configured, never both\n\n /**\n * @private\n * @type {Array<number|import("../size.js").Size>}\n */\n\n this.tileSizes_ = null;\n\n if (options.tileSizes !== undefined) {\n this.tileSizes_ = options.tileSizes;\n asserts_assert(this.tileSizes_.length == this.resolutions_.length, 19); // Number of `tileSizes` and `resolutions` must be equal\n }\n /**\n * @private\n * @type {number|import("../size.js").Size}\n */\n\n\n this.tileSize_ = options.tileSize !== undefined ? options.tileSize : !this.tileSizes_ ? DEFAULT_TILE_SIZE : null;\n asserts_assert(!this.tileSize_ && this.tileSizes_ || this.tileSize_ && !this.tileSizes_, 22); // Either `tileSize` or `tileSizes` must be configured, never both\n\n /**\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.extent_ = extent !== undefined ? extent : null;\n /**\n * @private\n * @type {Array<import("../TileRange.js").default>}\n */\n\n this.fullTileRanges_ = null;\n /**\n * @private\n * @type {import("../size.js").Size}\n */\n\n this.tmpSize_ = [0, 0];\n\n if (options.sizes !== undefined) {\n this.fullTileRanges_ = options.sizes.map(function (size, z) {\n var tileRange = new ol_TileRange(Math.min(0, size[0]), Math.max(size[0] - 1, -1), Math.min(0, size[1]), Math.max(size[1] - 1, -1));\n\n if (extent) {\n var restrictedTileRange = this.getTileRangeForExtentAndZ(extent, z);\n tileRange.minX = Math.max(restrictedTileRange.minX, tileRange.minX);\n tileRange.maxX = Math.min(restrictedTileRange.maxX, tileRange.maxX);\n tileRange.minY = Math.max(restrictedTileRange.minY, tileRange.minY);\n tileRange.maxY = Math.min(restrictedTileRange.maxY, tileRange.maxY);\n }\n\n return tileRange;\n }, this);\n } else if (extent) {\n this.calculateTileRanges_(extent);\n }\n }\n /**\n * Call a function with each tile coordinate for a given extent and zoom level.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} zoom Integer zoom level.\n * @param {function(import("../tilecoord.js").TileCoord): void} callback Function called with each tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.forEachTileCoord = function (extent, zoom, callback) {\n var tileRange = this.getTileRangeForExtentAndZ(extent, zoom);\n\n for (var i = tileRange.minX, ii = tileRange.maxX; i <= ii; ++i) {\n for (var j = tileRange.minY, jj = tileRange.maxY; j <= jj; ++j) {\n callback([zoom, i, j]);\n }\n }\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {function(number, import("../TileRange.js").default): boolean} callback Callback.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary import("../TileRange.js").default object.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {boolean} Callback succeeded.\n */\n\n\n TileGrid.prototype.forEachTileCoordParentTileRange = function (tileCoord, callback, opt_tileRange, opt_extent) {\n var tileRange, x, y;\n var tileCoordExtent = null;\n var z = tileCoord[0] - 1;\n\n if (this.zoomFactor_ === 2) {\n x = tileCoord[1];\n y = tileCoord[2];\n } else {\n tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n }\n\n while (z >= this.minZoom) {\n if (this.zoomFactor_ === 2) {\n x = Math.floor(x / 2);\n y = Math.floor(y / 2);\n tileRange = TileRange_createOrUpdate(x, x, y, y, opt_tileRange);\n } else {\n tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);\n }\n\n if (callback(z, tileRange)) {\n return true;\n }\n\n --z;\n }\n\n return false;\n };\n /**\n * Get the extent for this tile grid, if it was configured.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n TileGrid.prototype.getExtent = function () {\n return this.extent_;\n };\n /**\n * Get the maximum zoom level for the grid.\n * @return {number} Max zoom.\n * @api\n */\n\n\n TileGrid.prototype.getMaxZoom = function () {\n return this.maxZoom;\n };\n /**\n * Get the minimum zoom level for the grid.\n * @return {number} Min zoom.\n * @api\n */\n\n\n TileGrid.prototype.getMinZoom = function () {\n return this.minZoom;\n };\n /**\n * Get the origin for the grid at the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {import("../coordinate.js").Coordinate} Origin.\n * @api\n */\n\n\n TileGrid.prototype.getOrigin = function (z) {\n if (this.origin_) {\n return this.origin_;\n } else {\n return this.origins_[z];\n }\n };\n /**\n * Get the resolution for the given zoom level.\n * @param {number} z Integer zoom level.\n * @return {number} Resolution.\n * @api\n */\n\n\n TileGrid.prototype.getResolution = function (z) {\n return this.resolutions_[z];\n };\n /**\n * Get the list of resolutions for the tile grid.\n * @return {Array<number>} Resolutions.\n * @api\n */\n\n\n TileGrid.prototype.getResolutions = function () {\n return this.resolutions_;\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary import("../TileRange.js").default object.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {import("../TileRange.js").default} Tile range.\n */\n\n\n TileGrid.prototype.getTileCoordChildTileRange = function (tileCoord, opt_tileRange, opt_extent) {\n if (tileCoord[0] < this.maxZoom) {\n if (this.zoomFactor_ === 2) {\n var minX = tileCoord[1] * 2;\n var minY = tileCoord[2] * 2;\n return TileRange_createOrUpdate(minX, minX + 1, minY, minY + 1, opt_tileRange);\n }\n\n var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);\n return this.getTileRangeForExtentAndZ(tileCoordExtent, tileCoord[0] + 1, opt_tileRange);\n }\n\n return null;\n };\n /**\n * Get the extent for a tile range.\n * @param {number} z Integer zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.\n * @return {import("../extent.js").Extent} Extent.\n */\n\n\n TileGrid.prototype.getTileRangeExtent = function (z, tileRange, opt_extent) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var minX = origin[0] + tileRange.minX * tileSize[0] * resolution;\n var maxX = origin[0] + (tileRange.maxX + 1) * tileSize[0] * resolution;\n var minY = origin[1] + tileRange.minY * tileSize[1] * resolution;\n var maxY = origin[1] + (tileRange.maxY + 1) * tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get a tile range for the given extent and integer zoom level.\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} z Integer zoom level.\n * @param {import("../TileRange.js").default=} opt_tileRange Temporary tile range object.\n * @return {import("../TileRange.js").default} Tile range.\n */\n\n\n TileGrid.prototype.getTileRangeForExtentAndZ = function (extent, z, opt_tileRange) {\n var tileCoord = tmpTileCoord;\n this.getTileCoordForXYAndZ_(extent[0], extent[3], z, false, tileCoord);\n var minX = tileCoord[1];\n var minY = tileCoord[2];\n this.getTileCoordForXYAndZ_(extent[2], extent[1], z, true, tileCoord);\n return TileRange_createOrUpdate(minX, tileCoord[1], minY, tileCoord[2], opt_tileRange);\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {import("../coordinate.js").Coordinate} Tile center.\n */\n\n\n TileGrid.prototype.getTileCoordCenter = function (tileCoord) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n return [origin[0] + (tileCoord[1] + 0.5) * tileSize[0] * resolution, origin[1] - (tileCoord[2] + 0.5) * tileSize[1] * resolution];\n };\n /**\n * Get the extent of a tile coordinate.\n *\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../extent.js").Extent=} opt_extent Temporary extent object.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordExtent = function (tileCoord, opt_extent) {\n var origin = this.getOrigin(tileCoord[0]);\n var resolution = this.getResolution(tileCoord[0]);\n var tileSize = toSize(this.getTileSize(tileCoord[0]), this.tmpSize_);\n var minX = origin[0] + tileCoord[1] * tileSize[0] * resolution;\n var minY = origin[1] - (tileCoord[2] + 1) * tileSize[1] * resolution;\n var maxX = minX + tileSize[0] * resolution;\n var maxY = minY + tileSize[1] * resolution;\n return createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n };\n /**\n * Get the tile coordinate for the given map coordinate and resolution. This\n * method considers that coordinates that intersect tile boundaries should be\n * assigned the higher tile coordinate.\n *\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} resolution Resolution.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Destination import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordForCoordAndResolution = function (coordinate, resolution, opt_tileCoord) {\n return this.getTileCoordForXYAndResolution_(coordinate[0], coordinate[1], resolution, false, opt_tileCoord);\n };\n /**\n * Note that this method should not be called for resolutions that correspond\n * to an integer zoom level. Instead call the `getTileCoordForXYAndZ_` method.\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} resolution Resolution (for a non-integer zoom level).\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Temporary import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @private\n */\n\n\n TileGrid.prototype.getTileCoordForXYAndResolution_ = function (x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {\n var z = this.getZForResolution(resolution);\n var scale = resolution / this.getResolution(z);\n var origin = this.getOrigin(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n var adjustY = reverseIntersectionPolicy ? 0.5 : 0;\n var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n var yFromOrigin = Math.floor((origin[1] - y) / resolution + adjustY);\n var tileCoordX = scale * xFromOrigin / tileSize[0];\n var tileCoordY = scale * yFromOrigin / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = Math.ceil(tileCoordX) - 1;\n tileCoordY = Math.ceil(tileCoordY) - 1;\n } else {\n tileCoordX = Math.floor(tileCoordX);\n tileCoordY = Math.floor(tileCoordY);\n }\n\n return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Although there is repetition between this method and `getTileCoordForXYAndResolution_`,\n * they should have separate implementations. This method is for integer zoom\n * levels. The other method should only be called for resolutions corresponding\n * to non-integer zoom levels.\n * @param {number} x Map x coordinate.\n * @param {number} y Map y coordinate.\n * @param {number} z Integer zoom level.\n * @param {boolean} reverseIntersectionPolicy Instead of letting edge\n * intersections go to the higher tile coordinate, let edge intersections\n * go to the lower tile coordinate.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Temporary import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @private\n */\n\n\n TileGrid.prototype.getTileCoordForXYAndZ_ = function (x, y, z, reverseIntersectionPolicy, opt_tileCoord) {\n var origin = this.getOrigin(z);\n var resolution = this.getResolution(z);\n var tileSize = toSize(this.getTileSize(z), this.tmpSize_);\n var adjustX = reverseIntersectionPolicy ? 0.5 : 0;\n var adjustY = reverseIntersectionPolicy ? 0.5 : 0;\n var xFromOrigin = Math.floor((x - origin[0]) / resolution + adjustX);\n var yFromOrigin = Math.floor((origin[1] - y) / resolution + adjustY);\n var tileCoordX = xFromOrigin / tileSize[0];\n var tileCoordY = yFromOrigin / tileSize[1];\n\n if (reverseIntersectionPolicy) {\n tileCoordX = Math.ceil(tileCoordX) - 1;\n tileCoordY = Math.ceil(tileCoordY) - 1;\n } else {\n tileCoordX = Math.floor(tileCoordX);\n tileCoordY = Math.floor(tileCoordY);\n }\n\n return tilecoord_createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);\n };\n /**\n * Get a tile coordinate given a map coordinate and zoom level.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {number} z Zoom level.\n * @param {import("../tilecoord.js").TileCoord=} opt_tileCoord Destination import("../tilecoord.js").TileCoord object.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate.\n * @api\n */\n\n\n TileGrid.prototype.getTileCoordForCoordAndZ = function (coordinate, z, opt_tileCoord) {\n return this.getTileCoordForXYAndZ_(coordinate[0], coordinate[1], z, false, opt_tileCoord);\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @return {number} Tile resolution.\n */\n\n\n TileGrid.prototype.getTileCoordResolution = function (tileCoord) {\n return this.resolutions_[tileCoord[0]];\n };\n /**\n * Get the tile size for a zoom level. The type of the return value matches the\n * `tileSize` or `tileSizes` that the tile grid was configured with. To always\n * get an `import("../size.js").Size`, run the result through `import("../size.js").Size.toSize()`.\n * @param {number} z Z.\n * @return {number|import("../size.js").Size} Tile size.\n * @api\n */\n\n\n TileGrid.prototype.getTileSize = function (z) {\n if (this.tileSize_) {\n return this.tileSize_;\n } else {\n return this.tileSizes_[z];\n }\n };\n /**\n * @param {number} z Zoom level.\n * @return {import("../TileRange.js").default} Extent tile range for the specified zoom level.\n */\n\n\n TileGrid.prototype.getFullTileRange = function (z) {\n if (!this.fullTileRanges_) {\n return this.extent_ ? this.getTileRangeForExtentAndZ(this.extent_, z) : null;\n } else {\n return this.fullTileRanges_[z];\n }\n };\n /**\n * @param {number} resolution Resolution.\n * @param {number=} opt_direction If 0, the nearest resolution will be used.\n * If 1, the nearest lower resolution will be used. If -1, the nearest\n * higher resolution will be used. Default is 0.\n * @return {number} Z.\n * @api\n */\n\n\n TileGrid.prototype.getZForResolution = function (resolution, opt_direction) {\n var z = linearFindNearest(this.resolutions_, resolution, opt_direction || 0);\n return math_clamp(z, this.minZoom, this.maxZoom);\n };\n /**\n * @param {!import("../extent.js").Extent} extent Extent for this tile grid.\n * @private\n */\n\n\n TileGrid.prototype.calculateTileRanges_ = function (extent) {\n var length = this.resolutions_.length;\n var fullTileRanges = new Array(length);\n\n for (var z = this.minZoom; z < length; ++z) {\n fullTileRanges[z] = this.getTileRangeForExtentAndZ(extent, z);\n }\n\n this.fullTileRanges_ = fullTileRanges;\n };\n\n return TileGrid;\n}();\n\n/* harmony default export */ var tilegrid_TileGrid = (TileGrid);\n;// CONCATENATED MODULE: ./node_modules/ol/tilegrid.js\n/**\n * @module ol/tilegrid\n */\n\n\n\n\n\n\n\n/**\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {!TileGrid} Default tile grid for the\n * passed projection.\n */\n\nfunction getForProjection(projection) {\n var tileGrid = projection.getDefaultTileGrid();\n\n if (!tileGrid) {\n tileGrid = createForProjection(projection);\n projection.setDefaultTileGrid(tileGrid);\n }\n\n return tileGrid;\n}\n/**\n * @param {TileGrid} tileGrid Tile grid.\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {import("./tilecoord.js").TileCoord} Tile coordinate.\n */\n\nfunction tilegrid_wrapX(tileGrid, tileCoord, projection) {\n var z = tileCoord[0];\n var center = tileGrid.getTileCoordCenter(tileCoord);\n var projectionExtent = extentFromProjection(projection);\n\n if (!containsCoordinate(projectionExtent, center)) {\n var worldWidth = extent_getWidth(projectionExtent);\n var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);\n center[0] += worldWidth * worldsAway;\n return tileGrid.getTileCoordForCoordAndZ(center, z);\n } else {\n return tileCoord;\n }\n}\n/**\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import("./extent/Corner.js").default=} opt_corner Extent corner (default is `\'top-left\'`).\n * @return {!TileGrid} TileGrid instance.\n */\n\nfunction createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner) {\n var corner = opt_corner !== undefined ? opt_corner : extent_Corner.TOP_LEFT;\n var resolutions = resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize);\n return new tilegrid_TileGrid({\n extent: extent,\n origin: getCorner(extent, corner),\n resolutions: resolutions,\n tileSize: opt_tileSize\n });\n}\n/**\n * @typedef {Object} XYZOptions\n * @property {import("./extent.js").Extent} [extent] Extent for the tile grid. The origin for an XYZ tile grid is the\n * top-left corner of the extent. If `maxResolution` is not provided the zero level of the grid is defined by the resolution\n * at which one tile fits in the provided extent. If not provided, the extent of the EPSG:3857 projection is used.\n * @property {number} [maxResolution] Resolution at level zero.\n * @property {number} [maxZoom] Maximum zoom. The default is `42`. This determines the number of levels\n * in the grid set. For example, a `maxZoom` of 21 means there are 22 levels in the grid set.\n * @property {number} [minZoom=0] Minimum zoom.\n * @property {number|import("./size.js").Size} [tileSize=[256, 256]] Tile size in pixels.\n */\n\n/**\n * Creates a tile grid with a standard XYZ tiling scheme.\n * @param {XYZOptions=} opt_options Tile grid options.\n * @return {!TileGrid} Tile grid instance.\n * @api\n */\n\nfunction createXYZ(opt_options) {\n var xyzOptions = opt_options || {};\n var extent = xyzOptions.extent || proj_get(\'EPSG:3857\').getExtent();\n var gridOptions = {\n extent: extent,\n minZoom: xyzOptions.minZoom,\n tileSize: xyzOptions.tileSize,\n resolutions: resolutionsFromExtent(extent, xyzOptions.maxZoom, xyzOptions.tileSize, xyzOptions.maxResolution)\n };\n return new tilegrid_TileGrid(gridOptions);\n}\n/**\n * Create a resolutions array from an extent. A zoom factor of 2 is assumed.\n * @param {import("./extent.js").Extent} extent Extent.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {number=} opt_maxResolution Resolution at level zero.\n * @return {!Array<number>} Resolutions array.\n */\n\nfunction resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize, opt_maxResolution) {\n var maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : DEFAULT_MAX_ZOOM;\n var height = getHeight(extent);\n var width = extent_getWidth(extent);\n var tileSize = toSize(opt_tileSize !== undefined ? opt_tileSize : DEFAULT_TILE_SIZE);\n var maxResolution = opt_maxResolution > 0 ? opt_maxResolution : Math.max(width / tileSize[0], height / tileSize[1]);\n var length = maxZoom + 1;\n var resolutions = new Array(length);\n\n for (var z = 0; z < length; ++z) {\n resolutions[z] = maxResolution / Math.pow(2, z);\n }\n\n return resolutions;\n}\n/**\n * @param {import("./proj.js").ProjectionLike} projection Projection.\n * @param {number=} opt_maxZoom Maximum zoom level (default is\n * DEFAULT_MAX_ZOOM).\n * @param {number|import("./size.js").Size=} opt_tileSize Tile size (default uses\n * DEFAULT_TILE_SIZE).\n * @param {import("./extent/Corner.js").default=} opt_corner Extent corner (default is `\'top-left\'`).\n * @return {!TileGrid} TileGrid instance.\n */\n\n\nfunction createForProjection(projection, opt_maxZoom, opt_tileSize, opt_corner) {\n var extent = extentFromProjection(projection);\n return createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner);\n}\n/**\n * Generate a tile grid extent from a projection. If the projection has an\n * extent, it is used. If not, a global extent is assumed.\n * @param {import("./proj.js").ProjectionLike} projection Projection.\n * @return {import("./extent.js").Extent} Extent.\n */\n\nfunction extentFromProjection(projection) {\n projection = proj_get(projection);\n var extent = projection.getExtent();\n\n if (!extent) {\n var half = 180 * Units_METERS_PER_UNIT[proj_Units.DEGREES] / projection.getMetersPerUnit();\n extent = createOrUpdate(-half, -half, half, half);\n }\n\n return extent;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/Feature.js\nvar Feature_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Feature\n */\n\n\n\n\n\n\n/**\n * @typedef {typeof Feature|typeof import("./render/Feature.js").default} FeatureClass\n */\n\n/**\n * @typedef {Feature|import("./render/Feature.js").default} FeatureLike\n */\n\n/**\n * @classdesc\n * A vector object for geographic features with a geometry and other\n * attribute properties, similar to the features in vector file formats like\n * GeoJSON.\n *\n * Features can be styled individually with `setStyle`; otherwise they use the\n * style of their vector layer.\n *\n * Note that attribute properties are set as {@link module:ol/Object} properties on\n * the feature object, so they are observable, and have get/set accessors.\n *\n * Typically, a feature has a single geometry property. You can set the\n * geometry using the `setGeometry` method and get it with `getGeometry`.\n * It is possible to store more than one geometry on a feature using attribute\n * properties. By default, the geometry used for rendering is identified by\n * the property name `geometry`. If you want to use another geometry property\n * for rendering, use the `setGeometryName` method to change the attribute\n * property associated with the geometry for the feature. For example:\n *\n * ```js\n *\n * import Feature from \'ol/Feature\';\n * import Polygon from \'ol/geom/Polygon\';\n * import Point from \'ol/geom/Point\';\n *\n * var feature = new Feature({\n * geometry: new Polygon(polyCoords),\n * labelPoint: new Point(labelCoords),\n * name: \'My Polygon\'\n * });\n *\n * // get the polygon geometry\n * var poly = feature.getGeometry();\n *\n * // Render the feature as a point using the coordinates from labelPoint\n * feature.setGeometryName(\'labelPoint\');\n *\n * // get the point geometry\n * var point = feature.getGeometry();\n * ```\n *\n * @api\n * @template {import("./geom/Geometry.js").default} Geometry\n */\n\nvar Feature_Feature =\n/** @class */\nfunction (_super) {\n Feature_extends(Feature, _super);\n /**\n * @param {Geometry|Object<string, *>=} opt_geometryOrProperties\n * You may pass a Geometry object directly, or an object literal containing\n * properties. If you pass an object literal, you may include a Geometry\n * associated with a `geometry` key.\n */\n\n\n function Feature(opt_geometryOrProperties) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {number|string|undefined}\n */\n\n\n _this.id_ = undefined;\n /**\n * @type {string}\n * @private\n */\n\n _this.geometryName_ = \'geometry\';\n /**\n * User provided style.\n * @private\n * @type {import("./style/Style.js").StyleLike}\n */\n\n _this.style_ = null;\n /**\n * @private\n * @type {import("./style/Style.js").StyleFunction|undefined}\n */\n\n _this.styleFunction_ = undefined;\n /**\n * @private\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.geometryChangeKey_ = null;\n\n _this.addEventListener(getChangeEventType(_this.geometryName_), _this.handleGeometryChanged_);\n\n if (opt_geometryOrProperties) {\n if (typeof\n /** @type {?} */\n opt_geometryOrProperties.getSimplifiedGeometry === \'function\') {\n var geometry =\n /** @type {Geometry} */\n opt_geometryOrProperties;\n\n _this.setGeometry(geometry);\n } else {\n /** @type {Object<string, *>} */\n var properties = opt_geometryOrProperties;\n\n _this.setProperties(properties);\n }\n }\n\n return _this;\n }\n /**\n * Clone this feature. If the original feature has a geometry it\n * is also cloned. The feature id is not set in the clone.\n * @return {Feature} The clone.\n * @api\n */\n\n\n Feature.prototype.clone = function () {\n var clone = new Feature(this.hasProperties() ? this.getProperties() : null);\n clone.setGeometryName(this.getGeometryName());\n var geometry = this.getGeometry();\n\n if (geometry) {\n clone.setGeometry(geometry.clone());\n }\n\n var style = this.getStyle();\n\n if (style) {\n clone.setStyle(style);\n }\n\n return clone;\n };\n /**\n * Get the feature\'s default geometry. A feature may have any number of named\n * geometries. The "default" geometry (the one that is rendered by default) is\n * set when calling {@link module:ol/Feature~Feature#setGeometry}.\n * @return {Geometry|undefined} The default geometry for the feature.\n * @api\n * @observable\n */\n\n\n Feature.prototype.getGeometry = function () {\n return (\n /** @type {Geometry|undefined} */\n this.get(this.geometryName_)\n );\n };\n /**\n * Get the feature identifier. This is a stable identifier for the feature and\n * is either set when reading data from a remote source or set explicitly by\n * calling {@link module:ol/Feature~Feature#setId}.\n * @return {number|string|undefined} Id.\n * @api\n */\n\n\n Feature.prototype.getId = function () {\n return this.id_;\n };\n /**\n * Get the name of the feature\'s default geometry. By default, the default\n * geometry is named `geometry`.\n * @return {string} Get the property name associated with the default geometry\n * for this feature.\n * @api\n */\n\n\n Feature.prototype.getGeometryName = function () {\n return this.geometryName_;\n };\n /**\n * Get the feature\'s style. Will return what was provided to the\n * {@link module:ol/Feature~Feature#setStyle} method.\n * @return {import("./style/Style.js").StyleLike|undefined} The feature style.\n * @api\n */\n\n\n Feature.prototype.getStyle = function () {\n return this.style_;\n };\n /**\n * Get the feature\'s style function.\n * @return {import("./style/Style.js").StyleFunction|undefined} Return a function\n * representing the current style of this feature.\n * @api\n */\n\n\n Feature.prototype.getStyleFunction = function () {\n return this.styleFunction_;\n };\n /**\n * @private\n */\n\n\n Feature.prototype.handleGeometryChange_ = function () {\n this.changed();\n };\n /**\n * @private\n */\n\n\n Feature.prototype.handleGeometryChanged_ = function () {\n if (this.geometryChangeKey_) {\n unlistenByKey(this.geometryChangeKey_);\n this.geometryChangeKey_ = null;\n }\n\n var geometry = this.getGeometry();\n\n if (geometry) {\n this.geometryChangeKey_ = listen(geometry, EventType.CHANGE, this.handleGeometryChange_, this);\n }\n\n this.changed();\n };\n /**\n * Set the default geometry for the feature. This will update the property\n * with the name returned by {@link module:ol/Feature~Feature#getGeometryName}.\n * @param {Geometry|undefined} geometry The new geometry.\n * @api\n * @observable\n */\n\n\n Feature.prototype.setGeometry = function (geometry) {\n this.set(this.geometryName_, geometry);\n };\n /**\n * Set the style for the feature to override the layer style. This can be a\n * single style object, an array of styles, or a function that takes a\n * resolution and returns an array of styles. To unset the feature style, call\n * `setStyle()` without arguments or a falsey value.\n * @param {import("./style/Style.js").StyleLike=} opt_style Style for this feature.\n * @api\n * @fires module:ol/events/Event~BaseEvent#event:change\n */\n\n\n Feature.prototype.setStyle = function (opt_style) {\n this.style_ = opt_style;\n this.styleFunction_ = !opt_style ? undefined : createStyleFunction(opt_style);\n this.changed();\n };\n /**\n * Set the feature id. The feature id is considered stable and may be used when\n * requesting features or comparing identifiers returned from a remote source.\n * The feature id can be used with the\n * {@link module:ol/source/Vector~VectorSource#getFeatureById} method.\n * @param {number|string|undefined} id The feature id.\n * @api\n * @fires module:ol/events/Event~BaseEvent#event:change\n */\n\n\n Feature.prototype.setId = function (id) {\n this.id_ = id;\n this.changed();\n };\n /**\n * Set the property name to be used when getting the feature\'s default geometry.\n * When calling {@link module:ol/Feature~Feature#getGeometry}, the value of the property with\n * this name will be returned.\n * @param {string} name The property name of the default geometry.\n * @api\n */\n\n\n Feature.prototype.setGeometryName = function (name) {\n this.removeEventListener(getChangeEventType(this.geometryName_), this.handleGeometryChanged_);\n this.geometryName_ = name;\n this.addEventListener(getChangeEventType(this.geometryName_), this.handleGeometryChanged_);\n this.handleGeometryChanged_();\n };\n\n return Feature;\n}(ol_Object);\n/**\n * Convert the provided object into a feature style function. Functions passed\n * through unchanged. Arrays of Style or single style objects wrapped\n * in a new feature style function.\n * @param {!import("./style/Style.js").StyleFunction|!Array<import("./style/Style.js").default>|!import("./style/Style.js").default} obj\n * A feature style function, a single style, or an array of styles.\n * @return {import("./style/Style.js").StyleFunction} A style function.\n */\n\n\nfunction createStyleFunction(obj) {\n if (typeof obj === \'function\') {\n return obj;\n } else {\n /**\n * @type {Array<import("./style/Style.js").default>}\n */\n var styles_1;\n\n if (Array.isArray(obj)) {\n styles_1 = obj;\n } else {\n asserts_assert(typeof\n /** @type {?} */\n obj.getZIndex === \'function\', 41); // Expected an `import("./style/Style.js").Style` or an array of `import("./style/Style.js").Style`\n\n var style =\n /** @type {import("./style/Style.js").default} */\n obj;\n styles_1 = [style];\n }\n\n return function () {\n return styles_1;\n };\n }\n}\n/* harmony default export */ var ol_Feature = (Feature_Feature);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/GeometryCollection.js\nvar GeometryCollection_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/GeometryCollection\n */\n\n\n\n\n\n\n\n/**\n * @classdesc\n * An array of {@link module:ol/geom/Geometry} objects.\n *\n * @api\n */\n\nvar GeometryCollection =\n/** @class */\nfunction (_super) {\n GeometryCollection_extends(GeometryCollection, _super);\n /**\n * @param {Array<Geometry>=} opt_geometries Geometries.\n */\n\n\n function GeometryCollection(opt_geometries) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {Array<Geometry>}\n */\n\n\n _this.geometries_ = opt_geometries ? opt_geometries : null;\n /**\n * @type {Array<import("../events.js").EventsKey>}\n */\n\n _this.changeEventsKeys_ = [];\n\n _this.listenGeometriesChange_();\n\n return _this;\n }\n /**\n * @private\n */\n\n\n GeometryCollection.prototype.unlistenGeometriesChange_ = function () {\n this.changeEventsKeys_.forEach(unlistenByKey);\n this.changeEventsKeys_.length = 0;\n };\n /**\n * @private\n */\n\n\n GeometryCollection.prototype.listenGeometriesChange_ = function () {\n if (!this.geometries_) {\n return;\n }\n\n for (var i = 0, ii = this.geometries_.length; i < ii; ++i) {\n this.changeEventsKeys_.push(listen(this.geometries_[i], EventType.CHANGE, this.changed, this));\n }\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!GeometryCollection} Clone.\n * @api\n */\n\n\n GeometryCollection.prototype.clone = function () {\n var geometryCollection = new GeometryCollection(null);\n geometryCollection.setGeometries(this.geometries_);\n geometryCollection.applyProperties(this);\n return geometryCollection;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n GeometryCollection.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n minSquaredDistance = geometries[i].closestPointXY(x, y, closestPoint, minSquaredDistance);\n }\n\n return minSquaredDistance;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n GeometryCollection.prototype.containsXY = function (x, y) {\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n if (geometries[i].containsXY(x, y)) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @protected\n * @return {import("../extent.js").Extent} extent Extent.\n */\n\n\n GeometryCollection.prototype.computeExtent = function (extent) {\n createOrUpdateEmpty(extent);\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n extent_extend(extent, geometries[i].getExtent());\n }\n\n return extent;\n };\n /**\n * Return the geometries that make up this geometry collection.\n * @return {Array<Geometry>} Geometries.\n * @api\n */\n\n\n GeometryCollection.prototype.getGeometries = function () {\n return cloneGeometries(this.geometries_);\n };\n /**\n * @return {Array<Geometry>} Geometries.\n */\n\n\n GeometryCollection.prototype.getGeometriesArray = function () {\n return this.geometries_;\n };\n /**\n * @return {Array<Geometry>} Geometries.\n */\n\n\n GeometryCollection.prototype.getGeometriesArrayRecursive = function () {\n /** @type {Array<Geometry>} */\n var geometriesArray = [];\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n if (geometries[i].getType() === this.getType()) {\n geometriesArray = geometriesArray.concat(\n /** @type {GeometryCollection} */\n geometries[i].getGeometriesArrayRecursive());\n } else {\n geometriesArray.push(geometries[i]);\n }\n }\n\n return geometriesArray;\n };\n /**\n * Create a simplified version of this geometry using the Douglas Peucker algorithm.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {GeometryCollection} Simplified GeometryCollection.\n */\n\n\n GeometryCollection.prototype.getSimplifiedGeometry = function (squaredTolerance) {\n if (this.simplifiedGeometryRevision !== this.getRevision()) {\n this.simplifiedGeometryMaxMinSquaredTolerance = 0;\n this.simplifiedGeometryRevision = this.getRevision();\n }\n\n if (squaredTolerance < 0 || this.simplifiedGeometryMaxMinSquaredTolerance !== 0 && squaredTolerance < this.simplifiedGeometryMaxMinSquaredTolerance) {\n return this;\n }\n\n var simplifiedGeometries = [];\n var geometries = this.geometries_;\n var simplified = false;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n var geometry = geometries[i];\n var simplifiedGeometry = geometry.getSimplifiedGeometry(squaredTolerance);\n simplifiedGeometries.push(simplifiedGeometry);\n\n if (simplifiedGeometry !== geometry) {\n simplified = true;\n }\n }\n\n if (simplified) {\n var simplifiedGeometryCollection = new GeometryCollection(null);\n simplifiedGeometryCollection.setGeometriesArray(simplifiedGeometries);\n return simplifiedGeometryCollection;\n } else {\n this.simplifiedGeometryMaxMinSquaredTolerance = squaredTolerance;\n return this;\n }\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n GeometryCollection.prototype.getType = function () {\n return geom_GeometryType.GEOMETRY_COLLECTION;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n GeometryCollection.prototype.intersectsExtent = function (extent) {\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n if (geometries[i].intersectsExtent(extent)) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * @return {boolean} Is empty.\n */\n\n\n GeometryCollection.prototype.isEmpty = function () {\n return this.geometries_.length === 0;\n };\n /**\n * Rotate the geometry around a given coordinate. This modifies the geometry\n * coordinates in place.\n * @param {number} angle Rotation angle in radians.\n * @param {import("../coordinate.js").Coordinate} anchor The rotation center.\n * @api\n */\n\n\n GeometryCollection.prototype.rotate = function (angle, anchor) {\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n geometries[i].rotate(angle, anchor);\n }\n\n this.changed();\n };\n /**\n * Scale the geometry (with an optional origin). This modifies the geometry\n * coordinates in place.\n * @abstract\n * @param {number} sx The scaling factor in the x-direction.\n * @param {number=} opt_sy The scaling factor in the y-direction (defaults to sx).\n * @param {import("../coordinate.js").Coordinate=} opt_anchor The scale origin (defaults to the center\n * of the geometry extent).\n * @api\n */\n\n\n GeometryCollection.prototype.scale = function (sx, opt_sy, opt_anchor) {\n var anchor = opt_anchor;\n\n if (!anchor) {\n anchor = getCenter(this.getExtent());\n }\n\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n geometries[i].scale(sx, opt_sy, anchor);\n }\n\n this.changed();\n };\n /**\n * Set the geometries that make up this geometry collection.\n * @param {Array<Geometry>} geometries Geometries.\n * @api\n */\n\n\n GeometryCollection.prototype.setGeometries = function (geometries) {\n this.setGeometriesArray(cloneGeometries(geometries));\n };\n /**\n * @param {Array<Geometry>} geometries Geometries.\n */\n\n\n GeometryCollection.prototype.setGeometriesArray = function (geometries) {\n this.unlistenGeometriesChange_();\n this.geometries_ = geometries;\n this.listenGeometriesChange_();\n this.changed();\n };\n /**\n * Apply a transform function to the coordinates of the geometry.\n * The geometry is modified in place.\n * If you do not want the geometry modified in place, first `clone()` it and\n * then use this function on the clone.\n * @param {import("../proj.js").TransformFunction} transformFn Transform function.\n * Called with a flat array of geometry coordinates.\n * @api\n */\n\n\n GeometryCollection.prototype.applyTransform = function (transformFn) {\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n geometries[i].applyTransform(transformFn);\n }\n\n this.changed();\n };\n /**\n * Translate the geometry. This modifies the geometry coordinates in place. If\n * instead you want a new geometry, first `clone()` this geometry.\n * @param {number} deltaX Delta X.\n * @param {number} deltaY Delta Y.\n * @api\n */\n\n\n GeometryCollection.prototype.translate = function (deltaX, deltaY) {\n var geometries = this.geometries_;\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n geometries[i].translate(deltaX, deltaY);\n }\n\n this.changed();\n };\n /**\n * Clean up.\n */\n\n\n GeometryCollection.prototype.disposeInternal = function () {\n this.unlistenGeometriesChange_();\n\n _super.prototype.disposeInternal.call(this);\n };\n\n return GeometryCollection;\n}(geom_Geometry);\n/**\n * @param {Array<Geometry>} geometries Geometries.\n * @return {Array<Geometry>} Cloned geometries.\n */\n\n\nfunction cloneGeometries(geometries) {\n var clonedGeometries = [];\n\n for (var i = 0, ii = geometries.length; i < ii; ++i) {\n clonedGeometries.push(geometries[i].clone());\n }\n\n return clonedGeometries;\n}\n\n/* harmony default export */ var geom_GeometryCollection = (GeometryCollection);\n;// CONCATENATED MODULE: ./node_modules/ol/format/Feature.js\n/**\n * @module ol/format/Feature\n */\n\n\n\n\n/**\n * @typedef {Object} ReadOptions\n * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are reading.\n * If not provided, the projection will be derived from the data (where possible) or\n * the `dataProjection` of the format is assigned (where set). If the projection\n * can not be derived from the data and if no `dataProjection` is set for a format,\n * the features will not be reprojected.\n * @property {import("../extent.js").Extent} [extent] Tile extent in map units of the tile being read.\n * This is only required when reading data with tile pixels as geometry units. When configured,\n * a `dataProjection` with `TILE_PIXELS` as `units` and the tile\'s pixel extent as `extent` needs to be\n * provided.\n * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries\n * created by the format reader. If not provided, features will be returned in the\n * `dataProjection`.\n */\n\n/**\n * @typedef {Object} WriteOptions\n * @property {import("../proj.js").ProjectionLike} [dataProjection] Projection of the data we are writing.\n * If not provided, the `dataProjection` of the format is assigned (where set).\n * If no `dataProjection` is set for a format, the features will be returned\n * in the `featureProjection`.\n * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection of the feature geometries\n * that will be serialized by the format writer. If not provided, geometries are assumed\n * to be in the `dataProjection` if that is set; in other words, they are not transformed.\n * @property {boolean} [rightHanded] When writing geometries, follow the right-hand\n * rule for linear ring orientation. This means that polygons will have counter-clockwise\n * exterior rings and clockwise interior rings. By default, coordinates are serialized\n * as they are provided at construction. If `true`, the right-hand rule will\n * be applied. If `false`, the left-hand rule will be applied (clockwise for\n * exterior and counter-clockwise for interior rings). Note that not all\n * formats support this. The GeoJSON format does use this property when writing\n * geometries.\n * @property {number} [decimals] Maximum number of decimal places for coordinates.\n * Coordinates are stored internally as floats, but floating-point arithmetic can create\n * coordinates with a large number of decimal places, not generally wanted on output.\n * Set a number here to round coordinates. Can also be used to ensure that\n * coordinates read in can be written back out with the same number of decimals.\n * Default is no rounding.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for feature formats.\n * {@link module:ol/format/Feature~FeatureFormat} subclasses provide the ability to decode and encode\n * {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial\n * file formats. See the documentation for each format for more details.\n *\n * @abstract\n * @api\n */\n\nvar FeatureFormat =\n/** @class */\nfunction () {\n function FeatureFormat() {\n /**\n * @protected\n * @type {import("../proj/Projection.js").default}\n */\n this.dataProjection = null;\n /**\n * @protected\n * @type {import("../proj/Projection.js").default}\n */\n\n this.defaultFeatureProjection = null;\n }\n /**\n * Adds the data projection to the read options.\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Options.\n * @return {ReadOptions|undefined} Options.\n * @protected\n */\n\n\n FeatureFormat.prototype.getReadOptions = function (source, opt_options) {\n var options;\n\n if (opt_options) {\n var dataProjection = opt_options.dataProjection ? proj_get(opt_options.dataProjection) : this.readProjection(source);\n\n if (opt_options.extent && dataProjection && dataProjection.getUnits() === proj_Units.TILE_PIXELS) {\n dataProjection = proj_get(dataProjection);\n dataProjection.setWorldExtent(opt_options.extent);\n }\n\n options = {\n dataProjection: dataProjection,\n featureProjection: opt_options.featureProjection\n };\n }\n\n return this.adaptOptions(options);\n };\n /**\n * Sets the `dataProjection` on the options, if no `dataProjection`\n * is set.\n * @param {WriteOptions|ReadOptions|undefined} options\n * Options.\n * @protected\n * @return {WriteOptions|ReadOptions|undefined}\n * Updated options.\n */\n\n\n FeatureFormat.prototype.adaptOptions = function (options) {\n return obj_assign({\n dataProjection: this.dataProjection,\n featureProjection: this.defaultFeatureProjection\n }, options);\n };\n /**\n * @abstract\n * @return {import("./FormatType.js").default} Format.\n */\n\n\n FeatureFormat.prototype.getType = function () {\n return util_abstract();\n };\n /**\n * Read a single feature from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../Feature.js").FeatureLike} Feature.\n */\n\n\n FeatureFormat.prototype.readFeature = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read all features from a source.\n *\n * @abstract\n * @param {Document|Element|ArrayBuffer|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n */\n\n\n FeatureFormat.prototype.readFeatures = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read a single geometry from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../geom/Geometry.js").default} Geometry.\n */\n\n\n FeatureFormat.prototype.readGeometry = function (source, opt_options) {\n return util_abstract();\n };\n /**\n * Read the projection from a source.\n *\n * @abstract\n * @param {Document|Element|Object|string} source Source.\n * @return {import("../proj/Projection.js").default} Projection.\n */\n\n\n FeatureFormat.prototype.readProjection = function (source) {\n return util_abstract();\n };\n /**\n * Encode a feature in this format.\n *\n * @abstract\n * @param {import("../Feature.js").default} feature Feature.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeFeature = function (feature, opt_options) {\n return util_abstract();\n };\n /**\n * Encode an array of features in this format.\n *\n * @abstract\n * @param {Array<import("../Feature.js").default>} features Features.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeFeatures = function (features, opt_options) {\n return util_abstract();\n };\n /**\n * Write a single geometry in this format.\n *\n * @abstract\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {WriteOptions=} opt_options Write options.\n * @return {string} Result.\n */\n\n\n FeatureFormat.prototype.writeGeometry = function (geometry, opt_options) {\n return util_abstract();\n };\n\n return FeatureFormat;\n}();\n\n/* harmony default export */ var format_Feature = (FeatureFormat);\n/**\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {boolean} write Set to true for writing, false for reading.\n * @param {(WriteOptions|ReadOptions)=} opt_options Options.\n * @return {import("../geom/Geometry.js").default} Transformed geometry.\n */\n\nfunction transformGeometryWithOptions(geometry, write, opt_options) {\n var featureProjection = opt_options ? proj_get(opt_options.featureProjection) : null;\n var dataProjection = opt_options ? proj_get(opt_options.dataProjection) : null;\n var transformed;\n\n if (featureProjection && dataProjection && !equivalent(featureProjection, dataProjection)) {\n transformed = (write ? geometry.clone() : geometry).transform(write ? featureProjection : dataProjection, write ? dataProjection : featureProjection);\n } else {\n transformed = geometry;\n }\n\n if (write && opt_options &&\n /** @type {WriteOptions} */\n opt_options.decimals !== undefined) {\n var power_1 = Math.pow(10,\n /** @type {WriteOptions} */\n opt_options.decimals); // if decimals option on write, round each coordinate appropriately\n\n /**\n * @param {Array<number>} coordinates Coordinates.\n * @return {Array<number>} Transformed coordinates.\n */\n\n var transform = function transform(coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n coordinates[i] = Math.round(coordinates[i] * power_1) / power_1;\n }\n\n return coordinates;\n };\n\n if (transformed === geometry) {\n transformed = geometry.clone();\n }\n\n transformed.applyTransform(transform);\n }\n\n return transformed;\n}\n/**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {ReadOptions=} opt_options Read options.\n * @return {import("../extent.js").Extent} Transformed extent.\n */\n\nfunction transformExtentWithOptions(extent, opt_options) {\n var featureProjection = opt_options ? getProjection(opt_options.featureProjection) : null;\n var dataProjection = opt_options ? getProjection(opt_options.dataProjection) : null;\n\n if (featureProjection && dataProjection && !equivalentProjection(featureProjection, dataProjection)) {\n return transformExtent(extent, dataProjection, featureProjection);\n } else {\n return extent;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/ol/format/JSONFeature.js\nvar JSONFeature_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/format/JSONFeature\n */\n\n\n\n\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for JSON feature formats.\n *\n * @abstract\n */\n\nvar JSONFeature =\n/** @class */\nfunction (_super) {\n JSONFeature_extends(JSONFeature, _super);\n\n function JSONFeature() {\n return _super.call(this) || this;\n }\n /**\n * @return {import("./FormatType.js").default} Format.\n */\n\n\n JSONFeature.prototype.getType = function () {\n return FormatType.JSON;\n };\n /**\n * Read a feature. Only works for a single feature. Use `readFeatures` to\n * read a feature collection.\n *\n * @param {ArrayBuffer|Document|Element|Object|string} source Source.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {import("../Feature.js").default} Feature.\n * @api\n */\n\n\n JSONFeature.prototype.readFeature = function (source, opt_options) {\n return this.readFeatureFromObject(getObject(source), this.getReadOptions(source, opt_options));\n };\n /**\n * Read all features. Works with both a single feature and a feature\n * collection.\n *\n * @param {ArrayBuffer|Document|Element|Object|string} source Source.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {Array<import("../Feature.js").default>} Features.\n * @api\n */\n\n\n JSONFeature.prototype.readFeatures = function (source, opt_options) {\n return this.readFeaturesFromObject(getObject(source), this.getReadOptions(source, opt_options));\n };\n /**\n * @abstract\n * @param {Object} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {import("../Feature.js").default} Feature.\n */\n\n\n JSONFeature.prototype.readFeatureFromObject = function (object, opt_options) {\n return util_abstract();\n };\n /**\n * @abstract\n * @param {Object} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {Array<import("../Feature.js").default>} Features.\n */\n\n\n JSONFeature.prototype.readFeaturesFromObject = function (object, opt_options) {\n return util_abstract();\n };\n /**\n * Read a geometry.\n *\n * @param {ArrayBuffer|Document|Element|Object|string} source Source.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {import("../geom/Geometry.js").default} Geometry.\n * @api\n */\n\n\n JSONFeature.prototype.readGeometry = function (source, opt_options) {\n return this.readGeometryFromObject(getObject(source), this.getReadOptions(source, opt_options));\n };\n /**\n * @abstract\n * @param {Object} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {import("../geom/Geometry.js").default} Geometry.\n */\n\n\n JSONFeature.prototype.readGeometryFromObject = function (object, opt_options) {\n return util_abstract();\n };\n /**\n * Read the projection.\n *\n * @param {ArrayBuffer|Document|Element|Object|string} source Source.\n * @return {import("../proj/Projection.js").default} Projection.\n * @api\n */\n\n\n JSONFeature.prototype.readProjection = function (source) {\n return this.readProjectionFromObject(getObject(source));\n };\n /**\n * @abstract\n * @param {Object} object Object.\n * @protected\n * @return {import("../proj/Projection.js").default} Projection.\n */\n\n\n JSONFeature.prototype.readProjectionFromObject = function (object) {\n return util_abstract();\n };\n /**\n * Encode a feature as string.\n *\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {string} Encoded feature.\n * @api\n */\n\n\n JSONFeature.prototype.writeFeature = function (feature, opt_options) {\n return JSON.stringify(this.writeFeatureObject(feature, opt_options));\n };\n /**\n * @abstract\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {Object} Object.\n */\n\n\n JSONFeature.prototype.writeFeatureObject = function (feature, opt_options) {\n return util_abstract();\n };\n /**\n * Encode an array of features as string.\n *\n * @param {Array<import("../Feature.js").default>} features Features.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {string} Encoded features.\n * @api\n */\n\n\n JSONFeature.prototype.writeFeatures = function (features, opt_options) {\n return JSON.stringify(this.writeFeaturesObject(features, opt_options));\n };\n /**\n * @abstract\n * @param {Array<import("../Feature.js").default>} features Features.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {Object} Object.\n */\n\n\n JSONFeature.prototype.writeFeaturesObject = function (features, opt_options) {\n return util_abstract();\n };\n /**\n * Encode a geometry as string.\n *\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {string} Encoded geometry.\n * @api\n */\n\n\n JSONFeature.prototype.writeGeometry = function (geometry, opt_options) {\n return JSON.stringify(this.writeGeometryObject(geometry, opt_options));\n };\n /**\n * @abstract\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {Object} Object.\n */\n\n\n JSONFeature.prototype.writeGeometryObject = function (geometry, opt_options) {\n return util_abstract();\n };\n\n return JSONFeature;\n}(format_Feature);\n/**\n * @param {Document|Element|Object|string} source Source.\n * @return {Object} Object.\n */\n\n\nfunction getObject(source) {\n if (typeof source === \'string\') {\n var object = JSON.parse(source);\n return object ?\n /** @type {Object} */\n object : null;\n } else if (source !== null) {\n return source;\n } else {\n return null;\n }\n}\n\n/* harmony default export */ var format_JSONFeature = (JSONFeature);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/LineString.js\nvar LineString_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/LineString\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Linestring geometry.\n *\n * @api\n */\n\nvar LineString =\n/** @class */\nfunction (_super) {\n LineString_extends(LineString, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function LineString(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n /**\n * @private\n * @type {import("../coordinate.js").Coordinate}\n */\n\n\n _this.flatMidpoint_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.flatMidpointRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (opt_layout !== undefined && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed coordinate to the coordinates of the linestring.\n * @param {import("../coordinate.js").Coordinate} coordinate Coordinate.\n * @api\n */\n\n\n LineString.prototype.appendCoordinate = function (coordinate) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = coordinate.slice();\n } else {\n array_extend(this.flatCoordinates, coordinate);\n }\n\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!LineString} Clone.\n * @api\n */\n\n\n LineString.prototype.clone = function () {\n var lineString = new LineString(this.flatCoordinates.slice(), this.layout);\n lineString.applyProperties(this);\n return lineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n LineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(maxSquaredDelta(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestPoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Iterate over each segment, calling the provided callback.\n * If the callback returns a truthy value the function returns that\n * value immediately. Otherwise the function returns `false`.\n *\n * @param {function(this: S, import("../coordinate.js").Coordinate, import("../coordinate.js").Coordinate): T} callback Function\n * called for each segment. The function will receive two arguments, the start and end coordinates of the segment.\n * @return {T|boolean} Value.\n * @template T,S\n * @api\n */\n\n\n LineString.prototype.forEachSegment = function (callback) {\n return forEach(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, callback);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * @param {number} m M.\n * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n * @return {import("../coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n LineString.prototype.getCoordinateAtM = function (m, opt_extrapolate) {\n if (this.layout != geom_GeometryLayout.XYM && this.layout != geom_GeometryLayout.XYZM) {\n return null;\n }\n\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n return lineStringCoordinateAtM(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, m, extrapolate);\n };\n /**\n * Return the coordinates of the linestring.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n LineString.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the coordinate at the provided fraction along the linestring.\n * The `fraction` is a number between 0 and 1, where 0 is the start of the\n * linestring and 1 is the end.\n * @param {number} fraction Fraction.\n * @param {import("../coordinate.js").Coordinate=} opt_dest Optional coordinate whose values will\n * be modified. If not provided, a new coordinate will be returned.\n * @return {import("../coordinate.js").Coordinate} Coordinate of the interpolated point.\n * @api\n */\n\n\n LineString.prototype.getCoordinateAt = function (fraction, opt_dest) {\n return interpolatePoint(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, fraction, opt_dest, this.stride);\n };\n /**\n * Return the length of the linestring on projected plane.\n * @return {number} Length (on projected plane).\n * @api\n */\n\n\n LineString.prototype.getLength = function () {\n return lineStringLength(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * @return {Array<number>} Flat midpoint.\n */\n\n\n LineString.prototype.getFlatMidpoint = function () {\n if (this.flatMidpointRevision_ != this.getRevision()) {\n this.flatMidpoint_ = this.getCoordinateAt(0.5, this.flatMidpoint_);\n this.flatMidpointRevision_ = this.getRevision();\n }\n\n return this.flatMidpoint_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LineString} Simplified LineString.\n * @protected\n */\n\n\n LineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n simplifiedFlatCoordinates.length = douglasPeucker(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0);\n return new LineString(simplifiedFlatCoordinates, geom_GeometryLayout.XY);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n LineString.prototype.getType = function () {\n return geom_GeometryType.LINE_STRING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n LineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineString(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, extent);\n };\n /**\n * Set the coordinates of the linestring.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n LineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return LineString;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_LineString = (LineString);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiLineString.js\nvar MultiLineString_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiLineString\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-linestring geometry.\n *\n * @api\n */\n\nvar MultiLineString =\n/** @class */\nfunction (_super) {\n MultiLineString_extends(MultiLineString, _super);\n /**\n * @param {Array<Array<import("../coordinate.js").Coordinate>|LineString>|Array<number>} coordinates\n * Coordinates or LineString geometries. (For internal use, flat coordinates in\n * combination with `opt_layout` and `opt_ends` are also accepted.)\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<number>=} opt_ends Flat coordinate ends for internal use.\n */\n\n\n function MultiLineString(coordinates, opt_layout, opt_ends) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<number>}\n * @private\n */\n\n\n _this.ends_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n\n if (Array.isArray(coordinates[0])) {\n _this.setCoordinates(\n /** @type {Array<Array<import("../coordinate.js").Coordinate>>} */\n coordinates, opt_layout);\n } else if (opt_layout !== undefined && opt_ends) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.ends_ = opt_ends;\n } else {\n var layout = _this.getLayout();\n\n var lineStrings =\n /** @type {Array<LineString>} */\n coordinates;\n var flatCoordinates = [];\n var ends = [];\n\n for (var i = 0, ii = lineStrings.length; i < ii; ++i) {\n var lineString = lineStrings[i];\n\n if (i === 0) {\n layout = lineString.getLayout();\n }\n\n array_extend(flatCoordinates, lineString.getFlatCoordinates());\n ends.push(flatCoordinates.length);\n }\n\n _this.setFlatCoordinates(layout, flatCoordinates);\n\n _this.ends_ = ends;\n }\n\n return _this;\n }\n /**\n * Append the passed linestring to the multilinestring.\n * @param {LineString} lineString LineString.\n * @api\n */\n\n\n MultiLineString.prototype.appendLineString = function (lineString) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = lineString.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, lineString.getFlatCoordinates().slice());\n }\n\n this.ends_.push(this.flatCoordinates.length);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiLineString} Clone.\n * @api\n */\n\n\n MultiLineString.prototype.clone = function () {\n var multiLineString = new MultiLineString(this.flatCoordinates.slice(), this.layout, this.ends_.slice());\n multiLineString.applyProperties(this);\n return multiLineString;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiLineString.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(arrayMaxSquaredDelta(this.flatCoordinates, 0, this.ends_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestArrayPoint(this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * Returns the coordinate at `m` using linear interpolation, or `null` if no\n * such coordinate exists.\n *\n * `opt_extrapolate` controls extrapolation beyond the range of Ms in the\n * MultiLineString. If `opt_extrapolate` is `true` then Ms less than the first\n * M will return the first coordinate and Ms greater than the last M will\n * return the last coordinate.\n *\n * `opt_interpolate` controls interpolation between consecutive LineStrings\n * within the MultiLineString. If `opt_interpolate` is `true` the coordinates\n * will be linearly interpolated between the last coordinate of one LineString\n * and the first coordinate of the next LineString. If `opt_interpolate` is\n * `false` then the function will return `null` for Ms falling between\n * LineStrings.\n *\n * @param {number} m M.\n * @param {boolean=} opt_extrapolate Extrapolate. Default is `false`.\n * @param {boolean=} opt_interpolate Interpolate. Default is `false`.\n * @return {import("../coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\n\n MultiLineString.prototype.getCoordinateAtM = function (m, opt_extrapolate, opt_interpolate) {\n if (this.layout != geom_GeometryLayout.XYM && this.layout != geom_GeometryLayout.XYZM || this.flatCoordinates.length === 0) {\n return null;\n }\n\n var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;\n var interpolate = opt_interpolate !== undefined ? opt_interpolate : false;\n return lineStringsCoordinateAtM(this.flatCoordinates, 0, this.ends_, this.stride, m, extrapolate, interpolate);\n };\n /**\n * Return the coordinates of the multilinestring.\n * @return {Array<Array<import("../coordinate.js").Coordinate>>} Coordinates.\n * @api\n */\n\n\n MultiLineString.prototype.getCoordinates = function () {\n return inflateCoordinatesArray(this.flatCoordinates, 0, this.ends_, this.stride);\n };\n /**\n * @return {Array<number>} Ends.\n */\n\n\n MultiLineString.prototype.getEnds = function () {\n return this.ends_;\n };\n /**\n * Return the linestring at the specified index.\n * @param {number} index Index.\n * @return {LineString} LineString.\n * @api\n */\n\n\n MultiLineString.prototype.getLineString = function (index) {\n if (index < 0 || this.ends_.length <= index) {\n return null;\n }\n\n return new geom_LineString(this.flatCoordinates.slice(index === 0 ? 0 : this.ends_[index - 1], this.ends_[index]), this.layout);\n };\n /**\n * Return the linestrings of this multilinestring.\n * @return {Array<LineString>} LineStrings.\n * @api\n */\n\n\n MultiLineString.prototype.getLineStrings = function () {\n var flatCoordinates = this.flatCoordinates;\n var ends = this.ends_;\n var layout = this.layout;\n /** @type {Array<LineString>} */\n\n var lineStrings = [];\n var offset = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var lineString = new geom_LineString(flatCoordinates.slice(offset, end), layout);\n lineStrings.push(lineString);\n offset = end;\n }\n\n return lineStrings;\n };\n /**\n * @return {Array<number>} Flat midpoints.\n */\n\n\n MultiLineString.prototype.getFlatMidpoints = function () {\n var midpoints = [];\n var flatCoordinates = this.flatCoordinates;\n var offset = 0;\n var ends = this.ends_;\n var stride = this.stride;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i];\n var midpoint = interpolatePoint(flatCoordinates, offset, end, stride, 0.5);\n array_extend(midpoints, midpoint);\n offset = end;\n }\n\n return midpoints;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiLineString} Simplified MultiLineString.\n * @protected\n */\n\n\n MultiLineString.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEnds = [];\n simplifiedFlatCoordinates.length = douglasPeuckerArray(this.flatCoordinates, 0, this.ends_, this.stride, squaredTolerance, simplifiedFlatCoordinates, 0, simplifiedEnds);\n return new MultiLineString(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEnds);\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiLineString.prototype.getType = function () {\n return geom_GeometryType.MULTI_LINE_STRING;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiLineString.prototype.intersectsExtent = function (extent) {\n return intersectsLineStringArray(this.flatCoordinates, 0, this.ends_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multilinestring.\n * @param {!Array<Array<import("../coordinate.js").Coordinate>>} coordinates Coordinates.\n * @param {GeometryLayout=} opt_layout Layout.\n * @api\n */\n\n\n MultiLineString.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 2);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var ends = deflateCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.ends_);\n this.flatCoordinates.length = ends.length === 0 ? 0 : ends[ends.length - 1];\n this.changed();\n };\n\n return MultiLineString;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiLineString = (MultiLineString);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPoint.js\nvar MultiPoint_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiPoint\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-point geometry.\n *\n * @api\n */\n\nvar MultiPoint =\n/** @class */\nfunction (_super) {\n MultiPoint_extends(MultiPoint, _super);\n /**\n * @param {Array<import("../coordinate.js").Coordinate>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n */\n\n\n function MultiPoint(coordinates, opt_layout) {\n var _this = _super.call(this) || this;\n\n if (opt_layout && !Array.isArray(coordinates[0])) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n } else {\n _this.setCoordinates(\n /** @type {Array<import("../coordinate.js").Coordinate>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed point to this multipoint.\n * @param {Point} point Point.\n * @api\n */\n\n\n MultiPoint.prototype.appendPoint = function (point) {\n if (!this.flatCoordinates) {\n this.flatCoordinates = point.getFlatCoordinates().slice();\n } else {\n array_extend(this.flatCoordinates, point.getFlatCoordinates());\n }\n\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPoint} Clone.\n * @api\n */\n\n\n MultiPoint.prototype.clone = function () {\n var multiPoint = new MultiPoint(this.flatCoordinates.slice(), this.layout);\n multiPoint.applyProperties(this);\n return multiPoint;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiPoint.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var squaredDistance = math_squaredDistance(x, y, flatCoordinates[i], flatCoordinates[i + 1]);\n\n if (squaredDistance < minSquaredDistance) {\n minSquaredDistance = squaredDistance;\n\n for (var j = 0; j < stride; ++j) {\n closestPoint[j] = flatCoordinates[i + j];\n }\n\n closestPoint.length = stride;\n }\n }\n\n return minSquaredDistance;\n };\n /**\n * Return the coordinates of the multipoint.\n * @return {Array<import("../coordinate.js").Coordinate>} Coordinates.\n * @api\n */\n\n\n MultiPoint.prototype.getCoordinates = function () {\n return inflateCoordinates(this.flatCoordinates, 0, this.flatCoordinates.length, this.stride);\n };\n /**\n * Return the point at the specified index.\n * @param {number} index Index.\n * @return {Point} Point.\n * @api\n */\n\n\n MultiPoint.prototype.getPoint = function (index) {\n var n = !this.flatCoordinates ? 0 : this.flatCoordinates.length / this.stride;\n\n if (index < 0 || n <= index) {\n return null;\n }\n\n return new geom_Point(this.flatCoordinates.slice(index * this.stride, (index + 1) * this.stride), this.layout);\n };\n /**\n * Return the points of this multipoint.\n * @return {Array<Point>} Points.\n * @api\n */\n\n\n MultiPoint.prototype.getPoints = function () {\n var flatCoordinates = this.flatCoordinates;\n var layout = this.layout;\n var stride = this.stride;\n /** @type {Array<Point>} */\n\n var points = [];\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var point = new geom_Point(flatCoordinates.slice(i, i + stride), layout);\n points.push(point);\n }\n\n return points;\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiPoint.prototype.getType = function () {\n return geom_GeometryType.MULTI_POINT;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiPoint.prototype.intersectsExtent = function (extent) {\n var flatCoordinates = this.flatCoordinates;\n var stride = this.stride;\n\n for (var i = 0, ii = flatCoordinates.length; i < ii; i += stride) {\n var x = flatCoordinates[i];\n var y = flatCoordinates[i + 1];\n\n if (containsXY(extent, x, y)) {\n return true;\n }\n }\n\n return false;\n };\n /**\n * Set the coordinates of the multipoint.\n * @param {!Array<import("../coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n MultiPoint.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 1);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n this.flatCoordinates.length = deflateCoordinates(this.flatCoordinates, 0, coordinates, this.stride);\n this.changed();\n };\n\n return MultiPoint;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiPoint = (MultiPoint);\n;// CONCATENATED MODULE: ./node_modules/ol/geom/MultiPolygon.js\nvar MultiPolygon_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/geom/MultiPolygon\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Multi-polygon geometry.\n *\n * @api\n */\n\nvar MultiPolygon =\n/** @class */\nfunction (_super) {\n MultiPolygon_extends(MultiPolygon, _super);\n /**\n * @param {Array<Array<Array<import("../coordinate.js").Coordinate>>|Polygon>|Array<number>} coordinates Coordinates.\n * For internal use, flat coordinates in combination with `opt_layout` and `opt_endss` are also accepted.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @param {Array<Array<number>>=} opt_endss Array of ends for internal use with flat coordinates.\n */\n\n\n function MultiPolygon(coordinates, opt_layout, opt_endss) {\n var _this = _super.call(this) || this;\n /**\n * @type {Array<Array<number>>}\n * @private\n */\n\n\n _this.endss_ = [];\n /**\n * @private\n * @type {number}\n */\n\n _this.flatInteriorPointsRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.flatInteriorPoints_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDelta_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.maxDeltaRevision_ = -1;\n /**\n * @private\n * @type {number}\n */\n\n _this.orientedRevision_ = -1;\n /**\n * @private\n * @type {Array<number>}\n */\n\n _this.orientedFlatCoordinates_ = null;\n\n if (!opt_endss && !Array.isArray(coordinates[0])) {\n var layout = _this.getLayout();\n\n var polygons =\n /** @type {Array<Polygon>} */\n coordinates;\n var flatCoordinates = [];\n var endss = [];\n\n for (var i = 0, ii = polygons.length; i < ii; ++i) {\n var polygon = polygons[i];\n\n if (i === 0) {\n layout = polygon.getLayout();\n }\n\n var offset = flatCoordinates.length;\n var ends = polygon.getEnds();\n\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] += offset;\n }\n\n array_extend(flatCoordinates, polygon.getFlatCoordinates());\n endss.push(ends);\n }\n\n opt_layout = layout;\n coordinates = flatCoordinates;\n opt_endss = endss;\n }\n\n if (opt_layout !== undefined && opt_endss) {\n _this.setFlatCoordinates(opt_layout,\n /** @type {Array<number>} */\n coordinates);\n\n _this.endss_ = opt_endss;\n } else {\n _this.setCoordinates(\n /** @type {Array<Array<Array<import("../coordinate.js").Coordinate>>>} */\n coordinates, opt_layout);\n }\n\n return _this;\n }\n /**\n * Append the passed polygon to this multipolygon.\n * @param {Polygon} polygon Polygon.\n * @api\n */\n\n\n MultiPolygon.prototype.appendPolygon = function (polygon) {\n /** @type {Array<number>} */\n var ends;\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = polygon.getFlatCoordinates().slice();\n ends = polygon.getEnds().slice();\n this.endss_.push();\n } else {\n var offset = this.flatCoordinates.length;\n array_extend(this.flatCoordinates, polygon.getFlatCoordinates());\n ends = polygon.getEnds().slice();\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] += offset;\n }\n }\n\n this.endss_.push(ends);\n this.changed();\n };\n /**\n * Make a complete copy of the geometry.\n * @return {!MultiPolygon} Clone.\n * @api\n */\n\n\n MultiPolygon.prototype.clone = function () {\n var len = this.endss_.length;\n var newEndss = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n newEndss[i] = this.endss_[i].slice();\n }\n\n var multiPolygon = new MultiPolygon(this.flatCoordinates.slice(), this.layout, newEndss);\n multiPolygon.applyProperties(this);\n return multiPolygon;\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @param {import("../coordinate.js").Coordinate} closestPoint Closest point.\n * @param {number} minSquaredDistance Minimum squared distance.\n * @return {number} Minimum squared distance.\n */\n\n\n MultiPolygon.prototype.closestPointXY = function (x, y, closestPoint, minSquaredDistance) {\n if (minSquaredDistance < closestSquaredDistanceXY(this.getExtent(), x, y)) {\n return minSquaredDistance;\n }\n\n if (this.maxDeltaRevision_ != this.getRevision()) {\n this.maxDelta_ = Math.sqrt(multiArrayMaxSquaredDelta(this.flatCoordinates, 0, this.endss_, this.stride, 0));\n this.maxDeltaRevision_ = this.getRevision();\n }\n\n return assignClosestMultiArrayPoint(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance);\n };\n /**\n * @param {number} x X.\n * @param {number} y Y.\n * @return {boolean} Contains (x, y).\n */\n\n\n MultiPolygon.prototype.containsXY = function (x, y) {\n return linearRingssContainsXY(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, x, y);\n };\n /**\n * Return the area of the multipolygon on projected plane.\n * @return {number} Area (on projected plane).\n * @api\n */\n\n\n MultiPolygon.prototype.getArea = function () {\n return linearRingss(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride);\n };\n /**\n * Get the coordinate array for this geometry. This array has the structure\n * of a GeoJSON coordinate array for multi-polygons.\n *\n * @param {boolean=} opt_right Orient coordinates according to the right-hand\n * rule (counter-clockwise for exterior and clockwise for interior rings).\n * If `false`, coordinates will be oriented according to the left-hand rule\n * (clockwise for exterior and counter-clockwise for interior rings).\n * By default, coordinate orientation will depend on how the geometry was\n * constructed.\n * @return {Array<Array<Array<import("../coordinate.js").Coordinate>>>} Coordinates.\n * @api\n */\n\n\n MultiPolygon.prototype.getCoordinates = function (opt_right) {\n var flatCoordinates;\n\n if (opt_right !== undefined) {\n flatCoordinates = this.getOrientedFlatCoordinates().slice();\n orientLinearRingsArray(flatCoordinates, 0, this.endss_, this.stride, opt_right);\n } else {\n flatCoordinates = this.flatCoordinates;\n }\n\n return inflateMultiCoordinatesArray(flatCoordinates, 0, this.endss_, this.stride);\n };\n /**\n * @return {Array<Array<number>>} Endss.\n */\n\n\n MultiPolygon.prototype.getEndss = function () {\n return this.endss_;\n };\n /**\n * @return {Array<number>} Flat interior points.\n */\n\n\n MultiPolygon.prototype.getFlatInteriorPoints = function () {\n if (this.flatInteriorPointsRevision_ != this.getRevision()) {\n var flatCenters = center_linearRingss(this.flatCoordinates, 0, this.endss_, this.stride);\n this.flatInteriorPoints_ = getInteriorPointsOfMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, flatCenters);\n this.flatInteriorPointsRevision_ = this.getRevision();\n }\n\n return this.flatInteriorPoints_;\n };\n /**\n * Return the interior points as {@link module:ol/geom/MultiPoint multipoint}.\n * @return {MultiPoint} Interior points as XYM coordinates, where M is\n * the length of the horizontal intersection that the point belongs to.\n * @api\n */\n\n\n MultiPolygon.prototype.getInteriorPoints = function () {\n return new geom_MultiPoint(this.getFlatInteriorPoints().slice(), geom_GeometryLayout.XYM);\n };\n /**\n * @return {Array<number>} Oriented flat coordinates.\n */\n\n\n MultiPolygon.prototype.getOrientedFlatCoordinates = function () {\n if (this.orientedRevision_ != this.getRevision()) {\n var flatCoordinates = this.flatCoordinates;\n\n if (linearRingssAreOriented(flatCoordinates, 0, this.endss_, this.stride)) {\n this.orientedFlatCoordinates_ = flatCoordinates;\n } else {\n this.orientedFlatCoordinates_ = flatCoordinates.slice();\n this.orientedFlatCoordinates_.length = orientLinearRingsArray(this.orientedFlatCoordinates_, 0, this.endss_, this.stride);\n }\n\n this.orientedRevision_ = this.getRevision();\n }\n\n return this.orientedFlatCoordinates_;\n };\n /**\n * @param {number} squaredTolerance Squared tolerance.\n * @return {MultiPolygon} Simplified MultiPolygon.\n * @protected\n */\n\n\n MultiPolygon.prototype.getSimplifiedGeometryInternal = function (squaredTolerance) {\n var simplifiedFlatCoordinates = [];\n var simplifiedEndss = [];\n simplifiedFlatCoordinates.length = quantizeMultiArray(this.flatCoordinates, 0, this.endss_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEndss);\n return new MultiPolygon(simplifiedFlatCoordinates, geom_GeometryLayout.XY, simplifiedEndss);\n };\n /**\n * Return the polygon at the specified index.\n * @param {number} index Index.\n * @return {Polygon} Polygon.\n * @api\n */\n\n\n MultiPolygon.prototype.getPolygon = function (index) {\n if (index < 0 || this.endss_.length <= index) {\n return null;\n }\n\n var offset;\n\n if (index === 0) {\n offset = 0;\n } else {\n var prevEnds = this.endss_[index - 1];\n offset = prevEnds[prevEnds.length - 1];\n }\n\n var ends = this.endss_[index].slice();\n var end = ends[ends.length - 1];\n\n if (offset !== 0) {\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n ends[i] -= offset;\n }\n }\n\n return new geom_Polygon(this.flatCoordinates.slice(offset, end), this.layout, ends);\n };\n /**\n * Return the polygons of this multipolygon.\n * @return {Array<Polygon>} Polygons.\n * @api\n */\n\n\n MultiPolygon.prototype.getPolygons = function () {\n var layout = this.layout;\n var flatCoordinates = this.flatCoordinates;\n var endss = this.endss_;\n var polygons = [];\n var offset = 0;\n\n for (var i = 0, ii = endss.length; i < ii; ++i) {\n var ends = endss[i].slice();\n var end = ends[ends.length - 1];\n\n if (offset !== 0) {\n for (var j = 0, jj = ends.length; j < jj; ++j) {\n ends[j] -= offset;\n }\n }\n\n var polygon = new geom_Polygon(flatCoordinates.slice(offset, end), layout, ends);\n polygons.push(polygon);\n offset = end;\n }\n\n return polygons;\n };\n /**\n * Get the type of this geometry.\n * @return {import("./GeometryType.js").default} Geometry type.\n * @api\n */\n\n\n MultiPolygon.prototype.getType = function () {\n return geom_GeometryType.MULTI_POLYGON;\n };\n /**\n * Test if the geometry and the passed extent intersect.\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {boolean} `true` if the geometry and the extent intersect.\n * @api\n */\n\n\n MultiPolygon.prototype.intersectsExtent = function (extent) {\n return intersectsLinearRingMultiArray(this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, extent);\n };\n /**\n * Set the coordinates of the multipolygon.\n * @param {!Array<Array<Array<import("../coordinate.js").Coordinate>>>} coordinates Coordinates.\n * @param {import("./GeometryLayout.js").default=} opt_layout Layout.\n * @api\n */\n\n\n MultiPolygon.prototype.setCoordinates = function (coordinates, opt_layout) {\n this.setLayout(opt_layout, coordinates, 3);\n\n if (!this.flatCoordinates) {\n this.flatCoordinates = [];\n }\n\n var endss = deflateMultiCoordinatesArray(this.flatCoordinates, 0, coordinates, this.stride, this.endss_);\n\n if (endss.length === 0) {\n this.flatCoordinates.length = 0;\n } else {\n var lastEnds = endss[endss.length - 1];\n this.flatCoordinates.length = lastEnds.length === 0 ? 0 : lastEnds[lastEnds.length - 1];\n }\n\n this.changed();\n };\n\n return MultiPolygon;\n}(geom_SimpleGeometry);\n\n/* harmony default export */ var geom_MultiPolygon = (MultiPolygon);\n;// CONCATENATED MODULE: ./node_modules/ol/format/GeoJSON.js\n/**\n * @module ol/format/GeoJSON\n */\nvar GeoJSON_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {import("geojson").GeoJSON} GeoJSONObject\n * @typedef {import("geojson").Feature} GeoJSONFeature\n * @typedef {import("geojson").FeatureCollection} GeoJSONFeatureCollection\n * @typedef {import("geojson").Geometry} GeoJSONGeometry\n * @typedef {import("geojson").Point} GeoJSONPoint\n * @typedef {import("geojson").LineString} GeoJSONLineString\n * @typedef {import("geojson").Polygon} GeoJSONPolygon\n * @typedef {import("geojson").MultiPoint} GeoJSONMultiPoint\n * @typedef {import("geojson").MultiLineString} GeoJSONMultiLineString\n * @typedef {import("geojson").MultiPolygon} GeoJSONMultiPolygon\n * @typedef {import("geojson").GeometryCollection} GeoJSONGeometryCollection\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("../proj.js").ProjectionLike} [dataProjection=\'EPSG:4326\'] Default data projection.\n * @property {import("../proj.js").ProjectionLike} [featureProjection] Projection for features read or\n * written by the format. Options passed to read or write methods will take precedence.\n * @property {string} [geometryName] Geometry name to use when creating features.\n * @property {boolean} [extractGeometryName=false] Certain GeoJSON providers include\n * the geometry_name field in the feature GeoJSON. If set to `true` the GeoJSON reader\n * will look for that field to set the geometry name. If both this field is set to `true`\n * and a `geometryName` is provided, the `geometryName` will take precedence.\n */\n\n/**\n * @classdesc\n * Feature format for reading and writing data in the GeoJSON format.\n *\n * @api\n */\n\nvar GeoJSON =\n/** @class */\nfunction (_super) {\n GeoJSON_extends(GeoJSON, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function GeoJSON(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n _this = _super.call(this) || this;\n /**\n * @type {import("../proj/Projection.js").default}\n */\n\n _this.dataProjection = proj_get(options.dataProjection ? options.dataProjection : \'EPSG:4326\');\n\n if (options.featureProjection) {\n _this.defaultFeatureProjection = proj_get(options.featureProjection);\n }\n /**\n * Name of the geometry attribute for features.\n * @type {string|undefined}\n * @private\n */\n\n\n _this.geometryName_ = options.geometryName;\n /**\n * Look for the geometry name in the feature GeoJSON\n * @type {boolean|undefined}\n * @private\n */\n\n _this.extractGeometryName_ = options.extractGeometryName;\n return _this;\n }\n /**\n * @param {Object} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {import("../Feature.js").default} Feature.\n */\n\n\n GeoJSON.prototype.readFeatureFromObject = function (object, opt_options) {\n /**\n * @type {GeoJSONFeature}\n */\n var geoJSONFeature = null;\n\n if (object[\'type\'] === \'Feature\') {\n geoJSONFeature =\n /** @type {GeoJSONFeature} */\n object;\n } else {\n geoJSONFeature = {\n \'type\': \'Feature\',\n \'geometry\':\n /** @type {GeoJSONGeometry} */\n object,\n \'properties\': null\n };\n }\n\n var geometry = readGeometry(geoJSONFeature[\'geometry\'], opt_options);\n var feature = new ol_Feature();\n\n if (this.geometryName_) {\n feature.setGeometryName(this.geometryName_);\n } else if (this.extractGeometryName_ && \'geometry_name\' in geoJSONFeature !== undefined) {\n feature.setGeometryName(geoJSONFeature[\'geometry_name\']);\n }\n\n feature.setGeometry(geometry);\n\n if (\'id\' in geoJSONFeature) {\n feature.setId(geoJSONFeature[\'id\']);\n }\n\n if (geoJSONFeature[\'properties\']) {\n feature.setProperties(geoJSONFeature[\'properties\'], true);\n }\n\n return feature;\n };\n /**\n * @param {Object} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {Array<Feature>} Features.\n */\n\n\n GeoJSON.prototype.readFeaturesFromObject = function (object, opt_options) {\n var geoJSONObject =\n /** @type {GeoJSONObject} */\n object;\n /** @type {Array<import("../Feature.js").default>} */\n\n var features = null;\n\n if (geoJSONObject[\'type\'] === \'FeatureCollection\') {\n var geoJSONFeatureCollection =\n /** @type {GeoJSONFeatureCollection} */\n object;\n features = [];\n var geoJSONFeatures = geoJSONFeatureCollection[\'features\'];\n\n for (var i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {\n features.push(this.readFeatureFromObject(geoJSONFeatures[i], opt_options));\n }\n } else {\n features = [this.readFeatureFromObject(object, opt_options)];\n }\n\n return features;\n };\n /**\n * @param {GeoJSONGeometry} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @protected\n * @return {import("../geom/Geometry.js").default} Geometry.\n */\n\n\n GeoJSON.prototype.readGeometryFromObject = function (object, opt_options) {\n return readGeometry(object, opt_options);\n };\n /**\n * @param {Object} object Object.\n * @protected\n * @return {import("../proj/Projection.js").default} Projection.\n */\n\n\n GeoJSON.prototype.readProjectionFromObject = function (object) {\n var crs = object[\'crs\'];\n var projection;\n\n if (crs) {\n if (crs[\'type\'] == \'name\') {\n projection = proj_get(crs[\'properties\'][\'name\']);\n } else if (crs[\'type\'] === \'EPSG\') {\n projection = proj_get(\'EPSG:\' + crs[\'properties\'][\'code\']);\n } else {\n asserts_assert(false, 36); // Unknown SRS type\n }\n } else {\n projection = this.dataProjection;\n }\n\n return (\n /** @type {import("../proj/Projection.js").default} */\n projection\n );\n };\n /**\n * Encode a feature as a GeoJSON Feature object.\n *\n * @param {import("../Feature.js").default} feature Feature.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONFeature} Object.\n * @api\n */\n\n\n GeoJSON.prototype.writeFeatureObject = function (feature, opt_options) {\n opt_options = this.adaptOptions(opt_options);\n /** @type {GeoJSONFeature} */\n\n var object = {\n \'type\': \'Feature\',\n geometry: null,\n properties: null\n };\n var id = feature.getId();\n\n if (id !== undefined) {\n object.id = id;\n }\n\n if (!feature.hasProperties()) {\n return object;\n }\n\n var properties = feature.getProperties();\n var geometry = feature.getGeometry();\n\n if (geometry) {\n object.geometry = writeGeometry(geometry, opt_options);\n delete properties[feature.getGeometryName()];\n }\n\n if (!obj_isEmpty(properties)) {\n object.properties = properties;\n }\n\n return object;\n };\n /**\n * Encode an array of features as a GeoJSON object.\n *\n * @param {Array<import("../Feature.js").default>} features Features.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONFeatureCollection} GeoJSON Object.\n * @api\n */\n\n\n GeoJSON.prototype.writeFeaturesObject = function (features, opt_options) {\n opt_options = this.adaptOptions(opt_options);\n var objects = [];\n\n for (var i = 0, ii = features.length; i < ii; ++i) {\n objects.push(this.writeFeatureObject(features[i], opt_options));\n }\n\n return {\n type: \'FeatureCollection\',\n features: objects\n };\n };\n /**\n * Encode a geometry as a GeoJSON object.\n *\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.\n * @api\n */\n\n\n GeoJSON.prototype.writeGeometryObject = function (geometry, opt_options) {\n return writeGeometry(geometry, this.adaptOptions(opt_options));\n };\n\n return GeoJSON;\n}(format_JSONFeature);\n/**\n * @param {GeoJSONGeometry|GeoJSONGeometryCollection} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {import("../geom/Geometry.js").default} Geometry.\n */\n\n\nfunction readGeometry(object, opt_options) {\n if (!object) {\n return null;\n }\n /**\n * @type {import("../geom/Geometry.js").default}\n */\n\n\n var geometry;\n\n switch (object[\'type\']) {\n case geom_GeometryType.POINT:\n {\n geometry = readPointGeometry(\n /** @type {GeoJSONPoint} */\n object);\n break;\n }\n\n case geom_GeometryType.LINE_STRING:\n {\n geometry = readLineStringGeometry(\n /** @type {GeoJSONLineString} */\n object);\n break;\n }\n\n case geom_GeometryType.POLYGON:\n {\n geometry = readPolygonGeometry(\n /** @type {GeoJSONPolygon} */\n object);\n break;\n }\n\n case geom_GeometryType.MULTI_POINT:\n {\n geometry = readMultiPointGeometry(\n /** @type {GeoJSONMultiPoint} */\n object);\n break;\n }\n\n case geom_GeometryType.MULTI_LINE_STRING:\n {\n geometry = readMultiLineStringGeometry(\n /** @type {GeoJSONMultiLineString} */\n object);\n break;\n }\n\n case geom_GeometryType.MULTI_POLYGON:\n {\n geometry = readMultiPolygonGeometry(\n /** @type {GeoJSONMultiPolygon} */\n object);\n break;\n }\n\n case geom_GeometryType.GEOMETRY_COLLECTION:\n {\n geometry = readGeometryCollectionGeometry(\n /** @type {GeoJSONGeometryCollection} */\n object);\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported GeoJSON type: \' + object.type);\n }\n }\n\n return transformGeometryWithOptions(geometry, false, opt_options);\n}\n/**\n * @param {GeoJSONGeometryCollection} object Object.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {GeometryCollection} Geometry collection.\n */\n\n\nfunction readGeometryCollectionGeometry(object, opt_options) {\n var geometries = object[\'geometries\'].map(\n /**\n * @param {GeoJSONGeometry} geometry Geometry.\n * @return {import("../geom/Geometry.js").default} geometry Geometry.\n */\n function (geometry) {\n return readGeometry(geometry, opt_options);\n });\n return new geom_GeometryCollection(geometries);\n}\n/**\n * @param {GeoJSONPoint} object Object.\n * @return {Point} Point.\n */\n\n\nfunction readPointGeometry(object) {\n return new geom_Point(object[\'coordinates\']);\n}\n/**\n * @param {GeoJSONLineString} object Object.\n * @return {LineString} LineString.\n */\n\n\nfunction readLineStringGeometry(object) {\n return new geom_LineString(object[\'coordinates\']);\n}\n/**\n * @param {GeoJSONMultiLineString} object Object.\n * @return {MultiLineString} MultiLineString.\n */\n\n\nfunction readMultiLineStringGeometry(object) {\n return new geom_MultiLineString(object[\'coordinates\']);\n}\n/**\n * @param {GeoJSONMultiPoint} object Object.\n * @return {MultiPoint} MultiPoint.\n */\n\n\nfunction readMultiPointGeometry(object) {\n return new geom_MultiPoint(object[\'coordinates\']);\n}\n/**\n * @param {GeoJSONMultiPolygon} object Object.\n * @return {MultiPolygon} MultiPolygon.\n */\n\n\nfunction readMultiPolygonGeometry(object) {\n return new geom_MultiPolygon(object[\'coordinates\']);\n}\n/**\n * @param {GeoJSONPolygon} object Object.\n * @return {Polygon} Polygon.\n */\n\n\nfunction readPolygonGeometry(object) {\n return new geom_Polygon(object[\'coordinates\']);\n}\n/**\n * @param {import("../geom/Geometry.js").default} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writeGeometry(geometry, opt_options) {\n geometry = transformGeometryWithOptions(geometry, true, opt_options);\n var type = geometry.getType();\n /** @type {GeoJSONGeometry} */\n\n var geoJSON;\n\n switch (type) {\n case geom_GeometryType.POINT:\n {\n geoJSON = writePointGeometry(\n /** @type {Point} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.LINE_STRING:\n {\n geoJSON = writeLineStringGeometry(\n /** @type {LineString} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.POLYGON:\n {\n geoJSON = writePolygonGeometry(\n /** @type {Polygon} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.MULTI_POINT:\n {\n geoJSON = writeMultiPointGeometry(\n /** @type {MultiPoint} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.MULTI_LINE_STRING:\n {\n geoJSON = writeMultiLineStringGeometry(\n /** @type {MultiLineString} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.MULTI_POLYGON:\n {\n geoJSON = writeMultiPolygonGeometry(\n /** @type {MultiPolygon} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.GEOMETRY_COLLECTION:\n {\n geoJSON = writeGeometryCollectionGeometry(\n /** @type {GeometryCollection} */\n geometry, opt_options);\n break;\n }\n\n case geom_GeometryType.CIRCLE:\n {\n geoJSON = {\n type: \'GeometryCollection\',\n geometries: []\n };\n break;\n }\n\n default:\n {\n throw new Error(\'Unsupported geometry type: \' + type);\n }\n }\n\n return geoJSON;\n}\n/**\n * @param {GeometryCollection} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometryCollection} GeoJSON geometry collection.\n */\n\n\nfunction writeGeometryCollectionGeometry(geometry, opt_options) {\n var geometries = geometry.getGeometriesArray().map(function (geometry) {\n var options = obj_assign({}, opt_options);\n delete options.featureProjection;\n return writeGeometry(geometry, options);\n });\n return {\n type: \'GeometryCollection\',\n geometries: geometries\n };\n}\n/**\n * @param {LineString} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writeLineStringGeometry(geometry, opt_options) {\n return {\n type: \'LineString\',\n coordinates: geometry.getCoordinates()\n };\n}\n/**\n * @param {MultiLineString} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writeMultiLineStringGeometry(geometry, opt_options) {\n return {\n type: \'MultiLineString\',\n coordinates: geometry.getCoordinates()\n };\n}\n/**\n * @param {MultiPoint} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writeMultiPointGeometry(geometry, opt_options) {\n return {\n type: \'MultiPoint\',\n coordinates: geometry.getCoordinates()\n };\n}\n/**\n * @param {MultiPolygon} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writeMultiPolygonGeometry(geometry, opt_options) {\n var right;\n\n if (opt_options) {\n right = opt_options.rightHanded;\n }\n\n return {\n type: \'MultiPolygon\',\n coordinates: geometry.getCoordinates(right)\n };\n}\n/**\n * @param {Point} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writePointGeometry(geometry, opt_options) {\n return {\n type: \'Point\',\n coordinates: geometry.getCoordinates()\n };\n}\n/**\n * @param {Polygon} geometry Geometry.\n * @param {import("./Feature.js").WriteOptions=} opt_options Write options.\n * @return {GeoJSONGeometry} GeoJSON geometry.\n */\n\n\nfunction writePolygonGeometry(geometry, opt_options) {\n var right;\n\n if (opt_options) {\n right = opt_options.rightHanded;\n }\n\n return {\n type: \'Polygon\',\n coordinates: geometry.getCoordinates(right)\n };\n}\n\n/* harmony default export */ var format_GeoJSON = (GeoJSON);\n// EXTERNAL MODULE: ./node_modules/pbf/index.js\nvar node_modules_pbf = __webpack_require__(4362);\nvar pbf_default = /*#__PURE__*/__webpack_require__.n(node_modules_pbf);\n;// CONCATENATED MODULE: ./node_modules/ol/format/MVT.js\n/**\n * @module ol/format/MVT\n */\n//FIXME Implement projection handling\nvar MVT_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("../Feature.js").FeatureClass} [featureClass] Class for features returned by\n * {@link module:ol/format/MVT#readFeatures}. Set to {@link module:ol/Feature~Feature} to get full editing and geometry\n * support at the cost of decreased rendering performance. The default is\n * {@link module:ol/render/Feature~RenderFeature}, which is optimized for rendering and hit detection.\n * @property {string} [geometryName=\'geometry\'] Geometry name to use when creating features.\n * @property {string} [layerName=\'layer\'] Name of the feature attribute that holds the layer name.\n * @property {Array<string>} [layers] Layers to read features from. If not provided, features will be read from all\n * @property {string} [idProperty] Optional property that will be assigned as the feature id and removed from the properties.\n * layers.\n */\n\n/**\n * @classdesc\n * Feature format for reading data in the Mapbox MVT format.\n *\n * @param {Options=} opt_options Options.\n * @api\n */\n\nvar MVT =\n/** @class */\nfunction (_super) {\n MVT_extends(MVT, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function MVT(opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {Projection}\n */\n\n _this.dataProjection = new proj_Projection({\n code: \'\',\n units: proj_Units.TILE_PIXELS\n });\n /**\n * @private\n * @type {import("../Feature.js").FeatureClass}\n */\n\n _this.featureClass_ = options.featureClass ? options.featureClass : Feature;\n /**\n * @private\n * @type {string|undefined}\n */\n\n _this.geometryName_ = options.geometryName;\n /**\n * @private\n * @type {string}\n */\n\n _this.layerName_ = options.layerName ? options.layerName : \'layer\';\n /**\n * @private\n * @type {Array<string>}\n */\n\n _this.layers_ = options.layers ? options.layers : null;\n /**\n * @private\n * @type {string}\n */\n\n _this.idProperty_ = options.idProperty;\n return _this;\n }\n /**\n * Read the raw geometry from the pbf offset stored in a raw feature\'s geometry\n * property.\n * @param {PBF} pbf PBF.\n * @param {Object} feature Raw feature.\n * @param {Array<number>} flatCoordinates Array to store flat coordinates in.\n * @param {Array<number>} ends Array to store ends in.\n * @private\n */\n\n\n MVT.prototype.readRawGeometry_ = function (pbf, feature, flatCoordinates, ends) {\n pbf.pos = feature.geometry;\n var end = pbf.readVarint() + pbf.pos;\n var cmd = 1;\n var length = 0;\n var x = 0;\n var y = 0;\n var coordsLen = 0;\n var currentEnd = 0;\n\n while (pbf.pos < end) {\n if (!length) {\n var cmdLen = pbf.readVarint();\n cmd = cmdLen & 0x7;\n length = cmdLen >> 3;\n }\n\n length--;\n\n if (cmd === 1 || cmd === 2) {\n x += pbf.readSVarint();\n y += pbf.readSVarint();\n\n if (cmd === 1) {\n // moveTo\n if (coordsLen > currentEnd) {\n ends.push(coordsLen);\n currentEnd = coordsLen;\n }\n }\n\n flatCoordinates.push(x, y);\n coordsLen += 2;\n } else if (cmd === 7) {\n if (coordsLen > currentEnd) {\n // close polygon\n flatCoordinates.push(flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);\n coordsLen += 2;\n }\n } else {\n asserts_assert(false, 59); // Invalid command found in the PBF\n }\n }\n\n if (coordsLen > currentEnd) {\n ends.push(coordsLen);\n currentEnd = coordsLen;\n }\n };\n /**\n * @private\n * @param {PBF} pbf PBF\n * @param {Object} rawFeature Raw Mapbox feature.\n * @param {import("./Feature.js").ReadOptions} options Read options.\n * @return {import("../Feature.js").FeatureLike} Feature.\n */\n\n\n MVT.prototype.createFeature_ = function (pbf, rawFeature, options) {\n var type = rawFeature.type;\n\n if (type === 0) {\n return null;\n }\n\n var feature;\n var values = rawFeature.properties;\n var id;\n\n if (!this.idProperty_) {\n id = rawFeature.id;\n } else {\n id = values[this.idProperty_];\n delete values[this.idProperty_];\n }\n\n values[this.layerName_] = rawFeature.layer.name;\n var flatCoordinates = [];\n var ends = [];\n this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);\n var geometryType = getGeometryType(type, ends.length);\n\n if (this.featureClass_ === Feature) {\n feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);\n feature.transform(options.dataProjection);\n } else {\n var geom = void 0;\n\n if (geometryType == geom_GeometryType.POLYGON) {\n var endss = [];\n var offset = 0;\n var prevEndIndex = 0;\n\n for (var i = 0, ii = ends.length; i < ii; ++i) {\n var end = ends[i]; // classifies an array of rings into polygons with outer rings and holes\n\n if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {\n endss.push(ends.slice(prevEndIndex, i + 1));\n } else {\n if (endss.length === 0) {\n continue;\n }\n\n endss[endss.length - 1].push(ends[prevEndIndex]);\n }\n\n prevEndIndex = i + 1;\n offset = end;\n }\n\n if (endss.length > 1) {\n geom = new geom_MultiPolygon(flatCoordinates, geom_GeometryLayout.XY, endss);\n } else {\n geom = new geom_Polygon(flatCoordinates, geom_GeometryLayout.XY, ends);\n }\n } else {\n geom = geometryType === geom_GeometryType.POINT ? new geom_Point(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.LINE_STRING ? new geom_LineString(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.POLYGON ? new geom_Polygon(flatCoordinates, geom_GeometryLayout.XY, ends) : geometryType === geom_GeometryType.MULTI_POINT ? new geom_MultiPoint(flatCoordinates, geom_GeometryLayout.XY) : geometryType === geom_GeometryType.MULTI_LINE_STRING ? new geom_MultiLineString(flatCoordinates, geom_GeometryLayout.XY, ends) : null;\n }\n\n var ctor =\n /** @type {typeof import("../Feature.js").default} */\n this.featureClass_;\n feature = new ctor();\n\n if (this.geometryName_) {\n feature.setGeometryName(this.geometryName_);\n }\n\n var geometry = transformGeometryWithOptions(geom, false, options);\n feature.setGeometry(geometry);\n feature.setId(id);\n feature.setProperties(values, true);\n }\n\n return feature;\n };\n /**\n * @return {import("./FormatType.js").default} Format.\n */\n\n\n MVT.prototype.getType = function () {\n return FormatType.ARRAY_BUFFER;\n };\n /**\n * Read all features.\n *\n * @param {ArrayBuffer} source Source.\n * @param {import("./Feature.js").ReadOptions=} opt_options Read options.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n MVT.prototype.readFeatures = function (source, opt_options) {\n var layers = this.layers_;\n var options =\n /** @type {import("./Feature.js").ReadOptions} */\n this.adaptOptions(opt_options);\n var dataProjection = proj_get(options.dataProjection);\n dataProjection.setWorldExtent(options.extent);\n options.dataProjection = dataProjection;\n var pbf = new (pbf_default())(\n /** @type {ArrayBuffer} */\n source);\n var pbfLayers = pbf.readFields(layersPBFReader, {});\n var features = [];\n\n for (var name_1 in pbfLayers) {\n if (layers && layers.indexOf(name_1) == -1) {\n continue;\n }\n\n var pbfLayer = pbfLayers[name_1];\n var extent = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;\n dataProjection.setExtent(extent);\n\n for (var i = 0, ii = pbfLayer.length; i < ii; ++i) {\n var rawFeature = readRawFeature(pbf, pbfLayer, i);\n features.push(this.createFeature_(pbf, rawFeature, options));\n }\n }\n\n return features;\n };\n /**\n * Read the projection from the source.\n *\n * @param {Document|Element|Object|string} source Source.\n * @return {import("../proj/Projection.js").default} Projection.\n * @api\n */\n\n\n MVT.prototype.readProjection = function (source) {\n return this.dataProjection;\n };\n /**\n * Sets the layers that features will be read from.\n * @param {Array<string>} layers Layers.\n * @api\n */\n\n\n MVT.prototype.setLayers = function (layers) {\n this.layers_ = layers;\n };\n\n return MVT;\n}(format_Feature);\n/**\n * Reader callback for parsing layers.\n * @param {number} tag The tag.\n * @param {Object} layers The layers object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction layersPBFReader(tag, layers, pbf) {\n if (tag === 3) {\n var layer = {\n keys: [],\n values: [],\n features: []\n };\n var end = pbf.readVarint() + pbf.pos;\n pbf.readFields(layerPBFReader, layer, end);\n layer.length = layer.features.length;\n\n if (layer.length) {\n layers[layer.name] = layer;\n }\n }\n}\n/**\n * Reader callback for parsing layer.\n * @param {number} tag The tag.\n * @param {Object} layer The layer object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction layerPBFReader(tag, layer, pbf) {\n if (tag === 15) {\n layer.version = pbf.readVarint();\n } else if (tag === 1) {\n layer.name = pbf.readString();\n } else if (tag === 5) {\n layer.extent = pbf.readVarint();\n } else if (tag === 2) {\n layer.features.push(pbf.pos);\n } else if (tag === 3) {\n layer.keys.push(pbf.readString());\n } else if (tag === 4) {\n var value = null;\n var end = pbf.readVarint() + pbf.pos;\n\n while (pbf.pos < end) {\n tag = pbf.readVarint() >> 3;\n value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null;\n }\n\n layer.values.push(value);\n }\n}\n/**\n * Reader callback for parsing feature.\n * @param {number} tag The tag.\n * @param {Object} feature The feature object.\n * @param {PBF} pbf The PBF.\n */\n\n\nfunction featurePBFReader(tag, feature, pbf) {\n if (tag == 1) {\n feature.id = pbf.readVarint();\n } else if (tag == 2) {\n var end = pbf.readVarint() + pbf.pos;\n\n while (pbf.pos < end) {\n var key = feature.layer.keys[pbf.readVarint()];\n var value = feature.layer.values[pbf.readVarint()];\n feature.properties[key] = value;\n }\n } else if (tag == 3) {\n feature.type = pbf.readVarint();\n } else if (tag == 4) {\n feature.geometry = pbf.pos;\n }\n}\n/**\n * Read a raw feature from the pbf offset stored at index `i` in the raw layer.\n * @param {PBF} pbf PBF.\n * @param {Object} layer Raw layer.\n * @param {number} i Index of the feature in the raw layer\'s `features` array.\n * @return {Object} Raw feature.\n */\n\n\nfunction readRawFeature(pbf, layer, i) {\n pbf.pos = layer.features[i];\n var end = pbf.readVarint() + pbf.pos;\n var feature = {\n layer: layer,\n type: 0,\n properties: {}\n };\n pbf.readFields(featurePBFReader, feature, end);\n return feature;\n}\n/**\n * @param {number} type The raw feature\'s geometry type\n * @param {number} numEnds Number of ends of the flat coordinates of the\n * geometry.\n * @return {import("../geom/GeometryType.js").default} The geometry type.\n */\n\n\nfunction getGeometryType(type, numEnds) {\n /** @type {import("../geom/GeometryType.js").default} */\n var geometryType;\n\n if (type === 1) {\n geometryType = numEnds === 1 ? geom_GeometryType.POINT : geom_GeometryType.MULTI_POINT;\n } else if (type === 2) {\n geometryType = numEnds === 1 ? geom_GeometryType.LINE_STRING : geom_GeometryType.MULTI_LINE_STRING;\n } else if (type === 3) {\n geometryType = geom_GeometryType.POLYGON; // MultiPolygon not relevant for rendering - winding order determines\n // outer rings of polygons.\n }\n\n return geometryType;\n}\n\n/* harmony default export */ var format_MVT = (MVT);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/TileProperty.js\n/**\n * @module ol/layer/TileProperty\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var TileProperty = ({\n PRELOAD: \'preload\',\n USE_INTERIM_TILES_ON_ERROR: \'useInterimTilesOnError\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/layer/BaseTile.js\nvar BaseTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/BaseTile\n */\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {import("../source/Tile.js").default} [source] Source for this layer.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @extends {Layer<import("../source/Tile.js").default>}\n * @api\n */\n\nvar BaseTileLayer =\n/** @class */\nfunction (_super) {\n BaseTile_extends(BaseTileLayer, _super);\n /**\n * @param {Options=} opt_options Tile layer options.\n */\n\n\n function BaseTileLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions = obj_assign({}, options);\n delete baseOptions.preload;\n delete baseOptions.useInterimTilesOnError;\n _this = _super.call(this, baseOptions) || this;\n\n _this.setPreload(options.preload !== undefined ? options.preload : 0);\n\n _this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ? options.useInterimTilesOnError : true);\n\n return _this;\n }\n /**\n * Return the level as number to which we will preload tiles up to.\n * @return {number} The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.getPreload = function () {\n return (\n /** @type {number} */\n this.get(TileProperty.PRELOAD)\n );\n };\n /**\n * Set the level as number to which we will preload tiles up to.\n * @param {number} preload The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.setPreload = function (preload) {\n this.set(TileProperty.PRELOAD, preload);\n };\n /**\n * Whether we use interim tiles on error.\n * @return {boolean} Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.getUseInterimTilesOnError = function () {\n return (\n /** @type {boolean} */\n this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR)\n );\n };\n /**\n * Set whether we use interim tiles on error.\n * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n BaseTileLayer.prototype.setUseInterimTilesOnError = function (useInterimTilesOnError) {\n this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n };\n\n return BaseTileLayer;\n}(layer_Layer);\n\n/* harmony default export */ var BaseTile = (BaseTileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/TileLayer.js\nvar TileLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/TileLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @classdesc\n * Canvas renderer for tile layers.\n * @api\n */\n\nvar CanvasTileLayerRenderer =\n/** @class */\nfunction (_super) {\n TileLayer_extends(CanvasTileLayerRenderer, _super);\n /**\n * @param {import("../../layer/Tile.js").default|import("../../layer/VectorTile.js").default} tileLayer Tile layer.\n */\n\n\n function CanvasTileLayerRenderer(tileLayer) {\n var _this = _super.call(this, tileLayer) || this;\n /**\n * Rendered extent has changed since the previous `renderFrame()` call\n * @type {boolean}\n */\n\n\n _this.extentChanged = true;\n /**\n * @private\n * @type {?import("../../extent.js").Extent}\n */\n\n _this.renderedExtent_ = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedPixelRatio;\n /**\n * @protected\n * @type {import("../../proj/Projection.js").default}\n */\n\n _this.renderedProjection = null;\n /**\n * @protected\n * @type {number}\n */\n\n _this.renderedRevision;\n /**\n * @protected\n * @type {!Array<import("../../Tile.js").default>}\n */\n\n _this.renderedTiles = [];\n /**\n * @private\n * @type {boolean}\n */\n\n _this.newTiles_ = false;\n /**\n * @protected\n * @type {import("../../extent.js").Extent}\n */\n\n _this.tmpExtent = createEmpty();\n /**\n * @private\n * @type {import("../../TileRange.js").default}\n */\n\n _this.tmpTileRange_ = new ol_TileRange(0, 0, 0, 0);\n return _this;\n }\n /**\n * @protected\n * @param {import("../../Tile.js").default} tile Tile.\n * @return {boolean} Tile is drawable.\n */\n\n\n CanvasTileLayerRenderer.prototype.isDrawableTile = function (tile) {\n var tileLayer = this.getLayer();\n var tileState = tile.getState();\n var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();\n return tileState == TileState.LOADED || tileState == TileState.EMPTY || tileState == TileState.ERROR && !useInterimTilesOnError;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {!import("../../Tile.js").default} Tile.\n */\n\n\n CanvasTileLayerRenderer.prototype.getTile = function (z, x, y, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var projection = frameState.viewState.projection;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() == TileState.ERROR) {\n if (!tileLayer.getUseInterimTilesOnError()) {\n // When useInterimTilesOnError is false, we consider the error tile as loaded.\n tile.setState(TileState.LOADED);\n } else if (tileLayer.getPreload() > 0) {\n // Preloaded tiles for lower resolutions might have finished loading.\n this.newTiles_ = true;\n }\n }\n\n if (!this.isDrawableTile(tile)) {\n tile = tile.getInterimTile();\n }\n\n return tile;\n };\n /**\n * @param {Object<number, Object<string, import("../../Tile.js").default>>} tiles Lookup of loaded tiles by zoom level.\n * @param {number} zoom Zoom level.\n * @param {import("../../Tile.js").default} tile Tile.\n * @return {boolean|void} If `false`, the tile will not be considered loaded.\n */\n\n\n CanvasTileLayerRenderer.prototype.loadedTileCallback = function (tiles, zoom, tile) {\n if (this.isDrawableTile(tile)) {\n return _super.prototype.loadedTileCallback.call(this, tiles, zoom, tile);\n }\n\n return false;\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasTileLayerRenderer.prototype.prepareFrame = function (frameState) {\n return !!this.getLayer().getSource();\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasTileLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var layerState = frameState.layerStatesArray[frameState.layerIndex];\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var viewResolution = viewState.resolution;\n var viewCenter = viewState.center;\n var rotation = viewState.rotation;\n var pixelRatio = frameState.pixelRatio;\n var tileLayer = this.getLayer();\n var tileSource = tileLayer.getSource();\n var sourceRevision = tileSource.getRevision();\n var tileGrid = tileSource.getTileGridForProjection(projection);\n var z = tileGrid.getZForResolution(viewResolution, tileSource.zDirection);\n var tileResolution = tileGrid.getResolution(z);\n var extent = frameState.extent;\n var layerExtent = layerState.extent && fromUserExtent(layerState.extent, projection);\n\n if (layerExtent) {\n extent = getIntersection(extent, fromUserExtent(layerState.extent, projection));\n }\n\n var tilePixelRatio = tileSource.getTilePixelRatio(pixelRatio); // desired dimensions of the canvas in pixels\n\n var width = Math.round(frameState.size[0] * tilePixelRatio);\n var height = Math.round(frameState.size[1] * tilePixelRatio);\n\n if (rotation) {\n var size = Math.round(Math.sqrt(width * width + height * height));\n width = size;\n height = size;\n }\n\n var dx = tileResolution * width / 2 / tilePixelRatio;\n var dy = tileResolution * height / 2 / tilePixelRatio;\n var canvasExtent = [viewCenter[0] - dx, viewCenter[1] - dy, viewCenter[0] + dx, viewCenter[1] + dy];\n var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);\n /**\n * @type {Object<number, Object<string, import("../../Tile.js").default>>}\n */\n\n var tilesToDrawByZ = {};\n tilesToDrawByZ[z] = {};\n var findLoadedTiles = this.createLoadedTileFinder(tileSource, projection, tilesToDrawByZ);\n var tmpExtent = this.tmpExtent;\n var tmpTileRange = this.tmpTileRange_;\n this.newTiles_ = false;\n\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n var tile = this.getTile(z, x, y, frameState);\n\n if (this.isDrawableTile(tile)) {\n var uid = getUid(this);\n\n if (tile.getState() == TileState.LOADED) {\n tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;\n var inTransition = tile.inTransition(uid);\n\n if (!this.newTiles_ && (inTransition || this.renderedTiles.indexOf(tile) === -1)) {\n this.newTiles_ = true;\n }\n }\n\n if (tile.getAlpha(uid, frameState.time) === 1) {\n // don\'t look for alt tiles if alpha is 1\n continue;\n }\n }\n\n var childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord, tmpTileRange, tmpExtent);\n var covered = false;\n\n if (childTileRange) {\n covered = findLoadedTiles(z + 1, childTileRange);\n }\n\n if (!covered) {\n tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles, tmpTileRange, tmpExtent);\n }\n }\n }\n\n var canvasScale = tileResolution / viewResolution; // set forward and inverse pixel transforms\n\n compose(this.pixelTransform, frameState.size[0] / 2, frameState.size[1] / 2, 1 / tilePixelRatio, 1 / tilePixelRatio, rotation, -width / 2, -height / 2);\n var canvasTransform = createTransformString(this.pixelTransform);\n this.useContainer(target, canvasTransform, layerState.opacity);\n var context = this.context;\n var canvas = context.canvas;\n makeInverse(this.inversePixelTransform, this.pixelTransform); // set scale transform for calculating tile positions on the canvas\n\n compose(this.tempTransform, width / 2, height / 2, canvasScale, canvasScale, 0, -width / 2, -height / 2);\n\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n } else if (!this.containerReused) {\n context.clearRect(0, 0, width, height);\n }\n\n if (layerExtent) {\n this.clipUnrotated(context, frameState, layerExtent);\n }\n\n obj_assign(context, tileSource.getContextOptions());\n this.preRender(context, frameState);\n this.renderedTiles.length = 0;\n /** @type {Array<number>} */\n\n var zs = Object.keys(tilesToDrawByZ).map(Number);\n zs.sort(numberSafeCompareFunction);\n var clips, clipZs, currentClip;\n\n if (layerState.opacity === 1 && (!this.containerReused || tileSource.getOpaque(frameState.viewState.projection))) {\n zs = zs.reverse();\n } else {\n clips = [];\n clipZs = [];\n }\n\n for (var i = zs.length - 1; i >= 0; --i) {\n var currentZ = zs[i];\n var currentTilePixelSize = tileSource.getTilePixelSize(currentZ, pixelRatio, projection);\n var currentResolution = tileGrid.getResolution(currentZ);\n var currentScale = currentResolution / tileResolution;\n var dx_1 = currentTilePixelSize[0] * currentScale * canvasScale;\n var dy_1 = currentTilePixelSize[1] * currentScale * canvasScale;\n var originTileCoord = tileGrid.getTileCoordForCoordAndZ(getTopLeft(canvasExtent), currentZ);\n var originTileExtent = tileGrid.getTileCoordExtent(originTileCoord);\n var origin_1 = apply(this.tempTransform, [tilePixelRatio * (originTileExtent[0] - canvasExtent[0]) / tileResolution, tilePixelRatio * (canvasExtent[3] - originTileExtent[3]) / tileResolution]);\n var tileGutter = tilePixelRatio * tileSource.getGutterForProjection(projection);\n var tilesToDraw = tilesToDrawByZ[currentZ];\n\n for (var tileCoordKey in tilesToDraw) {\n var tile =\n /** @type {import("../../ImageTile.js").default} */\n tilesToDraw[tileCoordKey];\n var tileCoord = tile.tileCoord; // Calculate integer positions and sizes so that tiles align\n\n var floatX = origin_1[0] - (originTileCoord[1] - tileCoord[1]) * dx_1;\n var nextX = Math.round(floatX + dx_1);\n var floatY = origin_1[1] - (originTileCoord[2] - tileCoord[2]) * dy_1;\n var nextY = Math.round(floatY + dy_1);\n var x = Math.round(floatX);\n var y = Math.round(floatY);\n var w = nextX - x;\n var h = nextY - y;\n var transition = z === currentZ;\n var inTransition = transition && tile.getAlpha(getUid(this), frameState.time) !== 1;\n\n if (!inTransition) {\n if (clips) {\n // Clip mask for regions in this tile that already filled by a higher z tile\n context.save();\n currentClip = [x, y, x + w, y, x + w, y + h, x, y + h];\n\n for (var i_1 = 0, ii = clips.length; i_1 < ii; ++i_1) {\n if (z !== currentZ && currentZ < clipZs[i_1]) {\n var clip = clips[i_1];\n context.beginPath(); // counter-clockwise (outer ring) for current tile\n\n context.moveTo(currentClip[0], currentClip[1]);\n context.lineTo(currentClip[2], currentClip[3]);\n context.lineTo(currentClip[4], currentClip[5]);\n context.lineTo(currentClip[6], currentClip[7]); // clockwise (inner ring) for higher z tile\n\n context.moveTo(clip[6], clip[7]);\n context.lineTo(clip[4], clip[5]);\n context.lineTo(clip[2], clip[3]);\n context.lineTo(clip[0], clip[1]);\n context.clip();\n }\n }\n\n clips.push(currentClip);\n clipZs.push(currentZ);\n } else {\n context.clearRect(x, y, w, h);\n }\n }\n\n this.drawTileImage(tile, frameState, x, y, w, h, tileGutter, transition, layerState.opacity);\n\n if (clips && !inTransition) {\n context.restore();\n }\n\n this.renderedTiles.push(tile);\n this.updateUsedTiles(frameState.usedTiles, tileSource, tile);\n }\n }\n\n this.renderedRevision = sourceRevision;\n this.renderedResolution = tileResolution;\n this.extentChanged = !this.renderedExtent_ || !extent_equals(this.renderedExtent_, canvasExtent);\n this.renderedExtent_ = canvasExtent;\n this.renderedPixelRatio = pixelRatio;\n this.renderedProjection = projection;\n this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio, projection, extent, z, tileLayer.getPreload());\n this.scheduleExpireCache(frameState, tileSource);\n this.postRender(context, frameState);\n\n if (layerState.extent) {\n context.restore();\n }\n\n if (canvasTransform !== canvas.style.transform) {\n canvas.style.transform = canvasTransform;\n }\n\n return this.container;\n };\n /**\n * @param {import("../../ImageTile.js").default} tile Tile.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} x Left of the tile.\n * @param {number} y Top of the tile.\n * @param {number} w Width of the tile.\n * @param {number} h Height of the tile.\n * @param {number} gutter Tile gutter.\n * @param {boolean} transition Apply an alpha transition.\n * @param {number} opacity Opacity.\n */\n\n\n CanvasTileLayerRenderer.prototype.drawTileImage = function (tile, frameState, x, y, w, h, gutter, transition, opacity) {\n var image = this.getTileImage(tile);\n\n if (!image) {\n return;\n }\n\n var uid = getUid(this);\n var tileAlpha = transition ? tile.getAlpha(uid, frameState.time) : 1;\n var alpha = opacity * tileAlpha;\n var alphaChanged = alpha !== this.context.globalAlpha;\n\n if (alphaChanged) {\n this.context.save();\n this.context.globalAlpha = alpha;\n }\n\n this.context.drawImage(image, gutter, gutter, image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);\n\n if (alphaChanged) {\n this.context.restore();\n }\n\n if (tileAlpha !== 1) {\n frameState.animate = true;\n } else if (transition) {\n tile.endTransition(uid);\n }\n };\n /**\n * @return {HTMLCanvasElement} Image\n */\n\n\n CanvasTileLayerRenderer.prototype.getImage = function () {\n var context = this.context;\n return context ? context.canvas : null;\n };\n /**\n * Get the image from a tile.\n * @param {import("../../ImageTile.js").default} tile Tile.\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.getTileImage = function (tile) {\n return tile.getImage();\n };\n /**\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.scheduleExpireCache = function (frameState, tileSource) {\n if (tileSource.canExpireCache()) {\n /**\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import("../../PluggableMap.js").default} map Map.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n var postRenderFunction = function (tileSource, map, frameState) {\n var tileSourceKey = getUid(tileSource);\n\n if (tileSourceKey in frameState.usedTiles) {\n tileSource.expireCache(frameState.viewState.projection, frameState.usedTiles[tileSourceKey]);\n }\n }.bind(null, tileSource);\n\n frameState.postRenderFunctions.push(\n /** @type {import("../../PluggableMap.js").PostRenderFunction} */\n postRenderFunction);\n }\n };\n /**\n * @param {!Object<string, !Object<string, boolean>>} usedTiles Used tiles.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import(\'../../Tile.js\').default} tile Tile.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.updateUsedTiles = function (usedTiles, tileSource, tile) {\n // FIXME should we use tilesToDrawByZ instead?\n var tileSourceKey = getUid(tileSource);\n\n if (!(tileSourceKey in usedTiles)) {\n usedTiles[tileSourceKey] = {};\n }\n\n usedTiles[tileSourceKey][tile.getKey()] = true;\n };\n /**\n * Manage tile pyramid.\n * This function performs a number of functions related to the tiles at the\n * current zoom and lower zoom levels:\n * - registers idle tiles in frameState.wantedTiles so that they are not\n * discarded by the tile queue\n * - enqueues missing tiles\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {import("../../source/Tile.js").default} tileSource Tile source.\n * @param {import("../../tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @param {import("../../extent.js").Extent} extent Extent.\n * @param {number} currentZ Current Z.\n * @param {number} preload Load low resolution tiles up to \'preload\' levels.\n * @param {function(import("../../Tile.js").default)=} opt_tileCallback Tile callback.\n * @protected\n */\n\n\n CanvasTileLayerRenderer.prototype.manageTilePyramid = function (frameState, tileSource, tileGrid, pixelRatio, projection, extent, currentZ, preload, opt_tileCallback) {\n var tileSourceKey = getUid(tileSource);\n\n if (!(tileSourceKey in frameState.wantedTiles)) {\n frameState.wantedTiles[tileSourceKey] = {};\n }\n\n var wantedTiles = frameState.wantedTiles[tileSourceKey];\n var tileQueue = frameState.tileQueue;\n var minZoom = tileGrid.getMinZoom();\n var tileCount = 0;\n var tile, tileRange, tileResolution, x, y, z;\n\n for (z = minZoom; z <= currentZ; ++z) {\n tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z, tileRange);\n tileResolution = tileGrid.getResolution(z);\n\n for (x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (y = tileRange.minY; y <= tileRange.maxY; ++y) {\n if (currentZ - z <= preload) {\n ++tileCount;\n tile = tileSource.getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() == TileState.IDLE) {\n wantedTiles[tile.getKey()] = true;\n\n if (!tileQueue.isKeyQueued(tile.getKey())) {\n tileQueue.enqueue([tile, tileSourceKey, tileGrid.getTileCoordCenter(tile.tileCoord), tileResolution]);\n }\n }\n\n if (opt_tileCallback !== undefined) {\n opt_tileCallback(tile);\n }\n } else {\n tileSource.useTile(z, x, y, projection);\n }\n }\n }\n }\n\n tileSource.updateCacheSize(tileCount, projection);\n };\n\n return CanvasTileLayerRenderer;\n}(canvas_Layer);\n/**\n * @function\n * @return {import("../../layer/Tile.js").default|import("../../layer/VectorTile.js").default}\n */\n\n\nCanvasTileLayerRenderer.prototype.getLayer;\n/* harmony default export */ var canvas_TileLayer = (CanvasTileLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/Tile.js\nvar Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/Tile\n */\n\n\n\n\n/**\n * @classdesc\n * For layer sources that provide pre-rendered, tiled images in grids that are\n * organized by zoom levels for specific resolutions.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @api\n */\n\nvar TileLayer =\n/** @class */\nfunction (_super) {\n Tile_extends(TileLayer, _super);\n /**\n * @param {import("./BaseTile.js").Options=} opt_options Tile layer options.\n */\n\n\n function TileLayer(opt_options) {\n return _super.call(this, opt_options) || this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n TileLayer.prototype.createRenderer = function () {\n return new canvas_TileLayer(this);\n };\n\n return TileLayer;\n}(BaseTile);\n\n/* harmony default export */ var Tile = (TileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/VectorTileRenderType.js\n/**\n * @module ol/layer/VectorTileRenderType\n */\n\n/**\n * @enum {string}\n * Render mode for vector tiles:\n * * `\'image\'`: Vector tiles are rendered as images. Great performance, but\n * point symbols and texts are always rotated with the view and pixels are\n * scaled during zoom animations.\n * * `\'hybrid\'`: Polygon and line elements are rendered as images, so pixels\n * are scaled during zoom animations. Point symbols and texts are accurately\n * rendered as vectors and can stay upright on rotated views.\n * * `\'vector\'`: Everything is rendered as vectors. Use this mode for improved\n * performance on vector tile layers with only a few rendered features (e.g.\n * for highlighting a subset of features of another layer with the same\n * source).\n * @api\n */\n/* harmony default export */ var VectorTileRenderType = ({\n IMAGE: \'image\',\n HYBRID: \'hybrid\',\n VECTOR: \'vector\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/renderer/canvas/VectorTileLayer.js\nvar VectorTileLayer_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/renderer/canvas/VectorTileLayer\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @type {!Object<string, Array<import("../../render/canvas/BuilderType.js").default>>}\n */\n\nvar IMAGE_REPLAYS = {\n \'image\': [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT],\n \'hybrid\': [BuilderType.POLYGON, BuilderType.LINE_STRING],\n \'vector\': []\n};\n/**\n * @type {!Object<string, Array<import("../../render/canvas/BuilderType.js").default>>}\n */\n\nvar VECTOR_REPLAYS = {\n \'image\': [BuilderType.DEFAULT],\n \'hybrid\': [BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT],\n \'vector\': [BuilderType.POLYGON, BuilderType.CIRCLE, BuilderType.LINE_STRING, BuilderType.IMAGE, BuilderType.TEXT, BuilderType.DEFAULT]\n};\n/**\n * @classdesc\n * Canvas renderer for vector tile layers.\n * @api\n */\n\nvar CanvasVectorTileLayerRenderer =\n/** @class */\nfunction (_super) {\n VectorTileLayer_extends(CanvasVectorTileLayerRenderer, _super);\n /**\n * @param {import("../../layer/VectorTile.js").default} layer VectorTile layer.\n */\n\n\n function CanvasVectorTileLayerRenderer(layer) {\n var _this = _super.call(this, layer) || this;\n /** @private */\n\n\n _this.boundHandleStyleImageChange_ = _this.handleStyleImageChange_.bind(_this);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.dirty_ = false;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedLayerRevision_;\n /**\n * @private\n * @type {import("../../transform").Transform}\n */\n\n _this.renderedPixelToCoordinateTransform_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.renderedRotation_;\n /**\n * @private\n * @type {!Object<string, import("../../VectorRenderTile.js").default>}\n */\n\n _this.renderTileImageQueue_ = {};\n /**\n * @type {Object<string, import("../../events.js").EventsKey>}\n */\n\n _this.tileListenerKeys_ = {};\n /**\n * @private\n * @type {import("../../transform.js").Transform}\n */\n\n _this.tmpTransform_ = create();\n return _this;\n }\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection").default} projection Projection.\n * @param {boolean} queue Queue tile for rendering.\n * @return {boolean|undefined} Tile needs to be rendered.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.prepareTile = function (tile, pixelRatio, projection, queue) {\n var render;\n var tileUid = getUid(tile);\n var state = tile.getState();\n\n if ((state === TileState.LOADED && tile.hifi || state === TileState.ERROR) && tileUid in this.tileListenerKeys_) {\n unlistenByKey(this.tileListenerKeys_[tileUid]);\n delete this.tileListenerKeys_[tileUid];\n }\n\n if (state === TileState.LOADED || state === TileState.ERROR) {\n this.updateExecutorGroup_(tile, pixelRatio, projection);\n\n if (this.tileImageNeedsRender_(tile, pixelRatio, projection)) {\n render = true;\n\n if (queue) {\n this.renderTileImageQueue_[tileUid] = tile;\n }\n }\n }\n\n return render;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {!import("../../Tile.js").default} Tile.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getTile = function (z, x, y, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var resolution = viewState.resolution;\n var projection = viewState.projection;\n var layer = this.getLayer();\n var tile = layer.getSource().getTile(z, x, y, pixelRatio, projection);\n\n if (tile.getState() < TileState.LOADED) {\n tile.wantedResolution = resolution;\n var tileUid = getUid(tile);\n\n if (!(tileUid in this.tileListenerKeys_)) {\n var listenerKey = listen(tile, EventType.CHANGE, this.prepareTile.bind(this, tile, pixelRatio, projection, true));\n this.tileListenerKeys_[tileUid] = listenerKey;\n }\n } else {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n\n if (hifi || !tile.wantedResolution) {\n tile.wantedResolution = resolution;\n }\n\n var render = this.prepareTile(tile, pixelRatio, projection, false);\n\n if (render && layer.getRenderMode() !== VectorTileRenderType.VECTOR) {\n this.renderTileImage_(tile, frameState);\n }\n }\n\n return _super.prototype.getTile.call(this, z, x, y, frameState);\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @return {boolean} Tile is drawable.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.isDrawableTile = function (tile) {\n var layer = this.getLayer();\n return _super.prototype.isDrawableTile.call(this, tile) && (layer.getRenderMode() === VectorTileRenderType.VECTOR ? getUid(layer) in tile.executorGroups : tile.hasContext(layer));\n };\n /**\n * @inheritDoc\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getTileImage = function (tile) {\n return tile.getImage(this.getLayer());\n };\n /**\n * Determine whether render should be called.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.prepareFrame = function (frameState) {\n var layerRevision = this.getLayer().getRevision();\n\n if (this.renderedLayerRevision_ != layerRevision) {\n this.renderedTiles.length = 0;\n }\n\n this.renderedLayerRevision_ = layerRevision;\n return _super.prototype.prepareFrame.call(this, frameState);\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.updateExecutorGroup_ = function (tile, pixelRatio, projection) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var revision = layer.getRevision();\n var renderOrder = layer.getRenderOrder() || null;\n var resolution = tile.wantedResolution;\n var builderState = tile.getReplayState(layer);\n\n if (!builderState.dirty && builderState.renderedResolution === resolution && builderState.renderedRevision == revision && builderState.renderedRenderOrder == renderOrder && builderState.renderedZ === tile.sourceZ) {\n return;\n }\n\n var source = layer.getSource();\n var declutter = layer.getDeclutter();\n var sourceTileGrid = source.getTileGrid();\n var tileGrid = source.getTileGridForProjection(projection);\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var sourceTiles = source.getSourceTiles(pixelRatio, projection, tile);\n var layerUid = getUid(layer);\n delete tile.hitDetectionImageData[layerUid];\n tile.executorGroups[layerUid] = [];\n\n if (declutter) {\n tile.declutterExecutorGroups[layerUid] = [];\n }\n\n var _loop_1 = function _loop_1(t, tt) {\n var sourceTile = sourceTiles[t];\n\n if (sourceTile.getState() != TileState.LOADED) {\n return "continue";\n }\n\n var sourceTileCoord = sourceTile.tileCoord;\n var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);\n var sharedExtent = getIntersection(tileExtent, sourceTileExtent);\n var bufferedExtent = extent_equals(sourceTileExtent, sharedExtent) ? null : buffer(sharedExtent, layer.getRenderBuffer() * resolution, this_1.tmpExtent);\n builderState.dirty = false;\n var builderGroup = new canvas_BuilderGroup(0, sharedExtent, resolution, pixelRatio);\n var declutterBuilderGroup = declutter ? new canvas_BuilderGroup(0, sharedExtent, resolution, pixelRatio) : undefined;\n var squaredTolerance = getSquaredTolerance(resolution, pixelRatio);\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @this {CanvasVectorTileLayerRenderer}\n */\n\n var render = function render(feature) {\n var styles;\n var styleFunction = feature.getStyleFunction() || layer.getStyleFunction();\n\n if (styleFunction) {\n styles = styleFunction(feature, resolution);\n }\n\n if (styles) {\n var dirty = this.renderFeature(feature, squaredTolerance, styles, builderGroup, declutterBuilderGroup);\n this.dirty_ = this.dirty_ || dirty;\n builderState.dirty = builderState.dirty || dirty;\n }\n };\n\n var features = sourceTile.getFeatures();\n\n if (renderOrder && renderOrder !== builderState.renderedRenderOrder) {\n features.sort(renderOrder);\n }\n\n for (var i = 0, ii = features.length; i < ii; ++i) {\n var feature = features[i];\n\n if (!bufferedExtent || intersects(bufferedExtent, feature.getGeometry().getExtent())) {\n render.call(this_1, feature);\n }\n }\n\n var executorGroupInstructions = builderGroup.finish(); // no need to clip when the render tile is covered by a single source tile\n\n var replayExtent = layer.getRenderMode() !== VectorTileRenderType.VECTOR && declutter && sourceTiles.length === 1 ? null : sharedExtent;\n var renderingReplayGroup = new canvas_ExecutorGroup(replayExtent, resolution, pixelRatio, source.getOverlaps(), executorGroupInstructions, layer.getRenderBuffer());\n tile.executorGroups[layerUid].push(renderingReplayGroup);\n\n if (declutterBuilderGroup) {\n var declutterExecutorGroup = new canvas_ExecutorGroup(replayExtent, resolution, pixelRatio, source.getOverlaps(), declutterBuilderGroup.finish(), layer.getRenderBuffer());\n tile.declutterExecutorGroups[layerUid].push(declutterExecutorGroup);\n }\n };\n\n var this_1 = this;\n\n for (var t = 0, tt = sourceTiles.length; t < tt; ++t) {\n _loop_1(t, tt);\n }\n\n builderState.renderedRevision = revision;\n builderState.renderedZ = tile.sourceZ;\n builderState.renderedRenderOrder = renderOrder;\n builderState.renderedResolution = resolution;\n };\n /**\n * @param {import("../../coordinate.js").Coordinate} coordinate Coordinate.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import("../vector.js").FeatureCallback<T>} callback Feature callback.\n * @param {Array<import("../Map.js").HitMatch<T>>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.forEachFeatureAtCoordinate = function (coordinate, frameState, hitTolerance, callback, matches) {\n var resolution = frameState.viewState.resolution;\n var rotation = frameState.viewState.rotation;\n hitTolerance = hitTolerance == undefined ? 0 : hitTolerance;\n var layer = this.getLayer();\n var source = layer.getSource();\n var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);\n var hitExtent = boundingExtent([coordinate]);\n buffer(hitExtent, resolution * hitTolerance, hitExtent);\n /** @type {!Object<string, import("../Map.js").HitMatch<T>|true>} */\n\n var features = {};\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {import("../../geom/SimpleGeometry.js").default} geometry Geometry.\n * @param {number} distanceSq The squared distance to the click position.\n * @return {T|undefined} Callback result.\n */\n\n var featureCallback = function featureCallback(feature, geometry, distanceSq) {\n var key = feature.getId();\n\n if (key === undefined) {\n key = getUid(feature);\n }\n\n var match = features[key];\n\n if (!match) {\n if (distanceSq === 0) {\n features[key] = true;\n return callback(feature, layer, geometry);\n }\n\n matches.push(features[key] = {\n feature: feature,\n layer: layer,\n geometry: geometry,\n distanceSq: distanceSq,\n callback: callback\n });\n } else if (match !== true && distanceSq < match.distanceSq) {\n if (distanceSq === 0) {\n features[key] = true;\n matches.splice(matches.lastIndexOf(match), 1);\n return callback(feature, layer, geometry);\n }\n\n match.geometry = geometry;\n match.distanceSq = distanceSq;\n }\n\n return undefined;\n };\n\n var renderedTiles =\n /** @type {Array<import("../../VectorRenderTile.js").default>} */\n this.renderedTiles;\n var found;\n\n var _loop_2 = function _loop_2(i, ii) {\n var tile = renderedTiles[i];\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n\n if (!intersects(tileExtent, hitExtent)) {\n return "continue";\n }\n\n var layerUid = getUid(layer);\n var executorGroups = [tile.executorGroups[layerUid]];\n var declutterExecutorGroups = tile.declutterExecutorGroups[layerUid];\n\n if (declutterExecutorGroups) {\n executorGroups.push(declutterExecutorGroups);\n }\n\n executorGroups.some(function (executorGroups) {\n var declutteredFeatures = executorGroups === declutterExecutorGroups ? frameState.declutterTree.all().map(function (item) {\n return item.value;\n }) : null;\n\n for (var t = 0, tt = executorGroups.length; t < tt; ++t) {\n var executorGroup = executorGroups[t];\n found = executorGroup.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, featureCallback, declutteredFeatures);\n\n if (found) {\n return true;\n }\n }\n });\n };\n\n for (var i = 0, ii = renderedTiles.length; !found && i < ii; ++i) {\n _loop_2(i, ii);\n }\n\n return found;\n };\n /**\n * Asynchronous layer level hit detection.\n * @param {import("../../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../../Feature").default>>} Promise that resolves with an array of features.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.getFeatures = function (pixel) {\n return new Promise(function (resolve, reject) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var layerUid = getUid(layer);\n var source = layer.getSource();\n var projection = this.renderedProjection;\n var projectionExtent = projection.getExtent();\n var resolution = this.renderedResolution;\n var tileGrid = source.getTileGridForProjection(projection);\n var coordinate = apply(this.renderedPixelToCoordinateTransform_, pixel.slice());\n var tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate, resolution);\n var tile;\n\n for (var i = 0, ii = this.renderedTiles.length; i < ii; ++i) {\n if (tileCoord.toString() === this.renderedTiles[i].tileCoord.toString()) {\n tile = this.renderedTiles[i];\n\n if (tile.getState() === TileState.LOADED && tile.hifi) {\n var extent_1 = tileGrid.getTileCoordExtent(tile.tileCoord);\n\n if (source.getWrapX() && projection.canWrapX() && !containsExtent(projectionExtent, extent_1)) {\n coordinate_wrapX(coordinate, projection);\n }\n\n break;\n }\n\n tile = undefined;\n }\n }\n\n if (!tile || tile.loadingSourceTiles > 0) {\n resolve([]);\n return;\n }\n\n var extent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var corner = getTopLeft(extent);\n var tilePixel = [(coordinate[0] - corner[0]) / resolution, (corner[1] - coordinate[1]) / resolution];\n var features = tile.getSourceTiles().reduce(function (accumulator, sourceTile) {\n return accumulator.concat(sourceTile.getFeatures());\n }, []);\n var hitDetectionImageData = tile.hitDetectionImageData[layerUid];\n\n if (!hitDetectionImageData && !this.animatingOrInteracting_) {\n var tileSize = toSize(tileGrid.getTileSize(tileGrid.getZForResolution(resolution)));\n var size = [tileSize[0] / 2, tileSize[1] / 2];\n var rotation = this.renderedRotation_;\n var transforms = [this.getRenderTransform(tileGrid.getTileCoordCenter(tile.wrappedTileCoord), resolution, 0, 0.5, size[0], size[1], 0)];\n hitDetectionImageData = createHitDetectionImageData(tileSize, transforms, features, layer.getStyleFunction(), tileGrid.getTileCoordExtent(tile.wrappedTileCoord), tile.getReplayState(layer).renderedResolution, rotation);\n tile.hitDetectionImageData[layerUid] = hitDetectionImageData;\n }\n\n resolve(hitDetect(tilePixel, features, hitDetectionImageData));\n }.bind(this));\n };\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.handleFontsChanged = function () {\n clear(this.renderTileImageQueue_);\n var layer = this.getLayer();\n\n if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {\n layer.changed();\n }\n };\n /**\n * Handle changes in image style state.\n * @param {import("../../events/Event.js").default} event Image style change event.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.handleStyleImageChange_ = function (event) {\n this.renderIfReadyAndVisible();\n };\n /**\n * Render declutter items for this layer\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderDeclutter = function (frameState) {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n var tiles =\n /** @type {Array<import("../../VectorRenderTile.js").default>} */\n this.renderedTiles;\n\n for (var i = 0, ii = tiles.length; i < ii; ++i) {\n var tile = tiles[i];\n var declutterExecutorGroups = tile.declutterExecutorGroups[getUid(this.getLayer())];\n\n if (declutterExecutorGroups) {\n for (var j = declutterExecutorGroups.length - 1; j >= 0; --j) {\n declutterExecutorGroups[j].execute(this.context, 1, this.getTileRenderTransform(tile, frameState), frameState.viewState.rotation, hifi, undefined, frameState.declutterTree);\n }\n }\n }\n };\n\n CanvasVectorTileLayerRenderer.prototype.getTileRenderTransform = function (tile, frameState) {\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var center = viewState.center;\n var resolution = viewState.resolution;\n var rotation = viewState.rotation;\n var size = frameState.size;\n var width = Math.round(size[0] * pixelRatio);\n var height = Math.round(size[1] * pixelRatio);\n var source = this.getLayer().getSource();\n var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);\n var tileCoord = tile.tileCoord;\n var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);\n var worldOffset = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent)[0] - tileExtent[0];\n var transform = multiply(scale(this.inversePixelTransform.slice(), 1 / pixelRatio, 1 / pixelRatio), this.getRenderTransform(center, resolution, rotation, pixelRatio, width, height, worldOffset));\n return transform;\n };\n /**\n * Render the layer.\n * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @return {HTMLElement} The rendered element.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderFrame = function (frameState, target) {\n var viewHints = frameState.viewHints;\n var hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);\n this.renderQueuedTileImages_(hifi, frameState);\n\n _super.prototype.renderFrame.call(this, frameState, target);\n\n this.renderedPixelToCoordinateTransform_ = frameState.pixelToCoordinateTransform.slice();\n this.renderedRotation_ = frameState.viewState.rotation;\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var renderMode = layer.getRenderMode();\n\n if (renderMode === VectorTileRenderType.IMAGE) {\n return this.container;\n }\n\n var source = layer.getSource(); // Unqueue tiles from the image queue when we don\'t need any more\n\n var usedTiles = frameState.usedTiles[getUid(source)];\n\n for (var tileUid in this.renderTileImageQueue_) {\n if (!usedTiles || !(tileUid in usedTiles)) {\n delete this.renderTileImageQueue_[tileUid];\n }\n }\n\n var context = this.context;\n var replayTypes = VECTOR_REPLAYS[renderMode];\n var viewState = frameState.viewState;\n var rotation = viewState.rotation;\n var tiles = this.renderedTiles;\n var clips = [];\n var clipZs = [];\n\n for (var i = tiles.length - 1; i >= 0; --i) {\n var tile =\n /** @type {import("../../VectorRenderTile.js").default} */\n tiles[i];\n var transform = this.getTileRenderTransform(tile, frameState);\n var executorGroups = tile.executorGroups[getUid(layer)];\n var clipped = false;\n\n for (var t = 0, tt = executorGroups.length; t < tt; ++t) {\n var executorGroup = executorGroups[t];\n\n if (!executorGroup.hasExecutors(replayTypes)) {\n // sourceTile has no instructions of the types we want to render\n continue;\n }\n\n var currentZ = tile.tileCoord[0];\n var currentClip = void 0;\n\n if (!clipped) {\n currentClip = executorGroup.getClipCoords(transform);\n\n if (currentClip) {\n context.save(); // Create a clip mask for regions in this low resolution tile that are\n // already filled by a higher resolution tile\n\n for (var j = 0, jj = clips.length; j < jj; ++j) {\n var clip = clips[j];\n\n if (currentZ < clipZs[j]) {\n context.beginPath(); // counter-clockwise (outer ring) for current tile\n\n context.moveTo(currentClip[0], currentClip[1]);\n context.lineTo(currentClip[2], currentClip[3]);\n context.lineTo(currentClip[4], currentClip[5]);\n context.lineTo(currentClip[6], currentClip[7]); // clockwise (inner ring) for higher resolution tile\n\n context.moveTo(clip[6], clip[7]);\n context.lineTo(clip[4], clip[5]);\n context.lineTo(clip[2], clip[3]);\n context.lineTo(clip[0], clip[1]);\n context.clip();\n }\n }\n }\n }\n\n executorGroup.execute(context, 1, transform, rotation, hifi, replayTypes);\n\n if (!clipped && currentClip) {\n context.restore();\n clips.push(currentClip);\n clipZs.push(currentZ);\n clipped = true;\n }\n }\n }\n\n return this.container;\n };\n /**\n * @param {boolean} hifi We have time to render a high fidelity map image.\n * @param {import(\'../../PluggableMap.js\').FrameState} frameState Frame state.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderQueuedTileImages_ = function (hifi, frameState) {\n // When we don\'t have time to render hifi, only render tiles until we have used up\n // half of the frame budget of 16 ms\n for (var uid in this.renderTileImageQueue_) {\n if (!hifi && Date.now() - frameState.time > 8) {\n frameState.animate = true;\n break;\n }\n\n var tile = this.renderTileImageQueue_[uid];\n delete this.renderTileImageQueue_[uid];\n this.renderTileImage_(tile, frameState);\n }\n };\n /**\n * @param {import("../../Feature.js").FeatureLike} feature Feature.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.\n * @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Replay group.\n * @param {import("../../render/canvas/BuilderGroup.js").default=} opt_declutterBuilderGroup Builder group for decluttering.\n * @return {boolean} `true` if an image is loading.\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderFeature = function (feature, squaredTolerance, styles, builderGroup, opt_declutterBuilderGroup) {\n if (!styles) {\n return false;\n }\n\n var loading = false;\n\n if (Array.isArray(styles)) {\n for (var i = 0, ii = styles.length; i < ii; ++i) {\n loading = renderFeature(builderGroup, feature, styles[i], squaredTolerance, this.boundHandleStyleImageChange_, undefined, opt_declutterBuilderGroup) || loading;\n }\n } else {\n loading = renderFeature(builderGroup, feature, styles, squaredTolerance, this.boundHandleStyleImageChange_, undefined, opt_declutterBuilderGroup);\n }\n\n return loading;\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../../proj/Projection.js").default} projection Projection.\n * @return {boolean} A new tile image was rendered.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.tileImageNeedsRender_ = function (tile, pixelRatio, projection) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var replayState = tile.getReplayState(layer);\n var revision = layer.getRevision();\n var sourceZ = tile.sourceZ;\n var resolution = tile.wantedResolution;\n return replayState.renderedTileResolution !== resolution || replayState.renderedTileRevision !== revision || replayState.renderedTileZ !== sourceZ;\n };\n /**\n * @param {import("../../VectorRenderTile.js").default} tile Tile.\n * @param {import("../../PluggableMap").FrameState} frameState Frame state.\n * @private\n */\n\n\n CanvasVectorTileLayerRenderer.prototype.renderTileImage_ = function (tile, frameState) {\n var layer =\n /** @type {import("../../layer/VectorTile.js").default} */\n this.getLayer();\n var replayState = tile.getReplayState(layer);\n var revision = layer.getRevision();\n var executorGroups = tile.executorGroups[getUid(layer)];\n replayState.renderedTileRevision = revision;\n replayState.renderedTileZ = tile.sourceZ;\n var tileCoord = tile.wrappedTileCoord;\n var z = tileCoord[0];\n var source = layer.getSource();\n var pixelRatio = frameState.pixelRatio;\n var viewState = frameState.viewState;\n var projection = viewState.projection;\n var tileGrid = source.getTileGridForProjection(projection);\n var tileResolution = tileGrid.getResolution(tile.tileCoord[0]);\n var renderPixelRatio = frameState.pixelRatio / tile.wantedResolution * tileResolution;\n var resolution = tileGrid.getResolution(z);\n var context = tile.getContext(layer); // Increase tile size when overzooming for low pixel ratio, to avoid blurry tiles\n\n pixelRatio = Math.round(Math.max(pixelRatio, renderPixelRatio / pixelRatio));\n var size = source.getTilePixelSize(z, pixelRatio, projection);\n context.canvas.width = size[0];\n context.canvas.height = size[1];\n var renderScale = pixelRatio / renderPixelRatio;\n\n if (renderScale !== 1) {\n var canvasTransform = transform_reset(this.tmpTransform_);\n scale(canvasTransform, renderScale, renderScale);\n context.setTransform.apply(context, canvasTransform);\n }\n\n var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);\n var pixelScale = renderPixelRatio / resolution;\n var transform = transform_reset(this.tmpTransform_);\n scale(transform, pixelScale, -pixelScale);\n translate(transform, -tileExtent[0], -tileExtent[3]);\n\n for (var i = 0, ii = executorGroups.length; i < ii; ++i) {\n var executorGroup = executorGroups[i];\n executorGroup.execute(context, renderScale, transform, 0, true, IMAGE_REPLAYS[layer.getRenderMode()]);\n }\n\n replayState.renderedTileResolution = tile.wantedResolution;\n };\n\n return CanvasVectorTileLayerRenderer;\n}(canvas_TileLayer);\n\n/* harmony default export */ var canvas_VectorTileLayer = (CanvasVectorTileLayerRenderer);\n;// CONCATENATED MODULE: ./node_modules/ol/layer/VectorTile.js\nvar VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/layer/VectorTile\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {string} [className=\'ol-layer\'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map\'s `layers` collection, or `Infinity` when the layer\'s `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting\n * features before rendering. By default features are drawn in the order that they are created. Use\n * `null` to avoid the sort, but get an undefined draw order.\n * @property {number} [renderBuffer=100] The buffer in pixels around the tile extent used by the\n * renderer when getting features from the vector tile for the rendering or hit-detection.\n * Recommended value: Vector tiles are usually generated with a buffer, so this value should match\n * the largest possible buffer of the used tiles. It should be at least the size of the largest\n * point symbol or line width.\n * @property {import("./VectorTileRenderType.js").default|string} [renderMode=\'hybrid\'] Render mode for vector tiles:\n * * `\'image\'`: Vector tiles are rendered as images. Only available when `declutter` is set to `false` (default).\n * Otherwise, `\'hybrid\'` mode will used instead. Great performance, but point symbols and texts\n * are always rotated with the view and pixels are scaled during zoom animations. Labels and point symbols will\n * get cut off at tile boundaries.\n * * `\'hybrid\'`: Polygon and line elements are rendered as images, so pixels are scaled during zoom\n * animations. Point symbols and texts are accurately rendered as vectors and can stay upright on\n * rotated views.\n * * `\'vector\'`: Everything is rendered as vectors. Use this mode for improved performance on vector\n * tile layers with only a few rendered features (e.g. for highlighting a subset of features of\n * another layer with the same source).\n * @property {import("../source/VectorTile.js").default} [source] Source.\n * @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage\n * this layer in its layers collection, and the layer will be rendered on top. This is useful for\n * temporary layers. The standard way to add a layer to a map and have it managed by the map is to\n * use {@link module:ol/Map#addLayer}.\n * @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all\n * image and text styles of all Vector and VectorTile layers that have set this to `true`. The priority\n * is defined by the z-index of the layer, the `zIndex` of the style and the render order of features.\n * Higher z-index means higher priority. Within the same z-index, a feature rendered before another has\n * higher priority.\n * @property {import("../style/Style.js").StyleLike} [style] Layer style. See\n * {@link module:ol/style} for default style which will be used if this is not defined.\n * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will be\n * recreated during animations. This means that no vectors will be shown clipped, but the setting\n * will have a performance impact for large amounts of vector data. When set to `false`, batches\n * will be recreated when no animation is active.\n * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will be\n * recreated during interactions. See also `updateWhileAnimating`.\n * @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`\n * means no preloading.\n * @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.\n */\n\n/**\n * @classdesc\n * Layer for vector tile data that is rendered client-side.\n * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}\n * property on the layer object; for example, setting `title: \'My Title\'` in the\n * options means that `title` is observable, and has get/set accessors.\n *\n * @param {Options=} opt_options Options.\n * @extends {BaseVectorLayer<import("../source/VectorTile.js").default>}\n * @api\n */\n\nvar VectorTileLayer =\n/** @class */\nfunction (_super) {\n VectorTile_extends(VectorTileLayer, _super);\n /**\n * @param {Options=} opt_options Options.\n */\n\n\n function VectorTileLayer(opt_options) {\n var _this = this;\n\n var options = opt_options ? opt_options : {};\n var baseOptions =\n /** @type {Object} */\n obj_assign({}, options);\n delete baseOptions.preload;\n delete baseOptions.useInterimTilesOnError;\n _this = _super.call(this,\n /** @type {import("./BaseVector.js").Options} */\n baseOptions) || this;\n var renderMode = options.renderMode || VectorTileRenderType.HYBRID;\n asserts_assert(renderMode == undefined || renderMode == VectorTileRenderType.IMAGE || renderMode == VectorTileRenderType.HYBRID || renderMode == VectorTileRenderType.VECTOR, 28); // `renderMode` must be `\'image\'`, `\'hybrid\'` or `\'vector\'`.\n\n /**\n * @private\n * @type {import("./VectorTileRenderType.js").default}\n */\n\n _this.renderMode_ = renderMode;\n\n _this.setPreload(options.preload ? options.preload : 0);\n\n _this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ? options.useInterimTilesOnError : true);\n\n return _this;\n }\n /**\n * Create a renderer for this layer.\n * @return {import("../renderer/Layer.js").default} A layer renderer.\n * @protected\n */\n\n\n VectorTileLayer.prototype.createRenderer = function () {\n return new canvas_VectorTileLayer(this);\n };\n /**\n * Get the topmost feature that intersects the given pixel on the viewport. Returns a promise\n * that resolves with an array of features. The array will either contain the topmost feature\n * when a hit was detected, or it will be empty.\n *\n * The hit detection algorithm used for this method is optimized for performance, but is less\n * accurate than the one used in {@link import("../PluggableMap.js").default#getFeaturesAtPixel}: Text\n * is not considered, and icons are only represented by their bounding box instead of the exact\n * image.\n *\n * @param {import("../pixel.js").Pixel} pixel Pixel.\n * @return {Promise<Array<import("../Feature").default>>} Promise that resolves with an array of features.\n * @api\n */\n\n\n VectorTileLayer.prototype.getFeatures = function (pixel) {\n return _super.prototype.getFeatures.call(this, pixel);\n };\n /**\n * @return {import("./VectorTileRenderType.js").default} The render mode.\n */\n\n\n VectorTileLayer.prototype.getRenderMode = function () {\n return this.renderMode_;\n };\n /**\n * Return the level as number to which we will preload tiles up to.\n * @return {number} The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.getPreload = function () {\n return (\n /** @type {number} */\n this.get(TileProperty.PRELOAD)\n );\n };\n /**\n * Whether we use interim tiles on error.\n * @return {boolean} Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.getUseInterimTilesOnError = function () {\n return (\n /** @type {boolean} */\n this.get(TileProperty.USE_INTERIM_TILES_ON_ERROR)\n );\n };\n /**\n * Set the level as number to which we will preload tiles up to.\n * @param {number} preload The level to preload tiles up to.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.setPreload = function (preload) {\n this.set(TileProperty.PRELOAD, preload);\n };\n /**\n * Set whether we use interim tiles on error.\n * @param {boolean} useInterimTilesOnError Use interim tiles on error.\n * @observable\n * @api\n */\n\n\n VectorTileLayer.prototype.setUseInterimTilesOnError = function (useInterimTilesOnError) {\n this.set(TileProperty.USE_INTERIM_TILES_ON_ERROR, useInterimTilesOnError);\n };\n\n return VectorTileLayer;\n}(BaseVector);\n\n/* harmony default export */ var VectorTile = (VectorTileLayer);\n;// CONCATENATED MODULE: ./node_modules/ol/Tile.js\nvar ol_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Tile\n */\n\n\n\n\n\n\n\n/**\n * A function that takes an {@link module:ol/Tile} for the tile and a\n * `{string}` for the url as arguments. The default is\n * ```js\n * source.setTileLoadFunction(function(tile, src) {\n * tile.getImage().src = src;\n * });\n * ```\n * For more fine grained control, the load function can use fetch or XMLHttpRequest and involve\n * error handling:\n *\n * ```js\n * import TileState from \'ol/TileState\';\n *\n * source.setTileLoadFunction(function(tile, src) {\n * var xhr = new XMLHttpRequest();\n * xhr.responseType = \'blob\';\n * xhr.addEventListener(\'loadend\', function (evt) {\n * var data = this.response;\n * if (data !== undefined) {\n * tile.getImage().src = URL.createObjectURL(data);\n * } else {\n * tile.setState(TileState.ERROR);\n * }\n * });\n * xhr.addEventListener(\'error\', function () {\n * tile.setState(TileState.ERROR);\n * });\n * xhr.open(\'GET\', src);\n * xhr.send();\n * });\n * ```\n *\n * @typedef {function(Tile, string): void} LoadFunction\n * @api\n */\n\n/**\n * {@link module:ol/source/Tile~Tile} sources use a function of this type to get\n * the url that provides a tile for a given tile coordinate.\n *\n * This function takes an {@link module:ol/tilecoord~TileCoord} for the tile\n * coordinate, a `{number}` representing the pixel ratio and a\n * {@link module:ol/proj/Projection} for the projection as arguments\n * and returns a `{string}` representing the tile URL, or undefined if no tile\n * should be requested for the passed tile coordinate.\n *\n * @typedef {function(import("./tilecoord.js").TileCoord, number,\n * import("./proj/Projection.js").default): (string|undefined)} UrlFunction\n * @api\n */\n\n/**\n * @typedef {Object} Options\n * @property {number} [transition=250] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @api\n */\n\n/**\n * @classdesc\n * Base class for tiles.\n *\n * @abstract\n */\n\nvar Tile_Tile =\n/** @class */\nfunction (_super) {\n ol_Tile_extends(Tile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {Options=} opt_options Tile options.\n */\n\n\n function Tile(tileCoord, state, opt_options) {\n var _this = _super.call(this) || this;\n\n var options = opt_options ? opt_options : {};\n /**\n * @type {import("./tilecoord.js").TileCoord}\n */\n\n _this.tileCoord = tileCoord;\n /**\n * @protected\n * @type {import("./TileState.js").default}\n */\n\n _this.state = state;\n /**\n * An "interim" tile for this tile. The interim tile may be used while this\n * one is loading, for "smooth" transitions when changing params/dimensions\n * on the source.\n * @type {Tile}\n */\n\n _this.interimTile = null;\n /**\n * The tile is available at the highest possible resolution. Subclasses can\n * set this to `false` initially. Tile load listeners will not be\n * unregistered before this is set to `true` and a `#changed()` is called.\n * @type {boolean}\n */\n\n _this.hifi = true;\n /**\n * A key assigned to the tile. This is used by the tile source to determine\n * if this tile can effectively be used, or if a new tile should be created\n * and this one be used as an interim tile for this new tile.\n * @type {string}\n */\n\n _this.key = \'\';\n /**\n * The duration for the opacity transition.\n * @type {number}\n */\n\n _this.transition_ = options.transition === undefined ? 250 : options.transition;\n /**\n * Lookup of start times for rendering transitions. If the start time is\n * equal to -1, the transition is complete.\n * @type {Object<string, number>}\n */\n\n _this.transitionStarts_ = {};\n return _this;\n }\n /**\n * @protected\n */\n\n\n Tile.prototype.changed = function () {\n this.dispatchEvent(EventType.CHANGE);\n };\n /**\n * Called by the tile cache when the tile is removed from the cache due to expiry\n */\n\n\n Tile.prototype.release = function () {};\n /**\n * @return {string} Key.\n */\n\n\n Tile.prototype.getKey = function () {\n return this.key + \'/\' + this.tileCoord;\n };\n /**\n * Get the interim tile most suitable for rendering using the chain of interim\n * tiles. This corresponds to the most recent tile that has been loaded, if no\n * such tile exists, the original tile is returned.\n * @return {!Tile} Best tile for rendering.\n */\n\n\n Tile.prototype.getInterimTile = function () {\n if (!this.interimTile) {\n //empty chain\n return this;\n }\n\n var tile = this.interimTile; // find the first loaded tile and return it. Since the chain is sorted in\n // decreasing order of creation time, there is no need to search the remainder\n // of the list (all those tiles correspond to older requests and will be\n // cleaned up by refreshInterimChain)\n\n do {\n if (tile.getState() == TileState.LOADED) {\n // Show tile immediately instead of fading it in after loading, because\n // the interim tile is in place already\n this.transition_ = 0;\n return tile;\n }\n\n tile = tile.interimTile;\n } while (tile); // we can not find a better tile\n\n\n return this;\n };\n /**\n * Goes through the chain of interim tiles and discards sections of the chain\n * that are no longer relevant.\n */\n\n\n Tile.prototype.refreshInterimChain = function () {\n if (!this.interimTile) {\n return;\n }\n\n var tile = this.interimTile;\n var prev =\n /** @type {Tile} */\n this;\n\n do {\n if (tile.getState() == TileState.LOADED) {\n //we have a loaded tile, we can discard the rest of the list\n //we would could abort any LOADING tile request\n //older than this tile (i.e. any LOADING tile following this entry in the chain)\n tile.interimTile = null;\n break;\n } else if (tile.getState() == TileState.LOADING) {\n //keep this LOADING tile any loaded tiles later in the chain are\n //older than this tile, so we\'re still interested in the request\n prev = tile;\n } else if (tile.getState() == TileState.IDLE) {\n //the head of the list is the most current tile, we don\'t need\n //to start any other requests for this chain\n prev.interimTile = tile.interimTile;\n } else {\n prev = tile;\n }\n\n tile = prev.interimTile;\n } while (tile);\n };\n /**\n * Get the tile coordinate for this tile.\n * @return {import("./tilecoord.js").TileCoord} The tile coordinate.\n * @api\n */\n\n\n Tile.prototype.getTileCoord = function () {\n return this.tileCoord;\n };\n /**\n * @return {import("./TileState.js").default} State.\n */\n\n\n Tile.prototype.getState = function () {\n return this.state;\n };\n /**\n * Sets the state of this tile. If you write your own {@link module:ol/Tile~LoadFunction tileLoadFunction} ,\n * it is important to set the state correctly to {@link module:ol/TileState~ERROR}\n * when the tile cannot be loaded. Otherwise the tile cannot be removed from\n * the tile queue and will block other requests.\n * @param {import("./TileState.js").default} state State.\n * @api\n */\n\n\n Tile.prototype.setState = function (state) {\n if (this.state !== TileState.ERROR && this.state > state) {\n throw new Error(\'Tile load sequence violation\');\n }\n\n this.state = state;\n this.changed();\n };\n /**\n * Load the image or retry if loading previously failed.\n * Loading is taken care of by the tile queue, and calling this method is\n * only needed for preloading or for reloading in case of an error.\n * @abstract\n * @api\n */\n\n\n Tile.prototype.load = function () {\n util_abstract();\n };\n /**\n * Get the alpha value for rendering.\n * @param {string} id An id for the renderer.\n * @param {number} time The render frame time.\n * @return {number} A number between 0 and 1.\n */\n\n\n Tile.prototype.getAlpha = function (id, time) {\n if (!this.transition_) {\n return 1;\n }\n\n var start = this.transitionStarts_[id];\n\n if (!start) {\n start = time;\n this.transitionStarts_[id] = start;\n } else if (start === -1) {\n return 1;\n }\n\n var delta = time - start + 1000 / 60; // avoid rendering at 0\n\n if (delta >= this.transition_) {\n return 1;\n }\n\n return easeIn(delta / this.transition_);\n };\n /**\n * Determine if a tile is in an alpha transition. A tile is considered in\n * transition if tile.getAlpha() has not yet been called or has been called\n * and returned 1.\n * @param {string} id An id for the renderer.\n * @return {boolean} The tile is in transition.\n */\n\n\n Tile.prototype.inTransition = function (id) {\n if (!this.transition_) {\n return false;\n }\n\n return this.transitionStarts_[id] !== -1;\n };\n /**\n * Mark a transition as complete.\n * @param {string} id An id for the renderer.\n */\n\n\n Tile.prototype.endTransition = function (id) {\n if (this.transition_) {\n this.transitionStarts_[id] = -1;\n }\n };\n\n return Tile;\n}(events_Target);\n\n/* harmony default export */ var ol_Tile = (Tile_Tile);\n;// CONCATENATED MODULE: ./node_modules/ol/ImageTile.js\nvar ImageTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/ImageTile\n */\n\n\n\n\n\n\n\nvar ImageTile =\n/** @class */\nfunction (_super) {\n ImageTile_extends(ImageTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {string} src Image source URI.\n * @param {?string} crossOrigin Cross origin.\n * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @param {import("./Tile.js").Options=} opt_options Tile options.\n */\n\n\n function ImageTile(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {\n var _this = _super.call(this, tileCoord, state, opt_options) || this;\n /**\n * @private\n * @type {?string}\n */\n\n\n _this.crossOrigin_ = crossOrigin;\n /**\n * Image URI\n *\n * @private\n * @type {string}\n */\n\n _this.src_ = src;\n _this.key = src;\n /**\n * @private\n * @type {HTMLImageElement|HTMLCanvasElement}\n */\n\n _this.image_ = new Image();\n\n if (crossOrigin !== null) {\n _this.image_.crossOrigin = crossOrigin;\n }\n /**\n * @private\n * @type {?function():void}\n */\n\n\n _this.unlisten_ = null;\n /**\n * @private\n * @type {import("./Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction_ = tileLoadFunction;\n return _this;\n }\n /**\n * Get the HTML image element for this tile (may be a Canvas, Image, or Video).\n * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.\n * @api\n */\n\n\n ImageTile.prototype.getImage = function () {\n return this.image_;\n };\n /**\n * Tracks loading or read errors.\n *\n * @private\n */\n\n\n ImageTile.prototype.handleImageError_ = function () {\n this.state = TileState.ERROR;\n this.unlistenImage_();\n this.image_ = getBlankImage();\n this.changed();\n };\n /**\n * Tracks successful image load.\n *\n * @private\n */\n\n\n ImageTile.prototype.handleImageLoad_ = function () {\n var image =\n /** @type {HTMLImageElement} */\n this.image_;\n\n if (image.naturalWidth && image.naturalHeight) {\n this.state = TileState.LOADED;\n } else {\n this.state = TileState.EMPTY;\n }\n\n this.unlistenImage_();\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n * @api\n */\n\n\n ImageTile.prototype.load = function () {\n if (this.state == TileState.ERROR) {\n this.state = TileState.IDLE;\n this.image_ = new Image();\n\n if (this.crossOrigin_ !== null) {\n this.image_.crossOrigin = this.crossOrigin_;\n }\n }\n\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n this.tileLoadFunction_(this, this.src_);\n this.unlisten_ = listenImage(this.image_, this.handleImageLoad_.bind(this), this.handleImageError_.bind(this));\n }\n };\n /**\n * Discards event handlers which listen for load completion or errors.\n *\n * @private\n */\n\n\n ImageTile.prototype.unlistenImage_ = function () {\n if (this.unlisten_) {\n this.unlisten_();\n this.unlisten_ = null;\n }\n };\n\n return ImageTile;\n}(ol_Tile);\n/**\n * Get a 1-pixel blank image.\n * @return {HTMLCanvasElement} Blank image.\n */\n\n\nfunction getBlankImage() {\n var ctx = createCanvasContext2D(1, 1);\n ctx.fillStyle = \'rgba(0,0,0,0)\';\n ctx.fillRect(0, 0, 1, 1);\n return ctx.canvas;\n}\n\n/* harmony default export */ var ol_ImageTile = (ImageTile);\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/common.js\n/**\n * @module ol/reproj/common\n */\n\n/**\n * Default maximum allowed threshold (in pixels) for reprojection\n * triangulation.\n * @type {number}\n */\nvar ERROR_THRESHOLD = 0.5;\n/**\n * Enable automatic reprojection of raster sources. Default is `true`.\n * TODO: decide if we want to expose this as a build flag or remove it\n * @type {boolean}\n */\n\nvar ENABLE_RASTER_REPROJECTION = true;\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/Triangulation.js\n/**\n * @module ol/reproj/Triangulation\n */\n\n\n\n/**\n * Single triangle; consists of 3 source points and 3 target points.\n * @typedef {Object} Triangle\n * @property {Array<import("../coordinate.js").Coordinate>} source\n * @property {Array<import("../coordinate.js").Coordinate>} target\n */\n\n/**\n * Maximum number of subdivision steps during raster reprojection triangulation.\n * Prevents high memory usage and large number of proj4 calls (for certain\n * transformations and areas). At most `2*(2^this)` triangles are created for\n * each triangulated extent (tile/image).\n * @type {number}\n */\n\nvar MAX_SUBDIVISION = 10;\n/**\n * Maximum allowed size of triangle relative to world width. When transforming\n * corners of world extent between certain projections, the resulting\n * triangulation seems to have zero error and no subdivision is performed. If\n * the triangle width is more than this (relative to world width; 0-1),\n * subdivison is forced (up to `MAX_SUBDIVISION`). Default is `0.25`.\n * @type {number}\n */\n\nvar MAX_TRIANGLE_WIDTH = 0.25;\n/**\n * @classdesc\n * Class containing triangulation of the given target extent.\n * Used for determining source data and the reprojection itself.\n */\n\nvar Triangulation =\n/** @class */\nfunction () {\n /**\n * @param {import("../proj/Projection.js").default} sourceProj Source projection.\n * @param {import("../proj/Projection.js").default} targetProj Target projection.\n * @param {import("../extent.js").Extent} targetExtent Target extent to triangulate.\n * @param {import("../extent.js").Extent} maxSourceExtent Maximal source extent that can be used.\n * @param {number} errorThreshold Acceptable error (in source units).\n * @param {?number} opt_destinationResolution The (optional) resolution of the destination.\n */\n function Triangulation(sourceProj, targetProj, targetExtent, maxSourceExtent, errorThreshold, opt_destinationResolution) {\n /**\n * @type {import("../proj/Projection.js").default}\n * @private\n */\n this.sourceProj_ = sourceProj;\n /**\n * @type {import("../proj/Projection.js").default}\n * @private\n */\n\n this.targetProj_ = targetProj;\n /** @type {!Object<string, import("../coordinate.js").Coordinate>} */\n\n var transformInvCache = {};\n var transformInv = getTransform(this.targetProj_, this.sourceProj_);\n /**\n * @param {import("../coordinate.js").Coordinate} c A coordinate.\n * @return {import("../coordinate.js").Coordinate} Transformed coordinate.\n * @private\n */\n\n this.transformInv_ = function (c) {\n var key = c[0] + \'/\' + c[1];\n\n if (!transformInvCache[key]) {\n transformInvCache[key] = transformInv(c);\n }\n\n return transformInvCache[key];\n };\n /**\n * @type {import("../extent.js").Extent}\n * @private\n */\n\n\n this.maxSourceExtent_ = maxSourceExtent;\n /**\n * @type {number}\n * @private\n */\n\n this.errorThresholdSquared_ = errorThreshold * errorThreshold;\n /**\n * @type {Array<Triangle>}\n * @private\n */\n\n this.triangles_ = [];\n /**\n * Indicates that the triangulation crosses edge of the source projection.\n * @type {boolean}\n * @private\n */\n\n this.wrapsXInSource_ = false;\n /**\n * @type {boolean}\n * @private\n */\n\n this.canWrapXInSource_ = this.sourceProj_.canWrapX() && !!maxSourceExtent && !!this.sourceProj_.getExtent() && extent_getWidth(maxSourceExtent) == extent_getWidth(this.sourceProj_.getExtent());\n /**\n * @type {?number}\n * @private\n */\n\n this.sourceWorldWidth_ = this.sourceProj_.getExtent() ? extent_getWidth(this.sourceProj_.getExtent()) : null;\n /**\n * @type {?number}\n * @private\n */\n\n this.targetWorldWidth_ = this.targetProj_.getExtent() ? extent_getWidth(this.targetProj_.getExtent()) : null;\n var destinationTopLeft = getTopLeft(targetExtent);\n var destinationTopRight = getTopRight(targetExtent);\n var destinationBottomRight = getBottomRight(targetExtent);\n var destinationBottomLeft = getBottomLeft(targetExtent);\n var sourceTopLeft = this.transformInv_(destinationTopLeft);\n var sourceTopRight = this.transformInv_(destinationTopRight);\n var sourceBottomRight = this.transformInv_(destinationBottomRight);\n var sourceBottomLeft = this.transformInv_(destinationBottomLeft);\n /*\n * The maxSubdivision controls how many splittings of the target area can\n * be done. The idea here is to do a linear mapping of the target areas\n * but the actual overal reprojection (can be) extremely non-linear. The\n * default value of MAX_SUBDIVISION was chosen based on mapping a 256x256\n * tile size. However this function is also called to remap canvas rendered\n * layers which can be much larger. This calculation increases the maxSubdivision\n * value by the right factor so that each 256x256 pixel area has\n * MAX_SUBDIVISION divisions.\n */\n\n var maxSubdivision = MAX_SUBDIVISION + (opt_destinationResolution ? Math.max(0, Math.ceil(log2(getArea(targetExtent) / (opt_destinationResolution * opt_destinationResolution * 256 * 256)))) : 0);\n this.addQuad_(destinationTopLeft, destinationTopRight, destinationBottomRight, destinationBottomLeft, sourceTopLeft, sourceTopRight, sourceBottomRight, sourceBottomLeft, maxSubdivision);\n\n if (this.wrapsXInSource_) {\n var leftBound_1 = Infinity;\n this.triangles_.forEach(function (triangle, i, arr) {\n leftBound_1 = Math.min(leftBound_1, triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]);\n }); // Shift triangles to be as close to `leftBound` as possible\n // (if the distance is more than `worldWidth / 2` it can be closer.\n\n this.triangles_.forEach(function (triangle) {\n if (Math.max(triangle.source[0][0], triangle.source[1][0], triangle.source[2][0]) - leftBound_1 > this.sourceWorldWidth_ / 2) {\n var newTriangle = [[triangle.source[0][0], triangle.source[0][1]], [triangle.source[1][0], triangle.source[1][1]], [triangle.source[2][0], triangle.source[2][1]]];\n\n if (newTriangle[0][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[0][0] -= this.sourceWorldWidth_;\n }\n\n if (newTriangle[1][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[1][0] -= this.sourceWorldWidth_;\n }\n\n if (newTriangle[2][0] - leftBound_1 > this.sourceWorldWidth_ / 2) {\n newTriangle[2][0] -= this.sourceWorldWidth_;\n } // Rarely (if the extent contains both the dateline and prime meridian)\n // the shift can in turn break some triangles.\n // Detect this here and don\'t shift in such cases.\n\n\n var minX = Math.min(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n var maxX = Math.max(newTriangle[0][0], newTriangle[1][0], newTriangle[2][0]);\n\n if (maxX - minX < this.sourceWorldWidth_ / 2) {\n triangle.source = newTriangle;\n }\n }\n }.bind(this));\n }\n\n transformInvCache = {};\n }\n /**\n * Adds triangle to the triangulation.\n * @param {import("../coordinate.js").Coordinate} a The target a coordinate.\n * @param {import("../coordinate.js").Coordinate} b The target b coordinate.\n * @param {import("../coordinate.js").Coordinate} c The target c coordinate.\n * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.\n * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.\n * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.\n * @private\n */\n\n\n Triangulation.prototype.addTriangle_ = function (a, b, c, aSrc, bSrc, cSrc) {\n this.triangles_.push({\n source: [aSrc, bSrc, cSrc],\n target: [a, b, c]\n });\n };\n /**\n * Adds quad (points in clock-wise order) to the triangulation\n * (and reprojects the vertices) if valid.\n * Performs quad subdivision if needed to increase precision.\n *\n * @param {import("../coordinate.js").Coordinate} a The target a coordinate.\n * @param {import("../coordinate.js").Coordinate} b The target b coordinate.\n * @param {import("../coordinate.js").Coordinate} c The target c coordinate.\n * @param {import("../coordinate.js").Coordinate} d The target d coordinate.\n * @param {import("../coordinate.js").Coordinate} aSrc The source a coordinate.\n * @param {import("../coordinate.js").Coordinate} bSrc The source b coordinate.\n * @param {import("../coordinate.js").Coordinate} cSrc The source c coordinate.\n * @param {import("../coordinate.js").Coordinate} dSrc The source d coordinate.\n * @param {number} maxSubdivision Maximal allowed subdivision of the quad.\n * @private\n */\n\n\n Triangulation.prototype.addQuad_ = function (a, b, c, d, aSrc, bSrc, cSrc, dSrc, maxSubdivision) {\n var sourceQuadExtent = boundingExtent([aSrc, bSrc, cSrc, dSrc]);\n var sourceCoverageX = this.sourceWorldWidth_ ? extent_getWidth(sourceQuadExtent) / this.sourceWorldWidth_ : null;\n var sourceWorldWidth =\n /** @type {number} */\n this.sourceWorldWidth_; // when the quad is wrapped in the source projection\n // it covers most of the projection extent, but not fully\n\n var wrapsX = this.sourceProj_.canWrapX() && sourceCoverageX > 0.5 && sourceCoverageX < 1;\n var needsSubdivision = false;\n\n if (maxSubdivision > 0) {\n if (this.targetProj_.isGlobal() && this.targetWorldWidth_) {\n var targetQuadExtent = boundingExtent([a, b, c, d]);\n var targetCoverageX = extent_getWidth(targetQuadExtent) / this.targetWorldWidth_;\n needsSubdivision = targetCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n\n if (!wrapsX && this.sourceProj_.isGlobal() && sourceCoverageX) {\n needsSubdivision = sourceCoverageX > MAX_TRIANGLE_WIDTH || needsSubdivision;\n }\n }\n\n if (!needsSubdivision && this.maxSourceExtent_) {\n if (isFinite(sourceQuadExtent[0]) && isFinite(sourceQuadExtent[1]) && isFinite(sourceQuadExtent[2]) && isFinite(sourceQuadExtent[3])) {\n if (!intersects(sourceQuadExtent, this.maxSourceExtent_)) {\n // whole quad outside source projection extent -> ignore\n return;\n }\n }\n }\n\n var isNotFinite = 0;\n\n if (!needsSubdivision) {\n if (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) || !isFinite(bSrc[0]) || !isFinite(bSrc[1]) || !isFinite(cSrc[0]) || !isFinite(cSrc[1]) || !isFinite(dSrc[0]) || !isFinite(dSrc[1])) {\n if (maxSubdivision > 0) {\n needsSubdivision = true;\n } else {\n // It might be the case that only 1 of the points is infinite. In this case\n // we can draw a single triangle with the other three points\n isNotFinite = (!isFinite(aSrc[0]) || !isFinite(aSrc[1]) ? 8 : 0) + (!isFinite(bSrc[0]) || !isFinite(bSrc[1]) ? 4 : 0) + (!isFinite(cSrc[0]) || !isFinite(cSrc[1]) ? 2 : 0) + (!isFinite(dSrc[0]) || !isFinite(dSrc[1]) ? 1 : 0);\n\n if (isNotFinite != 1 && isNotFinite != 2 && isNotFinite != 4 && isNotFinite != 8) {\n return;\n }\n }\n }\n }\n\n if (maxSubdivision > 0) {\n if (!needsSubdivision) {\n var center = [(a[0] + c[0]) / 2, (a[1] + c[1]) / 2];\n var centerSrc = this.transformInv_(center);\n var dx = void 0;\n\n if (wrapsX) {\n var centerSrcEstimX = (math_modulo(aSrc[0], sourceWorldWidth) + math_modulo(cSrc[0], sourceWorldWidth)) / 2;\n dx = centerSrcEstimX - math_modulo(centerSrc[0], sourceWorldWidth);\n } else {\n dx = (aSrc[0] + cSrc[0]) / 2 - centerSrc[0];\n }\n\n var dy = (aSrc[1] + cSrc[1]) / 2 - centerSrc[1];\n var centerSrcErrorSquared = dx * dx + dy * dy;\n needsSubdivision = centerSrcErrorSquared > this.errorThresholdSquared_;\n }\n\n if (needsSubdivision) {\n if (Math.abs(a[0] - c[0]) <= Math.abs(a[1] - c[1])) {\n // split horizontally (top & bottom)\n var bc = [(b[0] + c[0]) / 2, (b[1] + c[1]) / 2];\n var bcSrc = this.transformInv_(bc);\n var da = [(d[0] + a[0]) / 2, (d[1] + a[1]) / 2];\n var daSrc = this.transformInv_(da);\n this.addQuad_(a, b, bc, da, aSrc, bSrc, bcSrc, daSrc, maxSubdivision - 1);\n this.addQuad_(da, bc, c, d, daSrc, bcSrc, cSrc, dSrc, maxSubdivision - 1);\n } else {\n // split vertically (left & right)\n var ab = [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];\n var abSrc = this.transformInv_(ab);\n var cd = [(c[0] + d[0]) / 2, (c[1] + d[1]) / 2];\n var cdSrc = this.transformInv_(cd);\n this.addQuad_(a, ab, cd, d, aSrc, abSrc, cdSrc, dSrc, maxSubdivision - 1);\n this.addQuad_(ab, b, c, cd, abSrc, bSrc, cSrc, cdSrc, maxSubdivision - 1);\n }\n\n return;\n }\n }\n\n if (wrapsX) {\n if (!this.canWrapXInSource_) {\n return;\n }\n\n this.wrapsXInSource_ = true;\n } // Exactly zero or one of *Src is not finite\n // The triangles must have the diagonal line as the first side\n // This is to allow easy code in reproj.s to make it straight for broken\n // browsers that can\'t handle diagonal clipping\n\n\n if ((isNotFinite & 0xb) == 0) {\n this.addTriangle_(a, c, d, aSrc, cSrc, dSrc);\n }\n\n if ((isNotFinite & 0xe) == 0) {\n this.addTriangle_(a, c, b, aSrc, cSrc, bSrc);\n }\n\n if (isNotFinite) {\n // Try the other two triangles\n if ((isNotFinite & 0xd) == 0) {\n this.addTriangle_(b, d, a, bSrc, dSrc, aSrc);\n }\n\n if ((isNotFinite & 0x7) == 0) {\n this.addTriangle_(b, d, c, bSrc, dSrc, cSrc);\n }\n }\n };\n /**\n * Calculates extent of the \'source\' coordinates from all the triangles.\n *\n * @return {import("../extent.js").Extent} Calculated extent.\n */\n\n\n Triangulation.prototype.calculateSourceExtent = function () {\n var extent = createEmpty();\n this.triangles_.forEach(function (triangle, i, arr) {\n var src = triangle.source;\n extendCoordinate(extent, src[0]);\n extendCoordinate(extent, src[1]);\n extendCoordinate(extent, src[2]);\n });\n return extent;\n };\n /**\n * @return {Array<Triangle>} Array of the calculated triangles.\n */\n\n\n Triangulation.prototype.getTriangles = function () {\n return this.triangles_;\n };\n\n return Triangulation;\n}();\n\n/* harmony default export */ var reproj_Triangulation = (Triangulation);\n;// CONCATENATED MODULE: ./node_modules/ol/source/common.js\n/**\n * @module ol/source/common\n */\n\n/**\n * Default WMS version.\n * @type {string}\n */\nvar DEFAULT_WMS_VERSION = \'1.3.0\';\n/**\n * Context options to disable image smoothing.\n * @type {Object}\n */\n\nvar IMAGE_SMOOTHING_DISABLED = {\n imageSmoothingEnabled: false,\n msImageSmoothingEnabled: false\n};\n;// CONCATENATED MODULE: ./node_modules/ol/reproj.js\n/**\n * @module ol/reproj\n */\n\n\n\n\n\n\nvar brokenDiagonalRendering_;\n/**\n * This draws a small triangle into a canvas by setting the triangle as the clip region\n * and then drawing a (too large) rectangle\n *\n * @param {CanvasRenderingContext2D} ctx The context in which to draw the triangle\n * @param {number} u1 The x-coordinate of the second point. The first point is 0,0.\n * @param {number} v1 The y-coordinate of the second point.\n * @param {number} u2 The x-coordinate of the third point.\n * @param {number} v2 The y-coordinate of the third point.\n */\n\nfunction drawTestTriangle(ctx, u1, v1, u2, v2) {\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(u1, v1);\n ctx.lineTo(u2, v2);\n ctx.closePath();\n ctx.save();\n ctx.clip();\n ctx.fillRect(0, 0, Math.max(u1, u2) + 1, Math.max(v1, v2));\n ctx.restore();\n}\n/**\n * Given the data from getImageData, see if the right values appear at the provided offset.\n * Returns true if either the color or transparency is off\n *\n * @param {Uint8ClampedArray} data The data returned from getImageData\n * @param {number} offset The pixel offset from the start of data.\n * @return {boolean} true if the diagonal rendering is broken\n */\n\n\nfunction verifyBrokenDiagonalRendering(data, offset) {\n // the values ought to be close to the rgba(210, 0, 0, 0.75)\n return Math.abs(data[offset * 4] - 210) > 2 || Math.abs(data[offset * 4 + 3] - 0.75 * 255) > 2;\n}\n/**\n * Determines if the current browser configuration can render triangular clip regions correctly.\n * This value is cached so the function is only expensive the first time called.\n * Firefox on Windows (as of now) does not if HWA is enabled. See https://bugzilla.mozilla.org/show_bug.cgi?id=1606976\n * IE also doesn\'t. Chrome works, and everything seems to work on OSX and Android. This function caches the\n * result. I suppose that it is conceivably possible that a browser might flip modes while the app is\n * running, but lets hope not.\n *\n * @return {boolean} true if the Diagonal Rendering is broken.\n */\n\n\nfunction isBrokenDiagonalRendering() {\n if (brokenDiagonalRendering_ === undefined) {\n var ctx = document.createElement(\'canvas\').getContext(\'2d\');\n ctx.globalCompositeOperation = \'lighter\';\n ctx.fillStyle = \'rgba(210, 0, 0, 0.75)\';\n drawTestTriangle(ctx, 4, 5, 4, 0);\n drawTestTriangle(ctx, 4, 5, 0, 5);\n var data = ctx.getImageData(0, 0, 3, 3).data;\n brokenDiagonalRendering_ = verifyBrokenDiagonalRendering(data, 0) || verifyBrokenDiagonalRendering(data, 4) || verifyBrokenDiagonalRendering(data, 8);\n }\n\n return brokenDiagonalRendering_;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import("./proj/Projection.js").default} sourceProj Source projection.\n * @param {import("./proj/Projection.js").default} targetProj Target projection.\n * @param {import("./coordinate.js").Coordinate} targetCenter Target center.\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\n\n\nfunction calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution) {\n var sourceCenter = transform(targetCenter, targetProj, sourceProj); // calculate the ideal resolution of the source data\n\n var sourceResolution = getPointResolution(targetProj, targetResolution, targetCenter);\n var targetMetersPerUnit = targetProj.getMetersPerUnit();\n\n if (targetMetersPerUnit !== undefined) {\n sourceResolution *= targetMetersPerUnit;\n }\n\n var sourceMetersPerUnit = sourceProj.getMetersPerUnit();\n\n if (sourceMetersPerUnit !== undefined) {\n sourceResolution /= sourceMetersPerUnit;\n } // Based on the projection properties, the point resolution at the specified\n // coordinates may be slightly different. We need to reverse-compensate this\n // in order to achieve optimal results.\n\n\n var sourceExtent = sourceProj.getExtent();\n\n if (!sourceExtent || containsCoordinate(sourceExtent, sourceCenter)) {\n var compensationFactor = getPointResolution(sourceProj, sourceResolution, sourceCenter) / sourceResolution;\n\n if (isFinite(compensationFactor) && compensationFactor > 0) {\n sourceResolution /= compensationFactor;\n }\n }\n\n return sourceResolution;\n}\n/**\n * Calculates ideal resolution to use from the source in order to achieve\n * pixel mapping as close as possible to 1:1 during reprojection.\n * The resolution is calculated regardless of what resolutions\n * are actually available in the dataset (TileGrid, Image, ...).\n *\n * @param {import("./proj/Projection.js").default} sourceProj Source projection.\n * @param {import("./proj/Projection.js").default} targetProj Target projection.\n * @param {import("./extent.js").Extent} targetExtent Target extent\n * @param {number} targetResolution Target resolution.\n * @return {number} The best resolution to use. Can be +-Infinity, NaN or 0.\n */\n\nfunction calculateSourceExtentResolution(sourceProj, targetProj, targetExtent, targetResolution) {\n var targetCenter = getCenter(targetExtent);\n var sourceResolution = calculateSourceResolution(sourceProj, targetProj, targetCenter, targetResolution);\n\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n forEachCorner(targetExtent, function (corner) {\n sourceResolution = calculateSourceResolution(sourceProj, targetProj, corner, targetResolution);\n return isFinite(sourceResolution) && sourceResolution > 0;\n });\n }\n\n return sourceResolution;\n}\n/**\n * Renders the source data into new canvas based on the triangulation.\n *\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} sourceResolution Source resolution.\n * @param {import("./extent.js").Extent} sourceExtent Extent of the data source.\n * @param {number} targetResolution Target resolution.\n * @param {import("./extent.js").Extent} targetExtent Target extent.\n * @param {import("./reproj/Triangulation.js").default} triangulation\n * Calculated triangulation.\n * @param {Array<{extent: import("./extent.js").Extent,\n * image: (HTMLCanvasElement|HTMLImageElement|HTMLVideoElement)}>} sources\n * Array of sources.\n * @param {number} gutter Gutter of the sources.\n * @param {boolean=} opt_renderEdges Render reprojection edges.\n * @param {object=} opt_contextOptions Properties to set on the canvas context.\n * @return {HTMLCanvasElement} Canvas with reprojected data.\n */\n\nfunction render(width, height, pixelRatio, sourceResolution, sourceExtent, targetResolution, targetExtent, triangulation, sources, gutter, opt_renderEdges, opt_contextOptions) {\n var context = createCanvasContext2D(Math.round(pixelRatio * width), Math.round(pixelRatio * height));\n obj_assign(context, opt_contextOptions);\n\n if (sources.length === 0) {\n return context.canvas;\n }\n\n context.scale(pixelRatio, pixelRatio);\n\n function pixelRound(value) {\n return Math.round(value * pixelRatio) / pixelRatio;\n }\n\n context.globalCompositeOperation = \'lighter\';\n var sourceDataExtent = createEmpty();\n sources.forEach(function (src, i, arr) {\n extent_extend(sourceDataExtent, src.extent);\n });\n var canvasWidthInUnits = extent_getWidth(sourceDataExtent);\n var canvasHeightInUnits = getHeight(sourceDataExtent);\n var stitchContext = createCanvasContext2D(Math.round(pixelRatio * canvasWidthInUnits / sourceResolution), Math.round(pixelRatio * canvasHeightInUnits / sourceResolution));\n obj_assign(stitchContext, opt_contextOptions);\n var stitchScale = pixelRatio / sourceResolution;\n sources.forEach(function (src, i, arr) {\n var xPos = src.extent[0] - sourceDataExtent[0];\n var yPos = -(src.extent[3] - sourceDataExtent[3]);\n var srcWidth = extent_getWidth(src.extent);\n var srcHeight = getHeight(src.extent); // This test should never fail -- but it does. Need to find a fix the upstream condition\n\n if (src.image.width > 0 && src.image.height > 0) {\n stitchContext.drawImage(src.image, gutter, gutter, src.image.width - 2 * gutter, src.image.height - 2 * gutter, xPos * stitchScale, yPos * stitchScale, srcWidth * stitchScale, srcHeight * stitchScale);\n }\n });\n var targetTopLeft = getTopLeft(targetExtent);\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n /* Calculate affine transform (src -> dst)\n * Resulting matrix can be used to transform coordinate\n * from `sourceProjection` to destination pixels.\n *\n * To optimize number of context calls and increase numerical stability,\n * we also do the following operations:\n * trans(-topLeftExtentCorner), scale(1 / targetResolution), scale(1, -1)\n * here before solving the linear system so [ui, vi] are pixel coordinates.\n *\n * Src points: xi, yi\n * Dst points: ui, vi\n * Affine coefficients: aij\n *\n * | x0 y0 1 0 0 0 | |a00| |u0|\n * | x1 y1 1 0 0 0 | |a01| |u1|\n * | x2 y2 1 0 0 0 | x |a02| = |u2|\n * | 0 0 0 x0 y0 1 | |a10| |v0|\n * | 0 0 0 x1 y1 1 | |a11| |v1|\n * | 0 0 0 x2 y2 1 | |a12| |v2|\n */\n var source = triangle.source;\n var target = triangle.target;\n var x0 = source[0][0],\n y0 = source[0][1];\n var x1 = source[1][0],\n y1 = source[1][1];\n var x2 = source[2][0],\n y2 = source[2][1]; // Make sure that everything is on pixel boundaries\n\n var u0 = pixelRound((target[0][0] - targetTopLeft[0]) / targetResolution);\n var v0 = pixelRound(-(target[0][1] - targetTopLeft[1]) / targetResolution);\n var u1 = pixelRound((target[1][0] - targetTopLeft[0]) / targetResolution);\n var v1 = pixelRound(-(target[1][1] - targetTopLeft[1]) / targetResolution);\n var u2 = pixelRound((target[2][0] - targetTopLeft[0]) / targetResolution);\n var v2 = pixelRound(-(target[2][1] - targetTopLeft[1]) / targetResolution); // Shift all the source points to improve numerical stability\n // of all the subsequent calculations. The [x0, y0] is used here.\n // This is also used to simplify the linear system.\n\n var sourceNumericalShiftX = x0;\n var sourceNumericalShiftY = y0;\n x0 = 0;\n y0 = 0;\n x1 -= sourceNumericalShiftX;\n y1 -= sourceNumericalShiftY;\n x2 -= sourceNumericalShiftX;\n y2 -= sourceNumericalShiftY;\n var augmentedMatrix = [[x1, y1, 0, 0, u1 - u0], [x2, y2, 0, 0, u2 - u0], [0, 0, x1, y1, v1 - v0], [0, 0, x2, y2, v2 - v0]];\n var affineCoefs = solveLinearSystem(augmentedMatrix);\n\n if (!affineCoefs) {\n return;\n }\n\n context.save();\n context.beginPath();\n\n if (isBrokenDiagonalRendering() || opt_contextOptions === IMAGE_SMOOTHING_DISABLED) {\n // Make sure that all lines are horizontal or vertical\n context.moveTo(u1, v1); // This is the diagonal line. Do it in 4 steps\n\n var steps = 4;\n var ud = u0 - u1;\n var vd = v0 - v1;\n\n for (var step = 0; step < steps; step++) {\n // Go horizontally\n context.lineTo(u1 + pixelRound((step + 1) * ud / steps), v1 + pixelRound(step * vd / (steps - 1))); // Go vertically\n\n if (step != steps - 1) {\n context.lineTo(u1 + pixelRound((step + 1) * ud / steps), v1 + pixelRound((step + 1) * vd / (steps - 1)));\n }\n } // We are almost at u0r, v0r\n\n\n context.lineTo(u2, v2);\n } else {\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n }\n\n context.clip();\n context.transform(affineCoefs[0], affineCoefs[2], affineCoefs[1], affineCoefs[3], u0, v0);\n context.translate(sourceDataExtent[0] - sourceNumericalShiftX, sourceDataExtent[3] - sourceNumericalShiftY);\n context.scale(sourceResolution / pixelRatio, -sourceResolution / pixelRatio);\n context.drawImage(stitchContext.canvas, 0, 0);\n context.restore();\n });\n\n if (opt_renderEdges) {\n context.save();\n context.globalCompositeOperation = \'source-over\';\n context.strokeStyle = \'black\';\n context.lineWidth = 1;\n triangulation.getTriangles().forEach(function (triangle, i, arr) {\n var target = triangle.target;\n var u0 = (target[0][0] - targetTopLeft[0]) / targetResolution;\n var v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution;\n var u1 = (target[1][0] - targetTopLeft[0]) / targetResolution;\n var v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution;\n var u2 = (target[2][0] - targetTopLeft[0]) / targetResolution;\n var v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution;\n context.beginPath();\n context.moveTo(u1, v1);\n context.lineTo(u0, v0);\n context.lineTo(u2, v2);\n context.closePath();\n context.stroke();\n });\n context.restore();\n }\n\n return context.canvas;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/reproj/Tile.js\nvar reproj_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/reproj/Tile\n */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {function(number, number, number, number) : import("../Tile.js").default} FunctionType\n */\n\n/**\n * @classdesc\n * Class encapsulating single reprojected tile.\n * See {@link module:ol/source/TileImage~TileImage}.\n *\n */\n\nvar ReprojTile =\n/** @class */\nfunction (_super) {\n reproj_Tile_extends(ReprojTile, _super);\n /**\n * @param {import("../proj/Projection.js").default} sourceProj Source projection.\n * @param {import("../tilegrid/TileGrid.js").default} sourceTileGrid Source tile grid.\n * @param {import("../proj/Projection.js").default} targetProj Target projection.\n * @param {import("../tilegrid/TileGrid.js").default} targetTileGrid Target tile grid.\n * @param {import("../tilecoord.js").TileCoord} tileCoord Coordinate of the tile.\n * @param {import("../tilecoord.js").TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} gutter Gutter of the source tiles.\n * @param {FunctionType} getTileFunction\n * Function returning source tiles (z, x, y, pixelRatio).\n * @param {number=} opt_errorThreshold Acceptable reprojection error (in px).\n * @param {boolean=} opt_renderEdges Render reprojection edges.\n * @param {object=} opt_contextOptions Properties to set on the canvas context.\n */\n\n\n function ReprojTile(sourceProj, sourceTileGrid, targetProj, targetTileGrid, tileCoord, wrappedTileCoord, pixelRatio, gutter, getTileFunction, opt_errorThreshold, opt_renderEdges, opt_contextOptions) {\n var _this = _super.call(this, tileCoord, TileState.IDLE) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.renderEdges_ = opt_renderEdges !== undefined ? opt_renderEdges : false;\n /**\n * @private\n * @type {object}\n */\n\n _this.contextOptions_ = opt_contextOptions;\n /**\n * @private\n * @type {number}\n */\n\n _this.pixelRatio_ = pixelRatio;\n /**\n * @private\n * @type {number}\n */\n\n _this.gutter_ = gutter;\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n\n _this.canvas_ = null;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.sourceTileGrid_ = sourceTileGrid;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.targetTileGrid_ = targetTileGrid;\n /**\n * @private\n * @type {import("../tilecoord.js").TileCoord}\n */\n\n _this.wrappedTileCoord_ = wrappedTileCoord ? wrappedTileCoord : tileCoord;\n /**\n * @private\n * @type {!Array<import("../Tile.js").default>}\n */\n\n _this.sourceTiles_ = [];\n /**\n * @private\n * @type {?Array<import("../events.js").EventsKey>}\n */\n\n _this.sourcesListenerKeys_ = null;\n /**\n * @private\n * @type {number}\n */\n\n _this.sourceZ_ = 0;\n var targetExtent = targetTileGrid.getTileCoordExtent(_this.wrappedTileCoord_);\n\n var maxTargetExtent = _this.targetTileGrid_.getExtent();\n\n var maxSourceExtent = _this.sourceTileGrid_.getExtent();\n\n var limitedTargetExtent = maxTargetExtent ? getIntersection(targetExtent, maxTargetExtent) : targetExtent;\n\n if (getArea(limitedTargetExtent) === 0) {\n // Tile is completely outside range -> EMPTY\n // TODO: is it actually correct that the source even creates the tile ?\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n var sourceProjExtent = sourceProj.getExtent();\n\n if (sourceProjExtent) {\n if (!maxSourceExtent) {\n maxSourceExtent = sourceProjExtent;\n } else {\n maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);\n }\n }\n\n var targetResolution = targetTileGrid.getResolution(_this.wrappedTileCoord_[0]);\n var sourceResolution = calculateSourceExtentResolution(sourceProj, targetProj, limitedTargetExtent, targetResolution);\n\n if (!isFinite(sourceResolution) || sourceResolution <= 0) {\n // invalid sourceResolution -> EMPTY\n // probably edges of the projections when no extent is defined\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n var errorThresholdInPixels = opt_errorThreshold !== undefined ? opt_errorThreshold : ERROR_THRESHOLD;\n /**\n * @private\n * @type {!import("./Triangulation.js").default}\n */\n\n _this.triangulation_ = new reproj_Triangulation(sourceProj, targetProj, limitedTargetExtent, maxSourceExtent, sourceResolution * errorThresholdInPixels, targetResolution);\n\n if (_this.triangulation_.getTriangles().length === 0) {\n // no valid triangles -> EMPTY\n _this.state = TileState.EMPTY;\n return _this;\n }\n\n _this.sourceZ_ = sourceTileGrid.getZForResolution(sourceResolution);\n\n var sourceExtent = _this.triangulation_.calculateSourceExtent();\n\n if (maxSourceExtent) {\n if (sourceProj.canWrapX()) {\n sourceExtent[1] = math_clamp(sourceExtent[1], maxSourceExtent[1], maxSourceExtent[3]);\n sourceExtent[3] = math_clamp(sourceExtent[3], maxSourceExtent[1], maxSourceExtent[3]);\n } else {\n sourceExtent = getIntersection(sourceExtent, maxSourceExtent);\n }\n }\n\n if (!getArea(sourceExtent)) {\n _this.state = TileState.EMPTY;\n } else {\n var sourceRange = sourceTileGrid.getTileRangeForExtentAndZ(sourceExtent, _this.sourceZ_);\n\n for (var srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {\n for (var srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {\n var tile = getTileFunction(_this.sourceZ_, srcX, srcY, pixelRatio);\n\n if (tile) {\n _this.sourceTiles_.push(tile);\n }\n }\n }\n\n if (_this.sourceTiles_.length === 0) {\n _this.state = TileState.EMPTY;\n }\n }\n\n return _this;\n }\n /**\n * Get the HTML Canvas element for this tile.\n * @return {HTMLCanvasElement} Canvas.\n */\n\n\n ReprojTile.prototype.getImage = function () {\n return this.canvas_;\n };\n /**\n * @private\n */\n\n\n ReprojTile.prototype.reproject_ = function () {\n var sources = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n if (tile && tile.getState() == TileState.LOADED) {\n sources.push({\n extent: this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord),\n image: tile.getImage()\n });\n }\n }.bind(this));\n this.sourceTiles_.length = 0;\n\n if (sources.length === 0) {\n this.state = TileState.ERROR;\n } else {\n var z = this.wrappedTileCoord_[0];\n var size = this.targetTileGrid_.getTileSize(z);\n var width = typeof size === \'number\' ? size : size[0];\n var height = typeof size === \'number\' ? size : size[1];\n var targetResolution = this.targetTileGrid_.getResolution(z);\n var sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);\n var targetExtent = this.targetTileGrid_.getTileCoordExtent(this.wrappedTileCoord_);\n this.canvas_ = render(width, height, this.pixelRatio_, sourceResolution, this.sourceTileGrid_.getExtent(), targetResolution, targetExtent, this.triangulation_, sources, this.gutter_, this.renderEdges_, this.contextOptions_);\n this.state = TileState.LOADED;\n }\n\n this.changed();\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n ReprojTile.prototype.load = function () {\n if (this.state == TileState.IDLE) {\n this.state = TileState.LOADING;\n this.changed();\n var leftToLoad_1 = 0;\n this.sourcesListenerKeys_ = [];\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n\n if (state == TileState.IDLE || state == TileState.LOADING) {\n leftToLoad_1++;\n var sourceListenKey_1 = listen(tile, EventType.CHANGE, function (e) {\n var state = tile.getState();\n\n if (state == TileState.LOADED || state == TileState.ERROR || state == TileState.EMPTY) {\n unlistenByKey(sourceListenKey_1);\n leftToLoad_1--;\n\n if (leftToLoad_1 === 0) {\n this.unlistenSources_();\n this.reproject_();\n }\n }\n }, this);\n this.sourcesListenerKeys_.push(sourceListenKey_1);\n }\n }.bind(this));\n this.sourceTiles_.forEach(function (tile, i, arr) {\n var state = tile.getState();\n\n if (state == TileState.IDLE) {\n tile.load();\n }\n });\n\n if (leftToLoad_1 === 0) {\n setTimeout(this.reproject_.bind(this), 0);\n }\n }\n };\n /**\n * @private\n */\n\n\n ReprojTile.prototype.unlistenSources_ = function () {\n this.sourcesListenerKeys_.forEach(unlistenByKey);\n this.sourcesListenerKeys_ = null;\n };\n\n return ReprojTile;\n}(ol_Tile);\n\n/* harmony default export */ var reproj_Tile = (ReprojTile);\n;// CONCATENATED MODULE: ./node_modules/ol/structs/LRUCache.js\n/**\n * @module ol/structs/LRUCache\n */\n\n/**\n * @typedef {Object} Entry\n * @property {string} key_\n * @property {Object} newer\n * @property {Object} older\n * @property {*} value_\n */\n\n/**\n * @classdesc\n * Implements a Least-Recently-Used cache where the keys do not conflict with\n * Object\'s properties (e.g. \'hasOwnProperty\' is not allowed as a key). Expiring\n * items from the cache is the responsibility of the user.\n *\n * @fires import("../events/Event.js").default\n * @template T\n */\n\nvar LRUCache =\n/** @class */\nfunction () {\n /**\n * @param {number=} opt_highWaterMark High water mark.\n */\n function LRUCache(opt_highWaterMark) {\n /**\n * Desired max cache size after expireCache(). If set to 0, no cache entries\n * will be pruned at all.\n * @type {number}\n */\n this.highWaterMark = opt_highWaterMark !== undefined ? opt_highWaterMark : 2048;\n /**\n * @private\n * @type {number}\n */\n\n this.count_ = 0;\n /**\n * @private\n * @type {!Object<string, Entry>}\n */\n\n this.entries_ = {};\n /**\n * @private\n * @type {?Entry}\n */\n\n this.oldest_ = null;\n /**\n * @private\n * @type {?Entry}\n */\n\n this.newest_ = null;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n LRUCache.prototype.canExpireCache = function () {\n return this.highWaterMark > 0 && this.getCount() > this.highWaterMark;\n };\n /**\n * FIXME empty description for jsdoc\n */\n\n\n LRUCache.prototype.clear = function () {\n this.count_ = 0;\n this.entries_ = {};\n this.oldest_ = null;\n this.newest_ = null;\n };\n /**\n * @param {string} key Key.\n * @return {boolean} Contains key.\n */\n\n\n LRUCache.prototype.containsKey = function (key) {\n return this.entries_.hasOwnProperty(key);\n };\n /**\n * @param {function(T, string, LRUCache<T>): ?} f The function\n * to call for every entry from the oldest to the newer. This function takes\n * 3 arguments (the entry value, the entry key and the LRUCache object).\n * The return value is ignored.\n */\n\n\n LRUCache.prototype.forEach = function (f) {\n var entry = this.oldest_;\n\n while (entry) {\n f(entry.value_, entry.key_, this);\n entry = entry.newer;\n }\n };\n /**\n * @param {string} key Key.\n * @param {*=} opt_options Options (reserverd for subclasses).\n * @return {T} Value.\n */\n\n\n LRUCache.prototype.get = function (key, opt_options) {\n var entry = this.entries_[key];\n asserts_assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n\n if (entry === this.newest_) {\n return entry.value_;\n } else if (entry === this.oldest_) {\n this.oldest_ =\n /** @type {Entry} */\n this.oldest_.newer;\n this.oldest_.older = null;\n } else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n\n entry.newer = null;\n entry.older = this.newest_;\n this.newest_.newer = entry;\n this.newest_ = entry;\n return entry.value_;\n };\n /**\n * Remove an entry from the cache.\n * @param {string} key The entry key.\n * @return {T} The removed entry.\n */\n\n\n LRUCache.prototype.remove = function (key) {\n var entry = this.entries_[key];\n asserts_assert(entry !== undefined, 15); // Tried to get a value for a key that does not exist in the cache\n\n if (entry === this.newest_) {\n this.newest_ =\n /** @type {Entry} */\n entry.older;\n\n if (this.newest_) {\n this.newest_.newer = null;\n }\n } else if (entry === this.oldest_) {\n this.oldest_ =\n /** @type {Entry} */\n entry.newer;\n\n if (this.oldest_) {\n this.oldest_.older = null;\n }\n } else {\n entry.newer.older = entry.older;\n entry.older.newer = entry.newer;\n }\n\n delete this.entries_[key];\n --this.count_;\n return entry.value_;\n };\n /**\n * @return {number} Count.\n */\n\n\n LRUCache.prototype.getCount = function () {\n return this.count_;\n };\n /**\n * @return {Array<string>} Keys.\n */\n\n\n LRUCache.prototype.getKeys = function () {\n var keys = new Array(this.count_);\n var i = 0;\n var entry;\n\n for (entry = this.newest_; entry; entry = entry.older) {\n keys[i++] = entry.key_;\n }\n\n return keys;\n };\n /**\n * @return {Array<T>} Values.\n */\n\n\n LRUCache.prototype.getValues = function () {\n var values = new Array(this.count_);\n var i = 0;\n var entry;\n\n for (entry = this.newest_; entry; entry = entry.older) {\n values[i++] = entry.value_;\n }\n\n return values;\n };\n /**\n * @return {T} Last value.\n */\n\n\n LRUCache.prototype.peekLast = function () {\n return this.oldest_.value_;\n };\n /**\n * @return {string} Last key.\n */\n\n\n LRUCache.prototype.peekLastKey = function () {\n return this.oldest_.key_;\n };\n /**\n * Get the key of the newest item in the cache. Throws if the cache is empty.\n * @return {string} The newest key.\n */\n\n\n LRUCache.prototype.peekFirstKey = function () {\n return this.newest_.key_;\n };\n /**\n * @return {T} value Value.\n */\n\n\n LRUCache.prototype.pop = function () {\n var entry = this.oldest_;\n delete this.entries_[entry.key_];\n\n if (entry.newer) {\n entry.newer.older = null;\n }\n\n this.oldest_ =\n /** @type {Entry} */\n entry.newer;\n\n if (!this.oldest_) {\n this.newest_ = null;\n }\n\n --this.count_;\n return entry.value_;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n\n\n LRUCache.prototype.replace = function (key, value) {\n this.get(key); // update `newest_`\n\n this.entries_[key].value_ = value;\n };\n /**\n * @param {string} key Key.\n * @param {T} value Value.\n */\n\n\n LRUCache.prototype.set = function (key, value) {\n asserts_assert(!(key in this.entries_), 16); // Tried to set a value for a key that is used already\n\n var entry = {\n key_: key,\n newer: null,\n older: this.newest_,\n value_: value\n };\n\n if (!this.newest_) {\n this.oldest_ = entry;\n } else {\n this.newest_.newer = entry;\n }\n\n this.newest_ = entry;\n this.entries_[key] = entry;\n ++this.count_;\n };\n /**\n * Set a maximum number of entries for the cache.\n * @param {number} size Cache size.\n * @api\n */\n\n\n LRUCache.prototype.setSize = function (size) {\n this.highWaterMark = size;\n };\n\n return LRUCache;\n}();\n\n/* harmony default export */ var structs_LRUCache = (LRUCache);\n;// CONCATENATED MODULE: ./node_modules/ol/TileCache.js\nvar TileCache_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/TileCache\n */\n\n\n\n\n\nvar TileCache =\n/** @class */\nfunction (_super) {\n TileCache_extends(TileCache, _super);\n\n function TileCache() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n /**\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileCache.prototype.expireCache = function (usedTiles) {\n while (this.canExpireCache()) {\n var tile = this.peekLast();\n\n if (tile.getKey() in usedTiles) {\n break;\n } else {\n this.pop().release();\n }\n }\n };\n /**\n * Prune all tiles from the cache that don\'t have the same z as the newest tile.\n */\n\n\n TileCache.prototype.pruneExceptNewestZ = function () {\n if (this.getCount() === 0) {\n return;\n }\n\n var key = this.peekFirstKey();\n var tileCoord = fromKey(key);\n var z = tileCoord[0];\n this.forEach(function (tile) {\n if (tile.tileCoord[0] !== z) {\n this.remove(tilecoord_getKey(tile.tileCoord));\n tile.release();\n }\n }.bind(this));\n };\n\n return TileCache;\n}(structs_LRUCache);\n\n/* harmony default export */ var ol_TileCache = (TileCache);\n;// CONCATENATED MODULE: ./node_modules/ol/source/TileEventType.js\n/**\n * @module ol/source/TileEventType\n */\n\n/**\n * @enum {string}\n */\n/* harmony default export */ var TileEventType = ({\n /**\n * Triggered when a tile starts loading.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadstart\n * @api\n */\n TILELOADSTART: \'tileloadstart\',\n\n /**\n * Triggered when a tile finishes loading, either when its data is loaded,\n * or when loading was aborted because the tile is no longer needed.\n * @event module:ol/source/Tile.TileSourceEvent#tileloadend\n * @api\n */\n TILELOADEND: \'tileloadend\',\n\n /**\n * Triggered if tile loading results in an error.\n * @event module:ol/source/Tile.TileSourceEvent#tileloaderror\n * @api\n */\n TILELOADERROR: \'tileloaderror\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/source/Tile.js\nvar source_Tile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/Tile\n */\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize]\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {number} [tilePixelRatio]\n * @property {import("../proj.js").ProjectionLike} [projection]\n * @property {import("./State.js").default} [state]\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n * @property {string} [key]\n * @property {number} [zDirection=0]\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Base class for sources providing images divided into a tile grid.\n * @abstract\n * @api\n */\n\nvar TileSource =\n/** @class */\nfunction (_super) {\n source_Tile_extends(TileSource, _super);\n /**\n * @param {Options} options SourceTile source options.\n */\n\n\n function TileSource(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n attributionsCollapsible: options.attributionsCollapsible,\n projection: options.projection,\n state: options.state,\n wrapX: options.wrapX\n }) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.opaque_ = options.opaque !== undefined ? options.opaque : false;\n /**\n * @private\n * @type {number}\n */\n\n _this.tilePixelRatio_ = options.tilePixelRatio !== undefined ? options.tilePixelRatio : 1;\n /**\n * @protected\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n _this.tileGrid = options.tileGrid !== undefined ? options.tileGrid : null;\n var tileSize = [256, 256];\n var tileGrid = options.tileGrid;\n\n if (tileGrid) {\n toSize(tileGrid.getTileSize(tileGrid.getMinZoom()), tileSize);\n }\n /**\n * @protected\n * @type {import("../TileCache.js").default}\n */\n\n\n _this.tileCache = new ol_TileCache(options.cacheSize || 0);\n /**\n * @protected\n * @type {import("../size.js").Size}\n */\n\n _this.tmpSize = [0, 0];\n /**\n * @private\n * @type {string}\n */\n\n _this.key_ = options.key || \'\';\n /**\n * @protected\n * @type {import("../Tile.js").Options}\n */\n\n _this.tileOptions = {\n transition: options.transition\n };\n /**\n * zDirection hint, read by the renderer. Indicates which resolution should be used\n * by a renderer if the views resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @type {number}\n */\n\n _this.zDirection = options.zDirection ? options.zDirection : 0;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n TileSource.prototype.canExpireCache = function () {\n return this.tileCache.canExpireCache();\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileSource.prototype.expireCache = function (projection, usedTiles) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (tileCache) {\n tileCache.expireCache(usedTiles);\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {number} z Zoom level.\n * @param {import("../TileRange.js").default} tileRange Tile range.\n * @param {function(import("../Tile.js").default):(boolean|void)} callback Called with each\n * loaded tile. If the callback returns `false`, the tile will not be\n * considered loaded.\n * @return {boolean} The tile range is fully covered with loaded tiles.\n */\n\n\n TileSource.prototype.forEachLoadedTile = function (projection, z, tileRange, callback) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (!tileCache) {\n return false;\n }\n\n var covered = true;\n var tile, tileCoordKey, loaded;\n\n for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {\n for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {\n tileCoordKey = getKeyZXY(z, x, y);\n loaded = false;\n\n if (tileCache.containsKey(tileCoordKey)) {\n tile =\n /** @type {!import("../Tile.js").default} */\n tileCache.get(tileCoordKey);\n loaded = tile.getState() === TileState.LOADED;\n\n if (loaded) {\n loaded = callback(tile) !== false;\n }\n }\n\n if (!loaded) {\n covered = false;\n }\n }\n }\n\n return covered;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {number} Gutter.\n */\n\n\n TileSource.prototype.getGutterForProjection = function (projection) {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n * @protected\n */\n\n\n TileSource.prototype.getKey = function () {\n return this.key_;\n };\n /**\n * Set the value to be used as the key for all tiles in the source.\n * @param {string} key The key for tiles.\n * @protected\n */\n\n\n TileSource.prototype.setKey = function (key) {\n if (this.key_ !== key) {\n this.key_ = key;\n this.changed();\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {boolean} Opaque.\n */\n\n\n TileSource.prototype.getOpaque = function (projection) {\n return this.opaque_;\n };\n /**\n * @return {Array<number>} Resolutions.\n */\n\n\n TileSource.prototype.getResolutions = function () {\n return this.tileGrid.getResolutions();\n };\n /**\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n */\n\n\n TileSource.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n return util_abstract();\n };\n /**\n * Return the tile grid of the tile source.\n * @return {import("../tilegrid/TileGrid.js").default} Tile grid.\n * @api\n */\n\n\n TileSource.prototype.getTileGrid = function () {\n return this.tileGrid;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n TileSource.prototype.getTileGridForProjection = function (projection) {\n if (!this.tileGrid) {\n return getForProjection(projection);\n } else {\n return this.tileGrid;\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../TileCache.js").default} Tile cache.\n * @protected\n */\n\n\n TileSource.prototype.getTileCacheForProjection = function (projection) {\n asserts_assert(equivalent(this.getProjection(), projection), 68 // A VectorTile source can only be rendered if it has a projection compatible with the view projection.\n );\n return this.tileCache;\n };\n /**\n * Get the tile pixel ratio for this source. Subclasses may override this\n * method, which is meant to return a supported pixel ratio that matches the\n * provided `pixelRatio` as close as possible.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Tile pixel ratio.\n */\n\n\n TileSource.prototype.getTilePixelRatio = function (pixelRatio) {\n return this.tilePixelRatio_;\n };\n /**\n * @param {number} z Z.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../size.js").Size} Tile size.\n */\n\n\n TileSource.prototype.getTilePixelSize = function (z, pixelRatio, projection) {\n var tileGrid = this.getTileGridForProjection(projection);\n var tilePixelRatio = this.getTilePixelRatio(pixelRatio);\n var tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n\n if (tilePixelRatio == 1) {\n return tileSize;\n } else {\n return size_scale(tileSize, tilePixelRatio, this.tmpSize);\n }\n };\n /**\n * Returns a tile coordinate wrapped around the x-axis. When the tile coordinate\n * is outside the resolution and extent range of the tile grid, `null` will be\n * returned.\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("../proj/Projection.js").default=} opt_projection Projection.\n * @return {import("../tilecoord.js").TileCoord} Tile coordinate to be passed to the tileUrlFunction or\n * null if no tile URL should be created for the passed `tileCoord`.\n */\n\n\n TileSource.prototype.getTileCoordForTileUrlFunction = function (tileCoord, opt_projection) {\n var projection = opt_projection !== undefined ? opt_projection : this.getProjection();\n var tileGrid = this.getTileGridForProjection(projection);\n\n if (this.getWrapX() && projection.isGlobal()) {\n tileCoord = tilegrid_wrapX(tileGrid, tileCoord, projection);\n }\n\n return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;\n };\n /**\n * Remove all cached tiles from the source. The next render cycle will fetch new tiles.\n * @api\n */\n\n\n TileSource.prototype.clear = function () {\n this.tileCache.clear();\n };\n\n TileSource.prototype.refresh = function () {\n this.clear();\n\n _super.prototype.refresh.call(this);\n };\n /**\n * Increases the cache size if needed\n * @param {number} tileCount Minimum number of tiles needed.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n TileSource.prototype.updateCacheSize = function (tileCount, projection) {\n var tileCache = this.getTileCacheForProjection(projection);\n\n if (tileCount > tileCache.highWaterMark) {\n tileCache.highWaterMark = tileCount;\n }\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @abstract\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n TileSource.prototype.useTile = function (z, x, y, projection) {};\n\n return TileSource;\n}(source_Source);\n/**\n * @classdesc\n * Events emitted by {@link module:ol/source/Tile~TileSource} instances are instances of this\n * type.\n */\n\n\nvar TileSourceEvent =\n/** @class */\nfunction (_super) {\n source_Tile_extends(TileSourceEvent, _super);\n /**\n * @param {string} type Type.\n * @param {import("../Tile.js").default} tile The tile.\n */\n\n\n function TileSourceEvent(type, tile) {\n var _this = _super.call(this, type) || this;\n /**\n * The tile related to the event.\n * @type {import("../Tile.js").default}\n * @api\n */\n\n\n _this.tile = tile;\n return _this;\n }\n\n return TileSourceEvent;\n}(Event);\n\n\n/* harmony default export */ var source_Tile = (TileSource);\n;// CONCATENATED MODULE: ./node_modules/ol/tileurlfunction.js\n/**\n * @module ol/tileurlfunction\n */\n\n\n\n/**\n * @param {string} template Template.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTemplate(template, tileGrid) {\n var zRegEx = /\\{z\\}/g;\n var xRegEx = /\\{x\\}/g;\n var yRegEx = /\\{y\\}/g;\n var dashYRegEx = /\\{-y\\}/g;\n return (\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n } else {\n return template.replace(zRegEx, tileCoord[0].toString()).replace(xRegEx, tileCoord[1].toString()).replace(yRegEx, tileCoord[2].toString()).replace(dashYRegEx, function () {\n var z = tileCoord[0];\n var range = tileGrid.getFullTileRange(z);\n asserts_assert(range, 55); // The {-y} placeholder requires a tile grid with extent\n\n var y = range.getHeight() - tileCoord[2] - 1;\n return y.toString();\n });\n }\n }\n );\n}\n/**\n * @param {Array<string>} templates Templates.\n * @param {import("./tilegrid/TileGrid.js").default} tileGrid Tile grid.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTemplates(templates, tileGrid) {\n var len = templates.length;\n var tileUrlFunctions = new Array(len);\n\n for (var i = 0; i < len; ++i) {\n tileUrlFunctions[i] = createFromTemplate(templates[i], tileGrid);\n }\n\n return createFromTileUrlFunctions(tileUrlFunctions);\n}\n/**\n * @param {Array<import("./Tile.js").UrlFunction>} tileUrlFunctions Tile URL Functions.\n * @return {import("./Tile.js").UrlFunction} Tile URL function.\n */\n\nfunction createFromTileUrlFunctions(tileUrlFunctions) {\n if (tileUrlFunctions.length === 1) {\n return tileUrlFunctions[0];\n }\n\n return (\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile Coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n function (tileCoord, pixelRatio, projection) {\n if (!tileCoord) {\n return undefined;\n } else {\n var h = hash(tileCoord);\n var index = math_modulo(h, tileUrlFunctions.length);\n return tileUrlFunctions[index](tileCoord, pixelRatio, projection);\n }\n }\n );\n}\n/**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("./proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n\nfunction nullTileUrlFunction(tileCoord, pixelRatio, projection) {\n return undefined;\n}\n/**\n * @param {string} url URL.\n * @return {Array<string>} Array of urls.\n */\n\nfunction expandUrl(url) {\n var urls = [];\n var match = /\\{([a-z])-([a-z])\\}/.exec(url);\n\n if (match) {\n // char range\n var startCharCode = match[1].charCodeAt(0);\n var stopCharCode = match[2].charCodeAt(0);\n var charCode = void 0;\n\n for (charCode = startCharCode; charCode <= stopCharCode; ++charCode) {\n urls.push(url.replace(match[0], String.fromCharCode(charCode)));\n }\n\n return urls;\n }\n\n match = /\\{(\\d+)-(\\d+)\\}/.exec(url);\n\n if (match) {\n // number range\n var stop_1 = parseInt(match[2], 10);\n\n for (var i = parseInt(match[1], 10); i <= stop_1; i++) {\n urls.push(url.replace(match[0], i.toString()));\n }\n\n return urls;\n }\n\n urls.push(url);\n return urls;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/UrlTile.js\nvar UrlTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/UrlTile\n */\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions]\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize]\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import("../proj.js").ProjectionLike} [projection]\n * @property {import("./State.js").default} [state]\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid]\n * @property {import("../Tile.js").LoadFunction} tileLoadFunction\n * @property {number} [tilePixelRatio]\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction]\n * @property {string} [url]\n * @property {Array<string>} [urls]\n * @property {boolean} [wrapX=true]\n * @property {number} [transition]\n * @property {string} [key]\n * @property {number} [zDirection=0]\n */\n\n/**\n * @classdesc\n * Base class for sources providing tiles divided into a tile grid over http.\n *\n * @fires import("./Tile.js").TileSourceEvent\n */\n\nvar UrlTile =\n/** @class */\nfunction (_super) {\n UrlTile_extends(UrlTile, _super);\n /**\n * @param {Options} options Image tile options.\n */\n\n\n function UrlTile(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tilePixelRatio: options.tilePixelRatio,\n wrapX: options.wrapX,\n transition: options.transition,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection\n }) || this;\n /**\n * @private\n * @type {boolean}\n */\n\n\n _this.generateTileUrlFunction_ = _this.tileUrlFunction === UrlTile.prototype.tileUrlFunction;\n /**\n * @protected\n * @type {import("../Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction = options.tileLoadFunction;\n\n if (options.tileUrlFunction) {\n _this.tileUrlFunction = options.tileUrlFunction;\n }\n /**\n * @protected\n * @type {!Array<string>|null}\n */\n\n\n _this.urls = null;\n\n if (options.urls) {\n _this.setUrls(options.urls);\n } else if (options.url) {\n _this.setUrl(options.url);\n }\n /**\n * @private\n * @type {!Object<string, boolean>}\n */\n\n\n _this.tileLoadingKeys_ = {};\n return _this;\n }\n /**\n * Return the tile load function of the source.\n * @return {import("../Tile.js").LoadFunction} TileLoadFunction\n * @api\n */\n\n\n UrlTile.prototype.getTileLoadFunction = function () {\n return this.tileLoadFunction;\n };\n /**\n * Return the tile URL function of the source.\n * @return {import("../Tile.js").UrlFunction} TileUrlFunction\n * @api\n */\n\n\n UrlTile.prototype.getTileUrlFunction = function () {\n return Object.getPrototypeOf(this).tileUrlFunction === this.tileUrlFunction ? this.tileUrlFunction.bind(this) : this.tileUrlFunction;\n };\n /**\n * Return the URLs used for this source.\n * When a tileUrlFunction is used instead of url or urls,\n * null will be returned.\n * @return {!Array<string>|null} URLs.\n * @api\n */\n\n\n UrlTile.prototype.getUrls = function () {\n return this.urls;\n };\n /**\n * Handle tile change events.\n * @param {import("../events/Event.js").default} event Event.\n * @protected\n */\n\n\n UrlTile.prototype.handleTileChange = function (event) {\n var tile =\n /** @type {import("../Tile.js").default} */\n event.target;\n var uid = getUid(tile);\n var tileState = tile.getState();\n var type;\n\n if (tileState == TileState.LOADING) {\n this.tileLoadingKeys_[uid] = true;\n type = TileEventType.TILELOADSTART;\n } else if (uid in this.tileLoadingKeys_) {\n delete this.tileLoadingKeys_[uid];\n type = tileState == TileState.ERROR ? TileEventType.TILELOADERROR : tileState == TileState.LOADED ? TileEventType.TILELOADEND : undefined;\n }\n\n if (type != undefined) {\n this.dispatchEvent(new TileSourceEvent(type, tile));\n }\n };\n /**\n * Set the tile load function of the source.\n * @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @api\n */\n\n\n UrlTile.prototype.setTileLoadFunction = function (tileLoadFunction) {\n this.tileCache.clear();\n this.tileLoadFunction = tileLoadFunction;\n this.changed();\n };\n /**\n * Set the tile URL function of the source.\n * @param {import("../Tile.js").UrlFunction} tileUrlFunction Tile URL function.\n * @param {string=} key Optional new tile key for the source.\n * @api\n */\n\n\n UrlTile.prototype.setTileUrlFunction = function (tileUrlFunction, key) {\n this.tileUrlFunction = tileUrlFunction;\n this.tileCache.pruneExceptNewestZ();\n\n if (typeof key !== \'undefined\') {\n this.setKey(key);\n } else {\n this.changed();\n }\n };\n /**\n * Set the URL to use for requests.\n * @param {string} url URL.\n * @api\n */\n\n\n UrlTile.prototype.setUrl = function (url) {\n var urls = expandUrl(url);\n this.urls = urls;\n this.setUrls(urls);\n };\n /**\n * Set the URLs to use for requests.\n * @param {Array<string>} urls URLs.\n * @api\n */\n\n\n UrlTile.prototype.setUrls = function (urls) {\n this.urls = urls;\n var key = urls.join(\'\\n\');\n\n if (this.generateTileUrlFunction_) {\n this.setTileUrlFunction(createFromTemplates(urls, this.tileGrid), key);\n } else {\n this.setKey(key);\n }\n };\n /**\n * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {string|undefined} Tile URL.\n */\n\n\n UrlTile.prototype.tileUrlFunction = function (tileCoord, pixelRatio, projection) {\n return undefined;\n };\n /**\n * Marks a tile coord as being used, without triggering a load.\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n */\n\n\n UrlTile.prototype.useTile = function (z, x, y) {\n var tileCoordKey = getKeyZXY(z, x, y);\n\n if (this.tileCache.containsKey(tileCoordKey)) {\n this.tileCache.get(tileCoordKey);\n }\n };\n\n return UrlTile;\n}(source_Tile);\n\n/* harmony default export */ var source_UrlTile = (UrlTile);\n;// CONCATENATED MODULE: ./node_modules/ol/source/TileImage.js\nvar TileImage_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/source/TileImage\n */\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Enable image smoothing.\n * @property {boolean} [opaque=false] Whether the layer is opaque.\n * @property {import("../proj.js").ProjectionLike} [projection] Projection. Default is the view projection.\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {import("./State.js").default} [state] Source state.\n * @property {typeof import("../ImageTile.js").default} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/ImageTile~ImageTile}.\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number} [tilePixelRatio=1] The pixel ratio used by the tile service. For example, if the tile\n * service advertizes 256px by 256px tiles but actually sends 512px\n * by 512px images (for retina/hidpi devices) then `tilePixelRatio`\n * should be set to `2`.\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX] Whether to wrap the world horizontally. The default, is to\n * request out-of-bounds tiles from the server. When set to `false`, only one\n * world will be rendered. When set to `true`, tiles will be requested for one\n * world only, but they will be wrapped horizontally to render multiple worlds.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n * @property {string} [key] Optional tile key for proper cache fetching\n * @property {number} [zDirection=0] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n */\n\n/**\n * @classdesc\n * Base class for sources providing images divided into a tile grid.\n *\n * @fires import("./Tile.js").TileSourceEvent\n * @api\n */\n\nvar TileImage =\n/** @class */\nfunction (_super) {\n TileImage_extends(TileImage, _super);\n /**\n * @param {!Options} options Image tile options.\n */\n\n\n function TileImage(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n opaque: options.opaque,\n projection: options.projection,\n state: options.state,\n tileGrid: options.tileGrid,\n tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultTileLoadFunction,\n tilePixelRatio: options.tilePixelRatio,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX,\n transition: options.transition,\n key: options.key,\n attributionsCollapsible: options.attributionsCollapsible,\n zDirection: options.zDirection\n }) || this;\n /**\n * @protected\n * @type {?string}\n */\n\n\n _this.crossOrigin = options.crossOrigin !== undefined ? options.crossOrigin : null;\n /**\n * @protected\n * @type {typeof ImageTile}\n */\n\n _this.tileClass = options.tileClass !== undefined ? options.tileClass : ol_ImageTile;\n /**\n * @protected\n * @type {!Object<string, TileCache>}\n */\n\n _this.tileCacheForProjection = {};\n /**\n * @protected\n * @type {!Object<string, import("../tilegrid/TileGrid.js").default>}\n */\n\n _this.tileGridForProjection = {};\n /**\n * @private\n * @type {number|undefined}\n */\n\n _this.reprojectionErrorThreshold_ = options.reprojectionErrorThreshold;\n /**\n * @private\n * @type {object|undefined}\n */\n\n _this.contextOptions_ = options.imageSmoothing === false ? IMAGE_SMOOTHING_DISABLED : undefined;\n /**\n * @private\n * @type {boolean}\n */\n\n _this.renderReprojectionEdges_ = false;\n return _this;\n }\n /**\n * @return {boolean} Can expire cache.\n */\n\n\n TileImage.prototype.canExpireCache = function () {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.canExpireCache.call(this);\n }\n\n if (this.tileCache.canExpireCache()) {\n return true;\n } else {\n for (var key in this.tileCacheForProjection) {\n if (this.tileCacheForProjection[key].canExpireCache()) {\n return true;\n }\n }\n }\n\n return false;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n TileImage.prototype.expireCache = function (projection, usedTiles) {\n if (!ENABLE_RASTER_REPROJECTION) {\n _super.prototype.expireCache.call(this, projection, usedTiles);\n\n return;\n }\n\n var usedTileCache = this.getTileCacheForProjection(projection);\n this.tileCache.expireCache(this.tileCache == usedTileCache ? usedTiles : {});\n\n for (var id in this.tileCacheForProjection) {\n var tileCache = this.tileCacheForProjection[id];\n tileCache.expireCache(tileCache == usedTileCache ? usedTiles : {});\n }\n };\n /**\n * @return {Object|undefined} Context options.\n */\n\n\n TileImage.prototype.getContextOptions = function () {\n return this.contextOptions_;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {number} Gutter.\n */\n\n\n TileImage.prototype.getGutterForProjection = function (projection) {\n if (ENABLE_RASTER_REPROJECTION && this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n return 0;\n } else {\n return this.getGutter();\n }\n };\n /**\n * @return {number} Gutter.\n */\n\n\n TileImage.prototype.getGutter = function () {\n return 0;\n };\n /**\n * Return the key to be used for all tiles in the source.\n * @return {string} The key for all tiles.\n * @protected\n */\n\n\n TileImage.prototype.getKey = function () {\n return _super.prototype.getKey.call(this) + (this.contextOptions_ ? \'\\n\' + JSON.stringify(this.contextOptions_) : \'\');\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {boolean} Opaque.\n */\n\n\n TileImage.prototype.getOpaque = function (projection) {\n if (ENABLE_RASTER_REPROJECTION && this.getProjection() && projection && !equivalent(this.getProjection(), projection)) {\n return false;\n } else {\n return _super.prototype.getOpaque.call(this, projection);\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n TileImage.prototype.getTileGridForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileGridForProjection.call(this, projection);\n }\n\n var thisProj = this.getProjection();\n\n if (this.tileGrid && (!thisProj || equivalent(thisProj, projection))) {\n return this.tileGrid;\n } else {\n var projKey = getUid(projection);\n\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] = getForProjection(projection);\n }\n\n return this.tileGridForProjection[projKey];\n }\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../TileCache.js").default} Tile cache.\n */\n\n\n TileImage.prototype.getTileCacheForProjection = function (projection) {\n if (!ENABLE_RASTER_REPROJECTION) {\n return _super.prototype.getTileCacheForProjection.call(this, projection);\n }\n\n var thisProj = this.getProjection();\n\n if (!thisProj || equivalent(thisProj, projection)) {\n return this.tileCache;\n } else {\n var projKey = getUid(projection);\n\n if (!(projKey in this.tileCacheForProjection)) {\n this.tileCacheForProjection[projKey] = new ol_TileCache(this.tileCache.highWaterMark);\n }\n\n return this.tileCacheForProjection[projKey];\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {string} key The key set on the tile.\n * @return {!import("../Tile.js").default} Tile.\n * @private\n */\n\n\n TileImage.prototype.createTile_ = function (z, x, y, pixelRatio, projection, key) {\n var tileCoord = [z, x, y];\n var urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var tileUrl = urlTileCoord ? this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;\n var tile = new this.tileClass(tileCoord, tileUrl !== undefined ? TileState.IDLE : TileState.EMPTY, tileUrl !== undefined ? tileUrl : \'\', this.crossOrigin, this.tileLoadFunction, this.tileOptions);\n tile.key = key;\n tile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));\n return tile;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n */\n\n\n TileImage.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n var sourceProjection = this.getProjection();\n\n if (!ENABLE_RASTER_REPROJECTION || !sourceProjection || !projection || equivalent(sourceProjection, projection)) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection || projection);\n } else {\n var cache = this.getTileCacheForProjection(projection);\n var tileCoord = [z, x, y];\n var tile = void 0;\n var tileCoordKey = tilecoord_getKey(tileCoord);\n\n if (cache.containsKey(tileCoordKey)) {\n tile = cache.get(tileCoordKey);\n }\n\n var key = this.getKey();\n\n if (tile && tile.key == key) {\n return tile;\n } else {\n var sourceTileGrid = this.getTileGridForProjection(sourceProjection);\n var targetTileGrid = this.getTileGridForProjection(projection);\n var wrappedTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var newTile = new reproj_Tile(sourceProjection, sourceTileGrid, projection, targetTileGrid, tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio), this.getGutter(), function (z, x, y, pixelRatio) {\n return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);\n }.bind(this), this.reprojectionErrorThreshold_, this.renderReprojectionEdges_, this.contextOptions_);\n newTile.key = key;\n\n if (tile) {\n newTile.interimTile = tile;\n newTile.refreshInterimChain();\n cache.replace(tileCoordKey, newTile);\n } else {\n cache.set(tileCoordKey, newTile);\n }\n\n return newTile;\n }\n }\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {!import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../Tile.js").default} Tile.\n * @protected\n */\n\n\n TileImage.prototype.getTileInternal = function (z, x, y, pixelRatio, projection) {\n var tile = null;\n var tileCoordKey = getKeyZXY(z, x, y);\n var key = this.getKey();\n\n if (!this.tileCache.containsKey(tileCoordKey)) {\n tile = this.createTile_(z, x, y, pixelRatio, projection, key);\n this.tileCache.set(tileCoordKey, tile);\n } else {\n tile = this.tileCache.get(tileCoordKey);\n\n if (tile.key != key) {\n // The source\'s params changed. If the tile has an interim tile and if we\n // can use it then we use it. Otherwise we create a new tile. In both\n // cases we attempt to assign an interim tile to the new tile.\n var interimTile = tile;\n tile = this.createTile_(z, x, y, pixelRatio, projection, key); //make the new tile the head of the list,\n\n if (interimTile.getState() == TileState.IDLE) {\n //the old tile hasn\'t begun loading yet, and is now outdated, so we can simply discard it\n tile.interimTile = interimTile.interimTile;\n } else {\n tile.interimTile = interimTile;\n }\n\n tile.refreshInterimChain();\n this.tileCache.replace(tileCoordKey, tile);\n }\n }\n\n return tile;\n };\n /**\n * Sets whether to render reprojection edges or not (usually for debugging).\n * @param {boolean} render Render the edges.\n * @api\n */\n\n\n TileImage.prototype.setRenderReprojectionEdges = function (render) {\n if (!ENABLE_RASTER_REPROJECTION || this.renderReprojectionEdges_ == render) {\n return;\n }\n\n this.renderReprojectionEdges_ = render;\n\n for (var id in this.tileCacheForProjection) {\n this.tileCacheForProjection[id].clear();\n }\n\n this.changed();\n };\n /**\n * Sets the tile grid to use when reprojecting the tiles to the given\n * projection instead of the default tile grid for the projection.\n *\n * This can be useful when the default tile grid cannot be created\n * (e.g. projection has no extent defined) or\n * for optimization reasons (custom tile size, resolutions, ...).\n *\n * @param {import("../proj.js").ProjectionLike} projection Projection.\n * @param {import("../tilegrid/TileGrid.js").default} tilegrid Tile grid to use for the projection.\n * @api\n */\n\n\n TileImage.prototype.setTileGridForProjection = function (projection, tilegrid) {\n if (ENABLE_RASTER_REPROJECTION) {\n var proj = proj_get(projection);\n\n if (proj) {\n var projKey = getUid(proj);\n\n if (!(projKey in this.tileGridForProjection)) {\n this.tileGridForProjection[projKey] = tilegrid;\n }\n }\n }\n };\n\n return TileImage;\n}(source_UrlTile);\n/**\n * @param {ImageTile} imageTile Image tile.\n * @param {string} src Source.\n */\n\n\nfunction defaultTileLoadFunction(imageTile, src) {\n /** @type {HTMLImageElement|HTMLVideoElement} */\n imageTile.getImage().src = src;\n}\n\n/* harmony default export */ var source_TileImage = (TileImage);\n;// CONCATENATED MODULE: ./node_modules/ol/net.js\n/**\n * @module ol/net\n */\n\n/**\n * Simple JSONP helper. Supports error callbacks and a custom callback param.\n * The error callback will be called when no JSONP is executed after 10 seconds.\n *\n * @param {string} url Request url. A \'callback\' query parameter will be\n * appended.\n * @param {Function} callback Callback on success.\n * @param {function()=} opt_errback Callback on error.\n * @param {string=} opt_callbackParam Custom query parameter for the JSONP\n * callback. Default is \'callback\'.\n */\n\nfunction jsonp(url, callback, opt_errback, opt_callbackParam) {\n var script = document.createElement(\'script\');\n var key = \'olc_\' + getUid(callback);\n\n function cleanup() {\n delete window[key];\n script.parentNode.removeChild(script);\n }\n\n script.async = true;\n script.src = url + (url.indexOf(\'?\') == -1 ? \'?\' : \'&\') + (opt_callbackParam || \'callback\') + \'=\' + key;\n var timer = setTimeout(function () {\n cleanup();\n\n if (opt_errback) {\n opt_errback();\n }\n }, 10000);\n\n window[key] = function (data) {\n clearTimeout(timer);\n cleanup();\n callback(data);\n };\n\n document.getElementsByTagName(\'head\')[0].appendChild(script);\n}\n;// CONCATENATED MODULE: ./node_modules/ol/source/TileJSON.js\n/**\n * @module ol/source/TileJSON\n */\n// FIXME check order of async callbacks\nvar TileJSON_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * See https://mapbox.com/developers/api/.\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Config\n * @property {string} [name] The name.\n * @property {string} [description] The description.\n * @property {string} [version] The version.\n * @property {string} [attribution] The attribution.\n * @property {string} [template] The template.\n * @property {string} [legend] The legend.\n * @property {string} [scheme] The scheme.\n * @property {Array<string>} tiles The tile URL templates.\n * @property {Array<string>} [grids] Optional grids.\n * @property {number} [minzoom] Minimum zoom level.\n * @property {number} [maxzoom] Maximum zoom level.\n * @property {Array<number>} [bounds] Optional bounds.\n * @property {Array<number>} [center] Optional center.\n */\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least the number of tiles in the viewport.\n * @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that\n * you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.\n * @property {boolean} [imageSmoothing=true] Enable image smoothing.\n * @property {boolean} [jsonp=false] Use JSONP with callback to load the TileJSON.\n * Useful when the server does not support CORS..\n * @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).\n * Higher values can increase reprojection performance, but decrease precision.\n * @property {Config} [tileJSON] TileJSON configuration for this source.\n * If not provided, `url` must be configured.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is\n * ```js\n * function(imageTile, src) {\n * imageTile.getImage().src = src;\n * };\n * ```\n * @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service.\n * Note: `tileSize` and other non-standard TileJSON properties are currently ignored.\n * @property {string} [url] URL to the TileJSON file. If not provided, `tileJSON` must be configured.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * @property {number} [transition] Duration of the opacity transition for rendering.\n * To disable the opacity transition, pass `transition: 0`.\n */\n\n/**\n * @classdesc\n * Layer source for tile data in TileJSON format.\n * @api\n */\n\nvar TileJSON =\n/** @class */\nfunction (_super) {\n TileJSON_extends(TileJSON, _super);\n /**\n * @param {Options} options TileJSON options.\n */\n\n\n function TileJSON(options) {\n var _this = _super.call(this, {\n attributions: options.attributions,\n cacheSize: options.cacheSize,\n crossOrigin: options.crossOrigin,\n imageSmoothing: options.imageSmoothing,\n projection: proj_get(\'EPSG:3857\'),\n reprojectionErrorThreshold: options.reprojectionErrorThreshold,\n state: State.LOADING,\n tileLoadFunction: options.tileLoadFunction,\n wrapX: options.wrapX !== undefined ? options.wrapX : true,\n transition: options.transition\n }) || this;\n /**\n * @type {Config}\n * @private\n */\n\n\n _this.tileJSON_ = null;\n /**\n * @type {number|import("../size.js").Size}\n * @private\n */\n\n _this.tileSize_ = options.tileSize;\n\n if (options.url) {\n if (options.jsonp) {\n jsonp(options.url, _this.handleTileJSONResponse.bind(_this), _this.handleTileJSONError.bind(_this));\n } else {\n var client = new XMLHttpRequest();\n client.addEventListener(\'load\', _this.onXHRLoad_.bind(_this));\n client.addEventListener(\'error\', _this.onXHRError_.bind(_this));\n client.open(\'GET\', options.url);\n client.send();\n }\n } else if (options.tileJSON) {\n _this.handleTileJSONResponse(options.tileJSON);\n } else {\n asserts_assert(false, 51); // Either `url` or `tileJSON` options must be provided\n }\n\n return _this;\n }\n /**\n * @private\n * @param {Event} event The load event.\n */\n\n\n TileJSON.prototype.onXHRLoad_ = function (event) {\n var client =\n /** @type {XMLHttpRequest} */\n event.target; // status will be 0 for file:// urls\n\n if (!client.status || client.status >= 200 && client.status < 300) {\n var response = void 0;\n\n try {\n response =\n /** @type {TileJSON} */\n JSON.parse(client.responseText);\n } catch (err) {\n this.handleTileJSONError();\n return;\n }\n\n this.handleTileJSONResponse(response);\n } else {\n this.handleTileJSONError();\n }\n };\n /**\n * @private\n * @param {Event} event The error event.\n */\n\n\n TileJSON.prototype.onXHRError_ = function (event) {\n this.handleTileJSONError();\n };\n /**\n * @return {Config} The tilejson object.\n * @api\n */\n\n\n TileJSON.prototype.getTileJSON = function () {\n return this.tileJSON_;\n };\n /**\n * @protected\n * @param {Config} tileJSON Tile JSON.\n */\n\n\n TileJSON.prototype.handleTileJSONResponse = function (tileJSON) {\n var epsg4326Projection = proj_get(\'EPSG:4326\');\n var sourceProjection = this.getProjection();\n var extent;\n\n if (tileJSON[\'bounds\'] !== undefined) {\n var transform = getTransformFromProjections(epsg4326Projection, sourceProjection);\n extent = applyTransform(tileJSON[\'bounds\'], transform);\n }\n\n var minZoom = tileJSON[\'minzoom\'] || 0;\n var maxZoom = tileJSON[\'maxzoom\'] || 22;\n var tileGrid = createXYZ({\n extent: extentFromProjection(sourceProjection),\n maxZoom: maxZoom,\n minZoom: minZoom,\n tileSize: this.tileSize_\n });\n this.tileGrid = tileGrid;\n this.tileUrlFunction = createFromTemplates(tileJSON[\'tiles\'], tileGrid);\n\n if (tileJSON[\'attribution\'] !== undefined && !this.getAttributions()) {\n var attributionExtent_1 = extent !== undefined ? extent : epsg4326Projection.getExtent();\n this.setAttributions(function (frameState) {\n if (intersects(attributionExtent_1, frameState.extent)) {\n return [tileJSON[\'attribution\']];\n }\n\n return null;\n });\n }\n\n this.tileJSON_ = tileJSON;\n this.setState(State.READY);\n };\n /**\n * @protected\n */\n\n\n TileJSON.prototype.handleTileJSONError = function () {\n this.setState(State.ERROR);\n };\n\n return TileJSON;\n}(source_TileImage);\n\n/* harmony default export */ var source_TileJSON = (TileJSON);\n;// CONCATENATED MODULE: ./node_modules/ol/VectorTile.js\nvar ol_VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/VectorTile\n */\n\n\n\n\n\nvar VectorTile_VectorTile =\n/** @class */\nfunction (_super) {\n ol_VectorTile_extends(VectorTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {string} src Data source url.\n * @param {import("./format/Feature.js").default} format Feature format.\n * @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.\n * @param {import("./Tile.js").Options=} opt_options Tile options.\n */\n\n\n function VectorTile(tileCoord, state, src, format, tileLoadFunction, opt_options) {\n var _this = _super.call(this, tileCoord, state, opt_options) || this;\n /**\n * Extent of this tile; set by the source.\n * @type {import("./extent.js").Extent}\n */\n\n\n _this.extent = null;\n /**\n * @private\n * @type {import("./format/Feature.js").default}\n */\n\n _this.format_ = format;\n /**\n * @private\n * @type {Array<import("./Feature.js").default>}\n */\n\n _this.features_ = null;\n /**\n * @private\n * @type {import("./featureloader.js").FeatureLoader}\n */\n\n _this.loader_;\n /**\n * Feature projection of this tile; set by the source.\n * @type {import("./proj/Projection.js").default}\n */\n\n _this.projection = null;\n /**\n * Resolution of this tile; set by the source.\n * @type {number}\n */\n\n _this.resolution;\n /**\n * @private\n * @type {import("./Tile.js").LoadFunction}\n */\n\n _this.tileLoadFunction_ = tileLoadFunction;\n /**\n * @private\n * @type {string}\n */\n\n _this.url_ = src;\n _this.key = src;\n return _this;\n }\n /**\n * Get the feature format assigned for reading this tile\'s features.\n * @return {import("./format/Feature.js").default} Feature format.\n * @api\n */\n\n\n VectorTile.prototype.getFormat = function () {\n return this.format_;\n };\n /**\n * Get the features for this tile. Geometries will be in the view projection.\n * @return {Array<import("./Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n VectorTile.prototype.getFeatures = function () {\n return this.features_;\n };\n /**\n * Load not yet loaded URI.\n */\n\n\n VectorTile.prototype.load = function () {\n if (this.state == TileState.IDLE) {\n this.setState(TileState.LOADING);\n this.tileLoadFunction_(this, this.url_);\n\n if (this.loader_) {\n this.loader_(this.extent, this.resolution, this.projection);\n }\n }\n };\n /**\n * Handler for successful tile load.\n * @param {Array<import("./Feature.js").default>} features The loaded features.\n * @param {import("./proj/Projection.js").default} dataProjection Data projection.\n */\n\n\n VectorTile.prototype.onLoad = function (features, dataProjection) {\n this.setFeatures(features);\n };\n /**\n * Handler for tile load errors.\n */\n\n\n VectorTile.prototype.onError = function () {\n this.setState(TileState.ERROR);\n };\n /**\n * Function for use in an {@link module:ol/source/VectorTile~VectorTile}\'s `tileLoadFunction`.\n * Sets the features for the tile.\n * @param {Array<import("./Feature.js").default>} features Features.\n * @api\n */\n\n\n VectorTile.prototype.setFeatures = function (features) {\n this.features_ = features;\n this.setState(TileState.LOADED);\n };\n /**\n * Set the feature loader for reading this tile\'s features.\n * @param {import("./featureloader.js").FeatureLoader} loader Feature loader.\n * @api\n */\n\n\n VectorTile.prototype.setLoader = function (loader) {\n this.loader_ = loader;\n };\n\n return VectorTile;\n}(ol_Tile);\n\n/* harmony default export */ var ol_VectorTile = (VectorTile_VectorTile);\n;// CONCATENATED MODULE: ./node_modules/ol/VectorRenderTile.js\nvar VectorRenderTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/VectorRenderTile\n */\n\n\n\n\n\n/**\n * @typedef {Object} ReplayState\n * @property {boolean} dirty\n * @property {null|import("./render.js").OrderFunction} renderedRenderOrder\n * @property {number} renderedTileRevision\n * @property {number} renderedResolution\n * @property {number} renderedRevision\n * @property {number} renderedZ\n * @property {number} renderedTileResolution\n * @property {number} renderedTileZ\n */\n\n/**\n * @type {Array<HTMLCanvasElement>}\n */\n\nvar canvasPool = [];\n\nvar VectorRenderTile =\n/** @class */\nfunction (_super) {\n VectorRenderTile_extends(VectorRenderTile, _super);\n /**\n * @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.\n * @param {import("./TileState.js").default} state State.\n * @param {import("./tilecoord.js").TileCoord} urlTileCoord Wrapped tile coordinate for source urls.\n * @param {function(VectorRenderTile):Array<import("./VectorTile").default>} getSourceTiles Function\n * to get source tiles for this tile.\n */\n\n\n function VectorRenderTile(tileCoord, state, urlTileCoord, getSourceTiles) {\n var _this = _super.call(this, tileCoord, state, {\n transition: 0\n }) || this;\n /**\n * @private\n * @type {!Object<string, CanvasRenderingContext2D>}\n */\n\n\n _this.context_ = {};\n /**\n * Executor groups by layer uid. Entries are read/written by the renderer.\n * @type {Object<string, Array<import("./render/canvas/ExecutorGroup.js").default>>}\n */\n\n _this.executorGroups = {};\n /**\n * Executor groups for decluttering, by layer uid. Entries are read/written by the renderer.\n * @type {Object<string, Array<import("./render/canvas/ExecutorGroup.js").default>>}\n */\n\n _this.declutterExecutorGroups = {};\n /**\n * Number of loading source tiles. Read/written by the source.\n * @type {number}\n */\n\n _this.loadingSourceTiles = 0;\n /**\n * Tile keys of error source tiles. Read/written by the source.\n * @type {Object<string, boolean>}\n */\n\n _this.errorSourceTileKeys = {};\n /**\n * @type {Object<number, ImageData>}\n */\n\n _this.hitDetectionImageData = {};\n /**\n * @private\n * @type {!Object<string, ReplayState>}\n */\n\n _this.replayState_ = {};\n /**\n * @type {Array<import("./VectorTile.js").default>}\n */\n\n _this.sourceTiles = null;\n /**\n * @type {number}\n */\n\n _this.wantedResolution;\n /**\n * @type {!function():Array<import("./VectorTile.js").default>}\n */\n\n _this.getSourceTiles = getSourceTiles.bind(undefined, _this);\n /**\n * z of the source tiles of the last getSourceTiles call.\n * @type {number}\n */\n\n _this.sourceZ = -1;\n /**\n * True when all tiles for this tile\'s nominal resolution are available.\n * @type {boolean}\n */\n\n _this.hifi = false;\n /**\n * @type {import("./tilecoord.js").TileCoord}\n */\n\n _this.wrappedTileCoord = urlTileCoord;\n return _this;\n }\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {CanvasRenderingContext2D} The rendering context.\n */\n\n\n VectorRenderTile.prototype.getContext = function (layer) {\n var key = getUid(layer);\n\n if (!(key in this.context_)) {\n this.context_[key] = createCanvasContext2D(1, 1, canvasPool);\n }\n\n return this.context_[key];\n };\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {boolean} Tile has a rendering context for the given layer.\n */\n\n\n VectorRenderTile.prototype.hasContext = function (layer) {\n return getUid(layer) in this.context_;\n };\n /**\n * Get the Canvas for this tile.\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {HTMLCanvasElement} Canvas.\n */\n\n\n VectorRenderTile.prototype.getImage = function (layer) {\n return this.hasContext(layer) ? this.getContext(layer).canvas : null;\n };\n /**\n * @param {import("./layer/Layer.js").default} layer Layer.\n * @return {ReplayState} The replay state.\n */\n\n\n VectorRenderTile.prototype.getReplayState = function (layer) {\n var key = getUid(layer);\n\n if (!(key in this.replayState_)) {\n this.replayState_[key] = {\n dirty: false,\n renderedRenderOrder: null,\n renderedResolution: NaN,\n renderedRevision: -1,\n renderedTileResolution: NaN,\n renderedTileRevision: -1,\n renderedZ: -1,\n renderedTileZ: -1\n };\n }\n\n return this.replayState_[key];\n };\n /**\n * Load the tile.\n */\n\n\n VectorRenderTile.prototype.load = function () {\n this.getSourceTiles();\n };\n /**\n * Remove from the cache due to expiry\n */\n\n\n VectorRenderTile.prototype.release = function () {\n for (var key in this.context_) {\n canvasPool.push(this.context_[key].canvas);\n delete this.context_[key];\n }\n\n _super.prototype.release.call(this);\n };\n\n return VectorRenderTile;\n}(ol_Tile);\n\n/* harmony default export */ var ol_VectorRenderTile = (VectorRenderTile);\n;// CONCATENATED MODULE: ./node_modules/ol/source/VectorTile.js\n/**\n * @module ol/source/VectorTile\n */\nvar source_VectorTile_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {import("./Source.js").AttributionLike} [attributions] Attributions.\n * @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.\n * @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least twice the number of tiles in the viewport.\n * @property {import("../extent.js").Extent} [extent]\n * @property {import("../format/Feature.js").default} [format] Feature format for tiles. Used and required by the default.\n * @property {boolean} [overlaps=true] This source may have overlapping geometries. Setting this\n * to `false` (e.g. for sources with polygons that represent administrative\n * boundaries or TopoJSON sources) allows the renderer to optimise fill and\n * stroke operations.\n * @property {import("../proj.js").ProjectionLike} [projection=\'EPSG:3857\'] Projection of the tile grid.\n * @property {import("./State.js").default} [state] Source state.\n * @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles.\n * Default is {@link module:ol/VectorTile}.\n * @property {number} [maxZoom=22] Optional max zoom level. Not used if `tileGrid` is provided.\n * @property {number} [minZoom] Optional min zoom level. Not used if `tileGrid` is provided.\n * @property {number|import("../size.js").Size} [tileSize=512] Optional tile size. Not used if `tileGrid` is provided.\n * @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.\n * @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.\n * @property {import("../Tile.js").LoadFunction} [tileLoadFunction]\n * Optional function to load a tile given a URL. Could look like this for pbf tiles:\n * ```js\n * function(tile, url) {\n * tile.setLoader(function(extent, resolution, projection) {\n * fetch(url).then(function(response) {\n * response.arrayBuffer().then(function(data) {\n * const format = tile.getFormat() // ol/format/MVT configured as source format\n * const features = format.readFeatures(data, {\n * extent: extent,\n * featureProjection: projection\n * });\n * tile.setFeatures(features);\n * });\n * });\n * });\n * }\n * ```\n * If you do not need extent, resolution and projection to get the features for a tile (e.g.\n * for GeoJSON tiles), your `tileLoadFunction` does not need a `setLoader()` call. Only make sure\n * to call `setFeatures()` on the tile:\n * ```js\n * const format = new GeoJSON({featureProjection: map.getView().getProjection()});\n * async function tileLoadFunction(tile, url) {\n * const response = await fetch(url);\n * const data = await response.json();\n * tile.setFeatures(format.readFeatures(data));\n * }\n * ```\n * @property {import("../Tile.js").UrlFunction} [tileUrlFunction] Optional function to get tile URL given a tile coordinate and the projection.\n * @property {string} [url] URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.\n * A `{?-?}` template pattern, for example `subdomain{a-f}.domain.com`, may be\n * used instead of defining each one separately in the `urls` option.\n * @property {number} [transition] A duration for tile opacity\n * transitions in milliseconds. A duration of 0 disables the opacity transition.\n * @property {Array<string>} [urls] An array of URL templates.\n * @property {boolean} [wrapX=true] Whether to wrap the world horizontally.\n * When set to `false`, only one world\n * will be rendered. When set to `true`, tiles will be wrapped horizontally to\n * render multiple worlds.\n * @property {number} [zDirection=1] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n */\n\n/**\n * @classdesc\n * Class for layer sources providing vector data divided into a tile grid, to be\n * used with {@link module:ol/layer/VectorTile~VectorTile}. Although this source receives tiles\n * with vector features from the server, it is not meant for feature editing.\n * Features are optimized for rendering, their geometries are clipped at or near\n * tile boundaries and simplified for a view resolution. See\n * {@link module:ol/source/Vector} for vector sources that are suitable for feature\n * editing.\n *\n * @fires import("./Tile.js").TileSourceEvent\n * @api\n */\n\nvar source_VectorTile_VectorTile =\n/** @class */\nfunction (_super) {\n source_VectorTile_extends(VectorTile, _super);\n /**\n * @param {!Options} options Vector tile options.\n */\n\n\n function VectorTile(options) {\n var _this = this;\n\n var projection = options.projection || \'EPSG:3857\';\n var extent = options.extent || extentFromProjection(projection);\n var tileGrid = options.tileGrid || createXYZ({\n extent: extent,\n maxResolution: options.maxResolution,\n maxZoom: options.maxZoom !== undefined ? options.maxZoom : 22,\n minZoom: options.minZoom,\n tileSize: options.tileSize || 512\n });\n _this = _super.call(this, {\n attributions: options.attributions,\n attributionsCollapsible: options.attributionsCollapsible,\n cacheSize: options.cacheSize,\n opaque: false,\n projection: projection,\n state: options.state,\n tileGrid: tileGrid,\n tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,\n tileUrlFunction: options.tileUrlFunction,\n url: options.url,\n urls: options.urls,\n wrapX: options.wrapX === undefined ? true : options.wrapX,\n transition: options.transition,\n zDirection: options.zDirection === undefined ? 1 : options.zDirection\n }) || this;\n /**\n * @private\n * @type {import("../format/Feature.js").default}\n */\n\n _this.format_ = options.format ? options.format : null;\n /**\n * @type {Object<string, import("./VectorTile").default>}\n */\n\n _this.loadingTiles_ = {};\n /**\n * @private\n * @type {TileCache}\n */\n\n _this.sourceTileCache = new ol_TileCache(_this.tileCache.highWaterMark);\n /**\n * @private\n * @type {boolean}\n */\n\n _this.overlaps_ = options.overlaps == undefined ? true : options.overlaps;\n /**\n * @protected\n * @type {typeof import("../VectorTile.js").default}\n */\n\n _this.tileClass = options.tileClass ? options.tileClass : ol_VectorTile;\n /**\n * @private\n * @type {Object<string, import("../tilegrid/TileGrid.js").default>}\n */\n\n _this.tileGrids_ = {};\n return _this;\n }\n /**\n * Get features whose bounding box intersects the provided extent. Only features for cached\n * tiles for the last rendered zoom level are available in the source. So this method is only\n * suitable for requesting tiles for extents that are currently rendered.\n *\n * Features are returned in random tile order and as they are included in the tiles. This means\n * they can be clipped, duplicated across tiles, and simplified to the render resolution.\n *\n * @param {import("../extent.js").Extent} extent Extent.\n * @return {Array<import("../Feature.js").FeatureLike>} Features.\n * @api\n */\n\n\n VectorTile.prototype.getFeaturesInExtent = function (extent) {\n var features = [];\n var tileCache = this.tileCache;\n\n if (tileCache.getCount() === 0) {\n return features;\n }\n\n var z = fromKey(tileCache.peekFirstKey())[0];\n var tileGrid = this.tileGrid;\n tileCache.forEach(function (tile) {\n if (tile.tileCoord[0] !== z || tile.getState() !== TileState.LOADED) {\n return;\n }\n\n var sourceTiles = tile.getSourceTiles();\n\n for (var i = 0, ii = sourceTiles.length; i < ii; ++i) {\n var sourceTile = sourceTiles[i];\n var tileCoord = sourceTile.tileCoord;\n\n if (intersects(extent, tileGrid.getTileCoordExtent(tileCoord))) {\n var tileFeatures = sourceTile.getFeatures();\n\n if (tileFeatures) {\n for (var j = 0, jj = tileFeatures.length; j < jj; ++j) {\n var candidate = tileFeatures[j];\n var geometry = candidate.getGeometry();\n\n if (intersects(extent, geometry.getExtent())) {\n features.push(candidate);\n }\n }\n }\n }\n }\n });\n return features;\n };\n /**\n * @return {boolean} The source can have overlapping geometries.\n */\n\n\n VectorTile.prototype.getOverlaps = function () {\n return this.overlaps_;\n };\n /**\n * clear {@link module:ol/TileCache~TileCache} and delete all source tiles\n * @api\n */\n\n\n VectorTile.prototype.clear = function () {\n this.tileCache.clear();\n this.sourceTileCache.clear();\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @param {!Object<string, boolean>} usedTiles Used tiles.\n */\n\n\n VectorTile.prototype.expireCache = function (projection, usedTiles) {\n _super.prototype.expireCache.call(this, projection, usedTiles);\n\n this.sourceTileCache.expireCache({});\n };\n /**\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection").default} projection Projection.\n * @param {VectorRenderTile} tile Vector image tile.\n * @return {Array<import("../VectorTile").default>} Tile keys.\n */\n\n\n VectorTile.prototype.getSourceTiles = function (pixelRatio, projection, tile) {\n var urlTileCoord = tile.wrappedTileCoord;\n var tileGrid = this.getTileGridForProjection(projection);\n var extent = tileGrid.getTileCoordExtent(urlTileCoord);\n var z = urlTileCoord[0];\n var resolution = tileGrid.getResolution(z); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n buffer(extent, -resolution, extent);\n var sourceTileGrid = this.tileGrid;\n var sourceExtent = sourceTileGrid.getExtent();\n\n if (sourceExtent) {\n getIntersection(extent, sourceExtent, extent);\n }\n\n var sourceZ = sourceTileGrid.getZForResolution(resolution, 1);\n var minZoom = sourceTileGrid.getMinZoom();\n var previousSourceTiles = tile.sourceTiles;\n var sourceTiles, covered, loadedZ;\n\n if (previousSourceTiles && previousSourceTiles.length > 0 && previousSourceTiles[0].tileCoord[0] === sourceZ) {\n sourceTiles = previousSourceTiles;\n covered = true;\n loadedZ = sourceZ;\n } else {\n sourceTiles = [];\n loadedZ = sourceZ + 1;\n\n do {\n --loadedZ;\n covered = true;\n sourceTileGrid.forEachTileCoord(extent, loadedZ, function (sourceTileCoord) {\n var tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);\n var sourceTile;\n\n if (tileUrl !== undefined) {\n if (this.sourceTileCache.containsKey(tileUrl)) {\n sourceTile = this.sourceTileCache.get(tileUrl);\n var state = sourceTile.getState();\n\n if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {\n sourceTiles.push(sourceTile);\n return;\n }\n } else if (loadedZ === sourceZ) {\n sourceTile = new this.tileClass(sourceTileCoord, TileState.IDLE, tileUrl, this.format_, this.tileLoadFunction);\n sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);\n sourceTile.projection = projection;\n sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]);\n this.sourceTileCache.set(tileUrl, sourceTile);\n sourceTile.addEventListener(EventType.CHANGE, this.handleTileChange.bind(this));\n sourceTile.load();\n }\n }\n\n covered = covered && sourceTile && sourceTile.getState() === TileState.LOADED;\n\n if (!sourceTile) {\n return;\n }\n\n if (sourceTile.getState() !== TileState.EMPTY && tile.getState() === TileState.IDLE) {\n tile.loadingSourceTiles++;\n sourceTile.addEventListener(EventType.CHANGE, function listenChange() {\n var state = sourceTile.getState();\n var sourceTileKey = sourceTile.getKey();\n\n if (state === TileState.LOADED || state === TileState.ERROR) {\n if (state === TileState.LOADED) {\n sourceTile.removeEventListener(EventType.CHANGE, listenChange);\n tile.loadingSourceTiles--;\n delete tile.errorSourceTileKeys[sourceTileKey];\n } else if (state === TileState.ERROR) {\n tile.errorSourceTileKeys[sourceTileKey] = true;\n }\n\n var errorTileCount = Object.keys(tile.errorSourceTileKeys).length;\n\n if (tile.loadingSourceTiles - errorTileCount === 0) {\n tile.hifi = errorTileCount === 0;\n tile.sourceZ = sourceZ;\n tile.setState(TileState.LOADED);\n }\n }\n });\n }\n }.bind(this));\n\n if (!covered) {\n sourceTiles.length = 0;\n }\n } while (!covered && loadedZ > minZoom);\n }\n\n if (tile.getState() === TileState.IDLE) {\n tile.setState(TileState.LOADING);\n }\n\n if (covered) {\n tile.hifi = sourceZ === loadedZ;\n tile.sourceZ = loadedZ;\n\n if (tile.getState() < TileState.LOADED) {\n tile.setState(TileState.LOADED);\n } else if (!previousSourceTiles || !equals(sourceTiles, previousSourceTiles)) {\n tile.sourceTiles = sourceTiles;\n }\n }\n\n return sourceTiles;\n };\n /**\n * @param {number} z Tile coordinate z.\n * @param {number} x Tile coordinate x.\n * @param {number} y Tile coordinate y.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!VectorRenderTile} Tile.\n */\n\n\n VectorTile.prototype.getTile = function (z, x, y, pixelRatio, projection) {\n var coordKey = getKeyZXY(z, x, y);\n var key = this.getKey();\n var tile;\n\n if (this.tileCache.containsKey(coordKey)) {\n tile = this.tileCache.get(coordKey);\n\n if (tile.key === key) {\n return tile;\n }\n }\n\n var tileCoord = [z, x, y];\n var urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);\n var sourceExtent = this.getTileGrid().getExtent();\n var tileGrid = this.getTileGridForProjection(projection);\n\n if (urlTileCoord && sourceExtent) {\n var tileExtent = tileGrid.getTileCoordExtent(urlTileCoord); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n buffer(tileExtent, -tileGrid.getResolution(z), tileExtent);\n\n if (!intersects(sourceExtent, tileExtent)) {\n urlTileCoord = null;\n }\n }\n\n var empty = true;\n\n if (urlTileCoord !== null) {\n var sourceTileGrid = this.tileGrid;\n var resolution = tileGrid.getResolution(z);\n var sourceZ = sourceTileGrid.getZForResolution(resolution, 1); // make extent 1 pixel smaller so we don\'t load tiles for < 0.5 pixel render space\n\n var extent = tileGrid.getTileCoordExtent(urlTileCoord);\n buffer(extent, -resolution, extent);\n sourceTileGrid.forEachTileCoord(extent, sourceZ, function (sourceTileCoord) {\n empty = empty && !this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);\n }.bind(this));\n }\n\n var newTile = new ol_VectorRenderTile(tileCoord, empty ? TileState.EMPTY : TileState.IDLE, urlTileCoord, this.getSourceTiles.bind(this, pixelRatio, projection));\n newTile.key = key;\n\n if (tile) {\n newTile.interimTile = tile;\n newTile.refreshInterimChain();\n this.tileCache.replace(coordKey, newTile);\n } else {\n this.tileCache.set(coordKey, newTile);\n }\n\n return newTile;\n };\n /**\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {!import("../tilegrid/TileGrid.js").default} Tile grid.\n */\n\n\n VectorTile.prototype.getTileGridForProjection = function (projection) {\n var code = projection.getCode();\n var tileGrid = this.tileGrids_[code];\n\n if (!tileGrid) {\n // A tile grid that matches the tile size of the source tile grid is more\n // likely to have 1:1 relationships between source tiles and rendered tiles.\n var sourceTileGrid = this.tileGrid;\n tileGrid = createForProjection(projection, undefined, sourceTileGrid ? sourceTileGrid.getTileSize(sourceTileGrid.getMinZoom()) : undefined);\n this.tileGrids_[code] = tileGrid;\n }\n\n return tileGrid;\n };\n /**\n * Get the tile pixel ratio for this source.\n * @param {number} pixelRatio Pixel ratio.\n * @return {number} Tile pixel ratio.\n */\n\n\n VectorTile.prototype.getTilePixelRatio = function (pixelRatio) {\n return pixelRatio;\n };\n /**\n * @param {number} z Z.\n * @param {number} pixelRatio Pixel ratio.\n * @param {import("../proj/Projection.js").default} projection Projection.\n * @return {import("../size.js").Size} Tile size.\n */\n\n\n VectorTile.prototype.getTilePixelSize = function (z, pixelRatio, projection) {\n var tileGrid = this.getTileGridForProjection(projection);\n var tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);\n return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];\n };\n /**\n * Increases the cache size if needed\n * @param {number} tileCount Minimum number of tiles needed.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n\n\n VectorTile.prototype.updateCacheSize = function (tileCount, projection) {\n _super.prototype.updateCacheSize.call(this, tileCount * 2, projection);\n };\n\n return VectorTile;\n}(source_UrlTile);\n\n/* harmony default export */ var source_VectorTile = (source_VectorTile_VectorTile);\n/**\n * Sets the loader for a tile.\n * @param {import("../VectorTile.js").default} tile Vector tile.\n * @param {string} url URL.\n */\n\nfunction defaultLoadFunction(tile, url) {\n tile.setLoader(\n /**\n * @param {import("../extent.js").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {import("../proj/Projection.js").default} projection Projection.\n */\n function (extent, resolution, projection) {\n loadFeaturesXhr(url, tile.getFormat(), extent, resolution, projection, tile.onLoad.bind(tile), tile.onError.bind(tile));\n });\n}\n;// CONCATENATED MODULE: ./node_modules/ol-mapbox-style/dist/index.js\n/*\nol-mapbox-style - Use Mapbox Style objects with OpenLayers\nCopyright 2016-present ol-mapbox-style contributors\nLicense: https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {import("ol/Map").default} PluggableMap\n * @typedef {import("ol/layer/Layer").default} Layer\n * @typedef {import("ol/source/Source").default} Source\n * @private\n */\n\nvar tilejsonCache = {};\nvar fontFamilyRegEx = /font-family: ?([^;]*);/;\nvar stripQuotesRegEx = /("|\')/g;\nvar loadedFontFamilies;\n\nfunction hasFontFamily(family) {\n if (!loadedFontFamilies) {\n loadedFontFamilies = {};\n var styleSheets = document.styleSheets;\n\n for (var i = 0, ii = styleSheets.length; i < ii; ++i) {\n var styleSheet =\n /** @type {CSSStyleSheet} */\n styleSheets[i];\n\n try {\n var cssRules = styleSheet.rules || styleSheet.cssRules;\n\n if (cssRules) {\n for (var j = 0, jj = cssRules.length; j < jj; ++j) {\n var cssRule = cssRules[j];\n\n if (cssRule.type == 5) {\n var match = cssRule.cssText.match(fontFamilyRegEx);\n loadedFontFamilies[match[1].replace(stripQuotesRegEx, \'\')] = true;\n }\n }\n }\n } catch (e) {// empty catch block\n }\n }\n }\n\n return family in loadedFontFamilies;\n}\n\nvar processedFontFamilies = {};\nvar googleFamilies = google_default().getNames();\n/**\n * @private\n * @param {Array} fonts Fonts.\n * @return {Array} Processed fonts.\n */\n\nfunction getFonts(fonts) {\n var fontsKey = fonts.toString();\n\n if (fontsKey in processedFontFamilies) {\n return fonts;\n }\n\n var googleFontDescriptions = fonts.map(function (font) {\n var parts = mapbox_to_css_font_default()(font, 1).split(\' \');\n return [parts.slice(3).join(\' \').replace(/"/g, \'\'), parts[1] + parts[0]];\n });\n\n for (var i = 0, ii = googleFontDescriptions.length; i < ii; ++i) {\n var googleFontDescription = googleFontDescriptions[i];\n var family = googleFontDescription[0];\n\n if (!hasFontFamily(family) && googleFamilies.indexOf(family) !== -1) {\n var fontUrl = \'https://fonts.googleapis.com/css?family=\' + family.replace(/ /g, \'+\') + \':\' + googleFontDescription[1];\n\n if (!document.querySelector(\'link[href="\' + fontUrl + \'"]\')) {\n var markup = document.createElement(\'link\');\n markup.href = fontUrl;\n markup.rel = \'stylesheet\';\n document.head.appendChild(markup);\n }\n }\n }\n\n processedFontFamilies[fontsKey] = true;\n return fonts;\n}\n\nvar spriteRegEx = /^(.*)(\\?.*)$/;\n\nfunction withPath(url, path) {\n if (path && url.indexOf(\'.\') === 0) {\n url = path + url;\n }\n\n return url;\n}\n\nfunction toSpriteUrl(url, path, extension) {\n url = withPath(url, path);\n var parts = url.match(spriteRegEx);\n return parts ? parts[1] + extension + (parts.length > 2 ? parts[2] : \'\') : url + extension;\n}\n/**\n * ```js\n * import {applyStyle} from \'ol-mapbox-style\';\n * ```\n *\n * Applies a style function to an `ol.layer.VectorTile` or `ol.layer.Vector`\n * with an `ol.source.VectorTile` or an `ol.source.Vector`. The style function\n * will render all layers from the `glStyle` object that use the specified\n * `source`, or a subset of layers from the same source. The source needs to be\n * a `"type": "vector"` or `"type": "geojson"` source.\n *\n * Two additional properties will be set on the provided layer:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document\'s source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document\'s layers that are\n * included in the OpenLayers layer.\n *\n * @param {VectorTileLayer|VectorLayer} layer OpenLayers layer.\n * @param {string|Object} glStyle Mapbox Style object.\n * @param {string|Array<string>} source `source` key or an array of layer `id`s from the\n * Mapbox Style object. When a `source` key is provided, all layers for the\n * specified source will be included in the style function. When layer `id`s\n * are provided, they must be from layers that use the same source.\n * @param {string} [path=undefined] Path of the style file. Only required when\n * a relative path is used with the `"sprite"` property of the style.\n * @param {Array<number>} [resolutions=undefined] Resolutions for mapping resolution to zoom level.\n * @return {Promise} Promise which will be resolved when the style can be used\n * for rendering.\n */\n\n\nfunction applyStyle(layer, glStyle, source, path, resolutions) {\n return new Promise(function (resolve, reject) {\n // TODO: figure out where best place to check source type is\n // Note that the source arg is an array of gl layer ids and each must be\n // dereferenced to get source type to validate\n if (typeof glStyle != \'object\') {\n glStyle = JSON.parse(glStyle);\n }\n\n if (glStyle.version != 8) {\n return reject(new Error(\'glStyle version 8 required.\'));\n }\n\n if (!(layer instanceof Vector || layer instanceof VectorTile)) {\n return reject(new Error(\'Can only apply to VectorLayer or VectorTileLayer\'));\n }\n\n var spriteScale, spriteData, spriteImageUrl, style;\n\n function onChange() {\n if (!style && (!glStyle.sprite || spriteData)) {\n style = stylefunction(layer, glStyle, source, resolutions, spriteData, spriteImageUrl, getFonts);\n\n if (!layer.getStyle()) {\n reject(new Error("Nothing to show for source [" + source + "]"));\n } else {\n resolve();\n }\n } else if (style) {\n layer.setStyle(style);\n resolve();\n } else {\n reject(new Error(\'Something went wrong trying to apply style.\'));\n }\n }\n\n if (glStyle.sprite) {\n spriteScale = window.devicePixelRatio >= 1.5 ? 0.5 : 1;\n var sizeFactor_1 = spriteScale == 0.5 ? \'@2x\' : \'\';\n var spriteUrl_1 = toSpriteUrl(glStyle.sprite, path, sizeFactor_1 + \'.json\');\n fetch(spriteUrl_1, {\n credentials: \'same-origin\'\n }).then(function (response) {\n if (!response.ok && sizeFactor_1 !== \'\') {\n spriteUrl_1 = toSpriteUrl(glStyle.sprite, path, \'.json\');\n return fetch(spriteUrl_1, {\n credentials: \'same-origin\'\n });\n } else {\n return response;\n }\n }).then(function (response) {\n if (response.ok) {\n return response.json();\n } else {\n reject(new Error("Problem fetching sprite from " + spriteUrl_1 + ": " + response.statusText));\n }\n }).then(function (spritesJson) {\n if (spritesJson === undefined) {\n return reject(new Error(\'No sprites found.\'));\n }\n\n spriteData = spritesJson;\n spriteImageUrl = toSpriteUrl(glStyle.sprite, path, sizeFactor_1 + \'.png\');\n onChange();\n }).catch(function (err) {\n reject(new Error("Sprites cannot be loaded: " + spriteUrl_1 + ": " + err.message));\n });\n } else {\n onChange();\n }\n });\n}\nvar dist_emptyObj = {};\n\nfunction setBackground(map, layer) {\n var background = {\n type: layer.type\n };\n\n function updateStyle() {\n var element = map.getTargetElement();\n\n if (!element) {\n return;\n }\n\n var layout = layer.layout || {};\n var paint = layer.paint || {};\n background[\'paint\'] = paint;\n background.id = \'olms-bg-\' + paint[\'background-opacity\'] + paint[\'background-color\'];\n var zoom = map.getView().getZoom();\n\n if (paint[\'background-color\'] !== undefined) {\n var bg = getValue(background, \'paint\', \'background-color\', zoom, dist_emptyObj);\n element.style.background = index_es/* Color.parse */.Il.parse(bg).toString();\n }\n\n if (paint[\'background-opacity\'] !== undefined) {\n element.style.opacity = getValue(background, \'paint\', \'background-opacity\', zoom, dist_emptyObj);\n }\n\n if (layout.visibility == \'none\') {\n element.style.backgroundColor = \'\';\n element.style.opacity = \'\';\n }\n }\n\n if (map.getTargetElement()) {\n updateStyle();\n }\n\n map.on([\'change:resolution\', \'change:target\'], updateStyle);\n}\n/**\n * ```js\n * import {applyBackground} from \'ol-mapbox-style\';\n * ```\n * Applies properties of the Mapbox Style\'s first `background` layer to the map.\n * @param {PluggableMap} map OpenLayers Map.\n * @param {Object} glStyle Mapbox Style object.\n */\n\n\nfunction applyBackground(map, glStyle) {\n glStyle.layers.some(function (l) {\n if (l.type == \'background\') {\n setBackground(map, l);\n return true;\n }\n });\n}\n\nfunction getSourceIdByRef(layers, ref) {\n var sourceId;\n layers.some(function (layer) {\n if (layer.id == ref) {\n sourceId = layer.source;\n return true;\n }\n });\n return sourceId;\n}\n\nfunction extentFromTileJSON(tileJSON) {\n var bounds = tileJSON.bounds;\n\n if (bounds) {\n var ll = fromLonLat([bounds[0], bounds[1]]);\n var tr = fromLonLat([bounds[2], bounds[3]]);\n return [ll[0], ll[1], tr[0], tr[1]];\n }\n}\n\nfunction setupVectorLayer(glSource, accessToken, url) {\n glSource = util_assign({}, glSource);\n var layer = new VectorTile({\n declutter: true,\n visible: false\n });\n var cacheKey = JSON.stringify(glSource);\n var tilejson = tilejsonCache[cacheKey];\n\n if (!tilejson) {\n tilejson = tilejsonCache[cacheKey] = new source_TileJSON({\n url: glSource.tiles ? undefined : url,\n tileJSON: glSource.tiles ? glSource : undefined\n });\n }\n\n var key = tilejson.on(\'change\', function () {\n var state = tilejson.getState();\n\n if (state === \'ready\') {\n var tileJSONDoc = tilejson.getTileJSON();\n var tiles = Array.isArray(tileJSONDoc.tiles) ? tileJSONDoc.tiles : [tileJSONDoc.tiles];\n\n if (url) {\n for (var i = 0, ii = tiles.length; i < ii; ++i) {\n var tile = tiles[i];\n\n if (tile.indexOf(\'http\') != 0) {\n tiles[i] = url.replace(/\\/?$/, \'/\') + tile.replace(/^\\//, \'\');\n }\n }\n }\n\n var tileGrid = tilejson.getTileGrid();\n var extent = extentFromTileJSON(tileJSONDoc);\n var minZoom = tileJSONDoc.minzoom || 0;\n var maxZoom = tileJSONDoc.maxzoom || 22;\n var source = tilejson.get(\'ol-source\');\n\n if (source === undefined) {\n source = new source_VectorTile({\n attributions: tilejson.getAttributions(),\n format: new format_MVT(),\n tileGrid: new tilegrid_TileGrid({\n origin: tileGrid.getOrigin(0),\n extent: extent || tileGrid.getExtent(),\n minZoom: minZoom,\n resolutions: defaultResolutions.slice(0, maxZoom + 1),\n tileSize: 512\n }),\n urls: tiles\n });\n tilejson.set(\'ol-source\', source);\n }\n\n unByKey(key);\n layer.setSource(source);\n } else if (state === \'error\') {\n tilejson.set(\'ol-source\', null);\n unByKey(key);\n layer.setSource(undefined);\n }\n });\n\n if (tilejson.getState() === \'ready\') {\n tilejson.changed();\n }\n\n return layer;\n}\n\nfunction setupRasterLayer(glSource, url) {\n var layer = new Tile();\n var source = new source_TileJSON({\n transition: 0,\n url: glSource.tiles ? undefined : url,\n tileJSON: glSource.tiles ? glSource : undefined,\n crossOrigin: \'anonymous\'\n });\n var key = source.on(\'change\', function () {\n var state = source.getState();\n\n if (state === \'ready\') {\n unByKey(key);\n var tileJSONDoc =\n /** @type {Object} */\n source.getTileJSON();\n var extent = extentFromTileJSON(tileJSONDoc);\n var tileGrid = source.getTileGrid();\n var tileSize = glSource.tileSize || tileJSONDoc.tileSize || 512;\n var minZoom = tileJSONDoc.minzoom || 0;\n var maxZoom = tileJSONDoc.maxzoom || 22; // Only works when using ES modules\n\n source.tileGrid = new tilegrid_TileGrid({\n origin: tileGrid.getOrigin(0),\n extent: extent || tileGrid.getExtent(),\n minZoom: minZoom,\n resolutions: createXYZ({\n maxZoom: maxZoom,\n tileSize: tileSize\n }).getResolutions(),\n tileSize: tileSize\n });\n layer.setSource(source);\n } else if (state === \'error\') {\n unByKey(key);\n layer.setSource(undefined);\n }\n });\n source.setTileLoadFunction(function (tile, src) {\n if (src.indexOf(\'{bbox-epsg-3857}\') != -1) {\n var bbox = source.getTileGrid().getTileCoordExtent(tile.getTileCoord());\n src = src.replace(\'{bbox-epsg-3857}\', bbox.toString());\n }\n\n var img =\n /** @type {import("ol/ImageTile").default} */\n tile.getImage();\n /** @type {HTMLImageElement} */\n\n img.src = src;\n });\n return layer;\n}\n\nvar geoJsonFormat = new format_GeoJSON();\n\nfunction setupGeoJSONLayer(glSource, path) {\n var data = glSource.data;\n var features, geoJsonUrl;\n\n if (typeof data == \'string\') {\n geoJsonUrl = withPath(data, path);\n } else {\n features = geoJsonFormat.readFeatures(data, {\n featureProjection: \'EPSG:3857\'\n });\n }\n\n return new Vector({\n source: new source_Vector({\n attributions: glSource.attribution,\n features: features,\n format: geoJsonFormat,\n url: geoJsonUrl\n }),\n visible: false\n });\n}\n\nfunction updateRasterLayerProperties(glLayer, layer, view) {\n var zoom = view.getZoom();\n var opacity = getValue(glLayer, \'paint\', \'raster-opacity\', zoom, dist_emptyObj);\n layer.setOpacity(opacity);\n}\n\nfunction processStyle(glStyle, map, baseUrl, host, path, accessToken) {\n if (accessToken === void 0) {\n accessToken = \'\';\n }\n\n var promises = [];\n var view = map.getView();\n\n if (!view.isDef() && !view.getRotation() && !view.getResolutions()) {\n view = new ol_View({\n maxResolution: defaultResolutions[0]\n });\n map.setView(view);\n }\n\n if (\'center\' in glStyle && !view.getCenter()) {\n view.setCenter(fromLonLat(glStyle.center));\n }\n\n if (\'zoom\' in glStyle && view.getZoom() === undefined) {\n view.setResolution(defaultResolutions[0] / Math.pow(2, glStyle.zoom));\n }\n\n if (!view.getCenter() || view.getZoom() === undefined) {\n view.fit(view.getProjection().getExtent(), {\n nearest: true,\n size: map.getSize()\n });\n }\n\n if (glStyle.sprite) {\n if (glStyle.sprite.indexOf(\'mapbox://\') == 0) {\n glStyle.sprite = baseUrl + \'/sprite\' + accessToken;\n } else if (glStyle.sprite.indexOf(\'http\') != 0) {\n glStyle.sprite = (host ? host + path : \'\') + glStyle.sprite + accessToken;\n }\n }\n\n var glLayers = glStyle.layers;\n var layerIds = [];\n var glLayer, glSource, glSourceId, id, layer, url;\n\n var _loop_1 = function _loop_1(i, ii) {\n glLayer = glLayers[i];\n var type = glLayer.type;\n\n if (type == \'heatmap\' || type == \'hillshade\') {//FIXME Unsupported layer type\n } else if (type == \'background\') {\n setBackground(map, glLayer);\n } else {\n id = glLayer.source || getSourceIdByRef(glLayers, glLayer.ref); // this technique assumes gl layers will be in a particular order\n\n if (id != glSourceId) {\n if (layerIds.length) {\n promises.push(finalizeLayer(layer, layerIds, glStyle, path, map));\n layerIds = [];\n }\n\n glSource = glStyle.sources[id];\n url = glSource.url;\n\n if (url) {\n url = withPath(url, path);\n\n if (url.indexOf(\'mapbox://\') == 0) {\n var mapid_1 = url.replace(\'mapbox://\', \'\');\n glSource.tiles = [\'a\', \'b\', \'c\', \'d\'].map(function (host) {\n return \'https://\' + host + \'.tiles.mapbox.com/v4/\' + mapid_1 + \'/{z}/{x}/{y}.\' + (glSource.type == \'vector\' ? \'vector.pbf\' : \'png\') + accessToken;\n });\n } else if (url.indexOf(\'/\') === 0 && host.indexOf(\'http\') === 0) {\n url = host + url;\n }\n }\n\n if (glSource.tiles) {\n glSource.tiles = glSource.tiles.map(function (url) {\n return withPath(url, path);\n });\n }\n\n if (glSource.type == \'vector\') {\n layer = setupVectorLayer(glSource, accessToken, url);\n } else if (glSource.type == \'raster\') {\n layer = setupRasterLayer(glSource, url);\n layer.setVisible(glLayer.layout ? glLayer.layout.visibility !== \'none\' : true);\n view.on(\'change:resolution\', updateRasterLayerProperties.bind(this_1, glLayer, layer, view));\n updateRasterLayerProperties(glLayer, layer, view);\n } else if (glSource.type == \'geojson\') {\n layer = setupGeoJSONLayer(glSource, path);\n }\n\n glSourceId = id;\n\n if (layer) {\n layer.set(\'mapbox-source\', glSourceId);\n }\n }\n\n layerIds.push(glLayer.id);\n }\n };\n\n var this_1 = this;\n\n for (var i = 0, ii = glLayers.length; i < ii; ++i) {\n _loop_1(i, ii);\n }\n\n promises.push(finalizeLayer(layer, layerIds, glStyle, path, map));\n map.set(\'mapbox-style\', glStyle);\n return Promise.all(promises);\n}\n/**\n * ```js\n * import olms from \'ol-mapbox-style\';\n * ```\n *\n * Loads and applies a Mapbox Style object to an OpenLayers Map. This includes\n * the map background, the layers, the center and the zoom.\n *\n * The center and zoom will only be set if present in the Mapbox Style document,\n * and if not already set on the OpenLayers map.\n *\n * Layers will be added to the OpenLayers map, without affecting any layers that\n * might already be set on the map.\n *\n * Layers added by `apply()` will have two additional properties:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document\'s source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document\'s layers that are\n * included in the OpenLayers layer.\n *\n * This function sets an additional `mapbox-style` property on the OpenLayers\n * map instance, which holds the Mapbox Style object.\n *\n * @param {PluggableMap|HTMLElement|string} map Either an existing OpenLayers Map\n * instance, or a HTML element, or the id of a HTML element that will be the\n * target of a new OpenLayers Map.\n * @param {string|Object} style JSON style object or style url pointing to a\n * Mapbox Style object. When using Mapbox APIs, the url must contain an access\n * token and look like\n * `https://api.mapbox.com/styles/v1/mapbox/bright-v9?access_token=[your_access_token_here]`.\n * When passed as JSON style object, all OpenLayers layers created by `apply()`\n * will be immediately available, but they may not have a source yet (i.e. when\n * they are defined by a TileJSON url in the Mapbox Style document). When passed\n * as style url, layers will be added to the map when the Mapbox Style document\n * is loaded and parsed.\n * @return {Promise} A promise that resolves after all layers have been added to\n * the OpenLayers Map instance, their sources set, and their styles applied. the\n * `resolve` callback will be called with the OpenLayers Map instance as\n * argument.\n */\n\n\nfunction olms(map, style) {\n var accessToken, baseUrl, host, path, promise;\n accessToken = baseUrl = host = path = \'\';\n\n if (typeof map === \'string\' || map instanceof HTMLElement) {\n map = new ol_Map({\n target: map\n });\n }\n\n if (typeof style === \'string\') {\n var parts = style.match(spriteRegEx);\n\n if (parts) {\n baseUrl = parts[1];\n accessToken = parts.length > 2 ? parts[2] : \'\';\n }\n\n promise = new Promise(function (resolve, reject) {\n fetch(style, {\n credentials: \'same-origin\'\n }).then(function (response) {\n return response.json();\n }).then(function (glStyle) {\n var a =\n /** @type {HTMLAnchorElement} */\n document.createElement(\'A\');\n a.href = style;\n var href = a.href;\n path = a.pathname.split(\'/\').slice(0, -1).join(\'/\') + \'/\';\n host = href.substr(0, href.indexOf(path));\n processStyle(glStyle, map, baseUrl, host, path, accessToken).then(function () {\n resolve(map);\n }).catch(reject);\n }).catch(function (err) {\n reject(new Error("Could not load " + style + ": " + err.message));\n });\n });\n } else {\n promise = new Promise(function (resolve, reject) {\n processStyle(style, map).then(function () {\n resolve(map);\n }).catch(reject);\n });\n }\n\n return promise;\n}\n/**\n * ```js\n * import {apply} from \'ol-mapbox-style\';\n * ```\n * Like `olms`, but returns an `ol/Map` instance instead of a `Promise`.\n *\n * @param {PluggableMap|HTMLElement|string} map Either an existing OpenLayers Map\n * instance, or a HTML element, or the id of a HTML element that will be the\n * target of a new OpenLayers Map.\n * @param {string|Object} style JSON style object or style url pointing to a\n * Mapbox Style object. When using Mapbox APIs, the url must contain an access\n * token and look like\n * `https://api.mapbox.com/styles/v1/mapbox/bright-v9?access_token=[your_access_token_here]`.\n * When passed as JSON style object, all OpenLayers layers created by `apply()`\n * will be immediately available, but they may not have a source yet (i.e. when\n * they are defined by a TileJSON url in the Mapbox Style document). When passed\n * as style url, layers will be added to the map when the Mapbox Style document\n * is loaded and parsed.\n * @return {PluggableMap} The OpenLayers Map instance that will be populated with the\n * contents described in the Mapbox Style object.\n */\n\nfunction dist_apply(map, style) {\n if (typeof map === \'string\' || map instanceof HTMLElement) {\n map = new Map({\n target: map\n });\n }\n\n setTimeout(function () {\n olms(map, style);\n }, 0);\n return map;\n}\n/**\n * @private\n * If layerIds is not empty, applies the style specified in glStyle to the layer,\n * and adds the layer to the map.\n *\n * The layer may not yet have a source when the function is called. If so, the style\n * is applied to the layer via a once listener on the \'change:source\' event.\n *\n * @param {Layer} layer An OpenLayers layer instance.\n * @param {Array<string>} layerIds Array containing layer ids of already-processed layers.\n * @param {Object} glStyle Style as a JSON object.\n * @param {string|undefined} path The path part of the style URL. Only required\n * when a relative path is used with the `"sprite"` property of the style.\n * @param {PluggableMap} map OpenLayers Map.\n * @return {Promise} Returns a promise that resolves after the source has\n * been set on the specified layer, and the style has been applied.\n */\n\nfunction finalizeLayer(layer, layerIds, glStyle, path, map) {\n var minZoom = 24;\n var maxZoom = 0;\n var glLayers = glStyle.layers;\n\n for (var i = 0, ii = glLayers.length; i < ii; ++i) {\n var glLayer = glLayers[i];\n\n if (layerIds.indexOf(glLayer.id) !== -1) {\n minZoom = Math.min(\'minzoom\' in glLayer ? glLayer.minzoom : 0, minZoom);\n maxZoom = Math.max(\'maxzoom\' in glLayer ? glLayer.maxzoom : 24, maxZoom);\n }\n }\n\n return new Promise(function (resolve, reject) {\n var setStyle = function setStyle() {\n var source = layer.getSource();\n\n if (!source || source.getState() === \'error\') {\n reject(new Error(\'Error accessing data for source \' + layer.get(\'mapbox-source\')));\n return;\n }\n\n if (typeof source.getTileGrid === \'function\') {\n var tileGrid = source.getTileGrid();\n\n if (tileGrid) {\n var sourceMinZoom = tileGrid.getMinZoom();\n\n if (minZoom > 0 || sourceMinZoom > 0) {\n layer.setMaxResolution(Math.min(defaultResolutions[minZoom], tileGrid.getResolution(sourceMinZoom)) + 1e-9);\n }\n\n if (maxZoom < 24) {\n layer.setMinResolution(defaultResolutions[maxZoom] + 1e-9);\n }\n }\n }\n\n if (source instanceof source_Vector || source instanceof source_VectorTile) {\n applyStyle(\n /** @type {import("ol/layer/Vector").default|import("ol/layer/VectorTile").default} */\n layer, glStyle, layerIds, path).then(function () {\n layer.setVisible(true);\n resolve();\n }, function (e) {\n reject(e);\n });\n } else {\n resolve();\n }\n };\n\n layer.set(\'mapbox-layers\', layerIds);\n\n if (map.getLayers().getArray().indexOf(layer) === -1) {\n map.addLayer(layer);\n }\n\n if (layer.getSource()) {\n setStyle();\n } else {\n layer.once(\'change:source\', setStyle);\n }\n });\n}\n/**\n * ```js\n * import {getLayer} from \'ol-mapbox-style\';\n * ```\n * Get the OpenLayers layer instance that contains the provided Mapbox Style\n * `layer`. Note that multiple Mapbox Style layers are combined in a single\n * OpenLayers layer instance when they use the same Mapbox Style `source`.\n * @param {PluggableMap} map OpenLayers Map.\n * @param {string} layerId Mapbox Style layer id.\n * @return {Layer} OpenLayers layer instance.\n */\n\n\nfunction getLayer(map, layerId) {\n var layers = map.getLayers().getArray();\n\n for (var i = 0, ii = layers.length; i < ii; ++i) {\n var mapboxLayers = layers[i].get(\'mapbox-layers\');\n\n if (mapboxLayers && mapboxLayers.indexOf(layerId) !== -1) {\n return (\n /** @type {Layer} */\n layers[i]\n );\n }\n }\n}\n/**\n * ```js\n * import {getLayers} from \'ol-mapbox-style\';\n * ```\n * Get the OpenLayers layer instances for the provided Mapbox Style `source`.\n * @param {PluggableMap} map OpenLayers Map.\n * @param {string} sourceId Mapbox Style source id.\n * @return {Array<Layer>} OpenLayers layer instances.\n */\n\nfunction getLayers(map, sourceId) {\n var result = [];\n var layers = map.getLayers().getArray();\n\n for (var i = 0, ii = layers.length; i < ii; ++i) {\n if (layers[i].get(\'mapbox-source\') === sourceId) {\n result.push(\n /** @type {Layer} */\n layers[i]);\n }\n }\n\n return result;\n}\n/**\n * ```js\n * import {getSource} from \'ol-mapbox-style\';\n * ```\n * Get the OpenLayers source instance for the provided Mapbox Style `source`.\n * @param {PluggableMap} map OpenLayers Map.\n * @param {string} sourceId Mapbox Style source id.\n * @return {Source} OpenLayers source instance.\n */\n\nfunction getSource(map, sourceId) {\n var layers = map.getLayers().getArray();\n\n for (var i = 0, ii = layers.length; i < ii; ++i) {\n var source =\n /** @type {Layer} */\n layers[i].getSource();\n\n if (layers[i].get(\'mapbox-source\') === sourceId) {\n return source;\n }\n }\n}\n\n;// CONCATENATED MODULE: ./src/components/openlayersPopup.module.scss\n// extracted by mini-css-extract-plugin\nvar popupContainer = "openlayersPopup-module--popupContainer--1aC-P";\nvar popupCloser = "openlayersPopup-module--popupCloser--1b04g";\nvar openlayersPopup_module_popupContent = "openlayersPopup-module--popupContent--2xAyt";\n;// CONCATENATED MODULE: ./node_modules/ol/OverlayPositioning.js\n/**\n * @module ol/OverlayPositioning\n */\n\n/**\n * Overlay position: `\'bottom-left\'`, `\'bottom-center\'`, `\'bottom-right\'`,\n * `\'center-left\'`, `\'center-center\'`, `\'center-right\'`, `\'top-left\'`,\n * `\'top-center\'`, `\'top-right\'`\n * @enum {string}\n */\n/* harmony default export */ var OverlayPositioning = ({\n BOTTOM_LEFT: \'bottom-left\',\n BOTTOM_CENTER: \'bottom-center\',\n BOTTOM_RIGHT: \'bottom-right\',\n CENTER_LEFT: \'center-left\',\n CENTER_CENTER: \'center-center\',\n CENTER_RIGHT: \'center-right\',\n TOP_LEFT: \'top-left\',\n TOP_CENTER: \'top-center\',\n TOP_RIGHT: \'top-right\'\n});\n;// CONCATENATED MODULE: ./node_modules/ol/Overlay.js\nvar Overlay_extends = undefined && undefined.__extends || function () {\n var _extendStatics = function extendStatics(d, b) {\n _extendStatics = Object.setPrototypeOf || {\n __proto__: []\n } instanceof Array && function (d, b) {\n d.__proto__ = b;\n } || function (d, b) {\n for (var p in b) {\n if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n }\n };\n\n return _extendStatics(d, b);\n };\n\n return function (d, b) {\n _extendStatics(d, b);\n\n function __() {\n this.constructor = d;\n }\n\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\n/**\n * @module ol/Overlay\n */\n\n\n\n\n\n\n\n\n\n/**\n * @typedef {Object} Options\n * @property {number|string} [id] Set the overlay id. The overlay id can be used\n * with the {@link module:ol/Map~Map#getOverlayById} method.\n * @property {HTMLElement} [element] The overlay element.\n * @property {Array<number>} [offset=[0, 0]] Offsets in pixels used when positioning\n * the overlay. The first element in the\n * array is the horizontal offset. A positive value shifts the overlay right.\n * The second element in the array is the vertical offset. A positive value\n * shifts the overlay down.\n * @property {import("./coordinate.js").Coordinate} [position] The overlay position\n * in map projection.\n * @property {import("./OverlayPositioning.js").default} [positioning=\'top-left\'] Defines how\n * the overlay is actually positioned with respect to its `position` property.\n * Possible values are `\'bottom-left\'`, `\'bottom-center\'`, `\'bottom-right\'`,\n * `\'center-left\'`, `\'center-center\'`, `\'center-right\'`, `\'top-left\'`,\n * `\'top-center\'`, and `\'top-right\'`.\n * @property {boolean} [stopEvent=true] Whether event propagation to the map\n * viewport should be stopped. If `true` the overlay is placed in the same\n * container as that of the controls (CSS class name\n * `ol-overlaycontainer-stopevent`); if `false` it is placed in the container\n * with CSS class name specified by the `className` property.\n * @property {boolean} [insertFirst=true] Whether the overlay is inserted first\n * in the overlay container, or appended. If the overlay is placed in the same\n * container as that of the controls (see the `stopEvent` option) you will\n * probably set `insertFirst` to `true` so the overlay is displayed below the\n * controls.\n * @property {PanIntoViewOptions|boolean} [autoPan=false] Pan the map when calling\n * `setPosition`, so that the overlay is entirely visible in the current viewport?\n * If `true` (deprecated), then `autoPanAnimation` and `autoPanMargin` will be\n * used to determine the panning parameters; if an object is supplied then other\n * parameters are ignored.\n * @property {PanOptions} [autoPanAnimation] The animation options used to pan\n * the overlay into view. This animation is only used when `autoPan` is enabled.\n * A `duration` and `easing` may be provided to customize the animation.\n * Deprecated and ignored if `autoPan` is supplied as an object.\n * @property {number} [autoPanMargin=20] The margin (in pixels) between the\n * overlay and the borders of the map when autopanning. Deprecated and ignored\n * if `autoPan` is supplied as an object.\n * @property {PanIntoViewOptions} [autoPanOptions] The options to use for the\n * autoPan. This is only used when `autoPan` is enabled and has preference over\n * the individual `autoPanMargin` and `autoPanOptions`.\n * @property {string} [className=\'ol-overlay-container ol-selectable\'] CSS class\n * name.\n */\n\n/**\n * @typedef {Object} PanOptions\n * @property {number} [duration=1000] The duration of the animation in\n * milliseconds.\n * @property {function(number):number} [easing] The easing function to use. Can\n * be one from {@link module:ol/easing} or a custom function.\n * Default is {@link module:ol/easing~inAndOut}.\n */\n\n/**\n * @typedef {Object} PanIntoViewOptions\n * @property {PanOptions} [animation={}] The animation parameters for the pan\n * @property {number} [margin=20] The margin (in pixels) between the\n * overlay and the borders of the map when panning into view.\n */\n\n/**\n * @enum {string}\n * @protected\n */\n\nvar Overlay_Property = {\n ELEMENT: \'element\',\n MAP: \'map\',\n OFFSET: \'offset\',\n POSITION: \'position\',\n POSITIONING: \'positioning\'\n};\n/**\n * @classdesc\n * An element to be displayed over the map and attached to a single map\n * location. Like {@link module:ol/control/Control~Control}, Overlays are\n * visible widgets. Unlike Controls, they are not in a fixed position on the\n * screen, but are tied to a geographical coordinate, so panning the map will\n * move an Overlay but not a Control.\n *\n * Example:\n *\n * import Overlay from \'ol/Overlay\';\n *\n * var popup = new Overlay({\n * element: document.getElementById(\'popup\')\n * });\n * popup.setPosition(coordinate);\n * map.addOverlay(popup);\n *\n * @api\n */\n\nvar Overlay =\n/** @class */\nfunction (_super) {\n Overlay_extends(Overlay, _super);\n /**\n * @param {Options} options Overlay options.\n */\n\n\n function Overlay(options) {\n var _this = _super.call(this) || this;\n /**\n * @protected\n * @type {Options}\n */\n\n\n _this.options = options;\n /**\n * @protected\n * @type {number|string|undefined}\n */\n\n _this.id = options.id;\n /**\n * @protected\n * @type {boolean}\n */\n\n _this.insertFirst = options.insertFirst !== undefined ? options.insertFirst : true;\n /**\n * @protected\n * @type {boolean}\n */\n\n _this.stopEvent = options.stopEvent !== undefined ? options.stopEvent : true;\n /**\n * @protected\n * @type {HTMLElement}\n */\n\n _this.element = document.createElement(\'div\');\n _this.element.className = options.className !== undefined ? options.className : \'ol-overlay-container \' + CLASS_SELECTABLE;\n _this.element.style.position = \'absolute\';\n _this.element.style.pointerEvents = \'auto\';\n var autoPan = options.autoPan;\n\n if (autoPan && \'object\' !== typeof autoPan) {\n autoPan = {\n animation: options.autoPanAnimation,\n margin: options.autoPanMargin\n };\n }\n /**\n * @protected\n * @type {PanIntoViewOptions|false}\n */\n\n\n _this.autoPan =\n /** @type {PanIntoViewOptions} */\n autoPan || false;\n /**\n * @protected\n * @type {{transform_: string,\n * visible: boolean}}\n */\n\n _this.rendered = {\n transform_: \'\',\n visible: true\n };\n /**\n * @protected\n * @type {?import("./events.js").EventsKey}\n */\n\n _this.mapPostrenderListenerKey = null;\n\n _this.addEventListener(getChangeEventType(Overlay_Property.ELEMENT), _this.handleElementChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.MAP), _this.handleMapChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.OFFSET), _this.handleOffsetChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.POSITION), _this.handlePositionChanged);\n\n _this.addEventListener(getChangeEventType(Overlay_Property.POSITIONING), _this.handlePositioningChanged);\n\n if (options.element !== undefined) {\n _this.setElement(options.element);\n }\n\n _this.setOffset(options.offset !== undefined ? options.offset : [0, 0]);\n\n _this.setPositioning(options.positioning !== undefined ?\n /** @type {import("./OverlayPositioning.js").default} */\n options.positioning : OverlayPositioning.TOP_LEFT);\n\n if (options.position !== undefined) {\n _this.setPosition(options.position);\n }\n\n return _this;\n }\n /**\n * Get the DOM element of this overlay.\n * @return {HTMLElement|undefined} The Element containing the overlay.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getElement = function () {\n return (\n /** @type {HTMLElement|undefined} */\n this.get(Overlay_Property.ELEMENT)\n );\n };\n /**\n * Get the overlay identifier which is set on constructor.\n * @return {number|string|undefined} Id.\n * @api\n */\n\n\n Overlay.prototype.getId = function () {\n return this.id;\n };\n /**\n * Get the map associated with this overlay.\n * @return {import("./PluggableMap.js").default|undefined} The map that the\n * overlay is part of.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getMap = function () {\n return (\n /** @type {import("./PluggableMap.js").default|undefined} */\n this.get(Overlay_Property.MAP)\n );\n };\n /**\n * Get the offset of this overlay.\n * @return {Array<number>} The offset.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getOffset = function () {\n return (\n /** @type {Array<number>} */\n this.get(Overlay_Property.OFFSET)\n );\n };\n /**\n * Get the current position of this overlay.\n * @return {import("./coordinate.js").Coordinate|undefined} The spatial point that the overlay is\n * anchored at.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getPosition = function () {\n return (\n /** @type {import("./coordinate.js").Coordinate|undefined} */\n this.get(Overlay_Property.POSITION)\n );\n };\n /**\n * Get the current positioning of this overlay.\n * @return {import("./OverlayPositioning.js").default} How the overlay is positioned\n * relative to its point on the map.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.getPositioning = function () {\n return (\n /** @type {import("./OverlayPositioning.js").default} */\n this.get(Overlay_Property.POSITIONING)\n );\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleElementChanged = function () {\n removeChildren(this.element);\n var element = this.getElement();\n\n if (element) {\n this.element.appendChild(element);\n }\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleMapChanged = function () {\n if (this.mapPostrenderListenerKey) {\n removeNode(this.element);\n unlistenByKey(this.mapPostrenderListenerKey);\n this.mapPostrenderListenerKey = null;\n }\n\n var map = this.getMap();\n\n if (map) {\n this.mapPostrenderListenerKey = listen(map, MapEventType.POSTRENDER, this.render, this);\n this.updatePixelPosition();\n var container = this.stopEvent ? map.getOverlayContainerStopEvent() : map.getOverlayContainer();\n\n if (this.insertFirst) {\n container.insertBefore(this.element, container.childNodes[0] || null);\n } else {\n container.appendChild(this.element);\n }\n\n this.performAutoPan();\n }\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.render = function () {\n this.updatePixelPosition();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handleOffsetChanged = function () {\n this.updatePixelPosition();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handlePositionChanged = function () {\n this.updatePixelPosition();\n this.performAutoPan();\n };\n /**\n * @protected\n */\n\n\n Overlay.prototype.handlePositioningChanged = function () {\n this.updatePixelPosition();\n };\n /**\n * Set the DOM element to be associated with this overlay.\n * @param {HTMLElement|undefined} element The Element containing the overlay.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setElement = function (element) {\n this.set(Overlay_Property.ELEMENT, element);\n };\n /**\n * Set the map to be associated with this overlay.\n * @param {import("./PluggableMap.js").default|undefined} map The map that the\n * overlay is part of.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setMap = function (map) {\n this.set(Overlay_Property.MAP, map);\n };\n /**\n * Set the offset for this overlay.\n * @param {Array<number>} offset Offset.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setOffset = function (offset) {\n this.set(Overlay_Property.OFFSET, offset);\n };\n /**\n * Set the position for this overlay. If the position is `undefined` the\n * overlay is hidden.\n * @param {import("./coordinate.js").Coordinate|undefined} position The spatial point that the overlay\n * is anchored at.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setPosition = function (position) {\n this.set(Overlay_Property.POSITION, position);\n };\n /**\n * Pan the map so that the overlay is entirely visisble in the current viewport\n * (if necessary) using the configured autoPan parameters\n * @protected\n */\n\n\n Overlay.prototype.performAutoPan = function () {\n if (this.autoPan) {\n this.panIntoView(this.autoPan);\n }\n };\n /**\n * Pan the map so that the overlay is entirely visible in the current viewport\n * (if necessary).\n * @param {PanIntoViewOptions=} opt_panIntoViewOptions Options for the pan action\n * @api\n */\n\n\n Overlay.prototype.panIntoView = function (opt_panIntoViewOptions) {\n var map = this.getMap();\n\n if (!map || !map.getTargetElement() || !this.get(Overlay_Property.POSITION)) {\n return;\n }\n\n var mapRect = this.getRect(map.getTargetElement(), map.getSize());\n var element = this.getElement();\n var overlayRect = this.getRect(element, [dom_outerWidth(element), dom_outerHeight(element)]);\n var panIntoViewOptions = opt_panIntoViewOptions || {};\n var myMargin = panIntoViewOptions.margin === undefined ? 20 : panIntoViewOptions.margin;\n\n if (!containsExtent(mapRect, overlayRect)) {\n // the overlay is not completely inside the viewport, so pan the map\n var offsetLeft = overlayRect[0] - mapRect[0];\n var offsetRight = mapRect[2] - overlayRect[2];\n var offsetTop = overlayRect[1] - mapRect[1];\n var offsetBottom = mapRect[3] - overlayRect[3];\n var delta = [0, 0];\n\n if (offsetLeft < 0) {\n // move map to the left\n delta[0] = offsetLeft - myMargin;\n } else if (offsetRight < 0) {\n // move map to the right\n delta[0] = Math.abs(offsetRight) + myMargin;\n }\n\n if (offsetTop < 0) {\n // move map up\n delta[1] = offsetTop - myMargin;\n } else if (offsetBottom < 0) {\n // move map down\n delta[1] = Math.abs(offsetBottom) + myMargin;\n }\n\n if (delta[0] !== 0 || delta[1] !== 0) {\n var center =\n /** @type {import("./coordinate.js").Coordinate} */\n map.getView().getCenterInternal();\n var centerPx = map.getPixelFromCoordinateInternal(center);\n\n if (!centerPx) {\n return;\n }\n\n var newCenterPx = [centerPx[0] + delta[0], centerPx[1] + delta[1]];\n var panOptions = panIntoViewOptions.animation || {};\n map.getView().animateInternal({\n center: map.getCoordinateFromPixelInternal(newCenterPx),\n duration: panOptions.duration,\n easing: panOptions.easing\n });\n }\n }\n };\n /**\n * Get the extent of an element relative to the document\n * @param {HTMLElement} element The element.\n * @param {import("./size.js").Size} size The size of the element.\n * @return {import("./extent.js").Extent} The extent.\n * @protected\n */\n\n\n Overlay.prototype.getRect = function (element, size) {\n var box = element.getBoundingClientRect();\n var offsetX = box.left + window.pageXOffset;\n var offsetY = box.top + window.pageYOffset;\n return [offsetX, offsetY, offsetX + size[0], offsetY + size[1]];\n };\n /**\n * Set the positioning for this overlay.\n * @param {import("./OverlayPositioning.js").default} positioning how the overlay is\n * positioned relative to its point on the map.\n * @observable\n * @api\n */\n\n\n Overlay.prototype.setPositioning = function (positioning) {\n this.set(Overlay_Property.POSITIONING, positioning);\n };\n /**\n * Modify the visibility of the element.\n * @param {boolean} visible Element visibility.\n * @protected\n */\n\n\n Overlay.prototype.setVisible = function (visible) {\n if (this.rendered.visible !== visible) {\n this.element.style.display = visible ? \'\' : \'none\';\n this.rendered.visible = visible;\n }\n };\n /**\n * Update pixel position.\n * @protected\n */\n\n\n Overlay.prototype.updatePixelPosition = function () {\n var map = this.getMap();\n var position = this.getPosition();\n\n if (!map || !map.isRendered() || !position) {\n this.setVisible(false);\n return;\n }\n\n var pixel = map.getPixelFromCoordinate(position);\n var mapSize = map.getSize();\n this.updateRenderedPosition(pixel, mapSize);\n };\n /**\n * @param {import("./pixel.js").Pixel} pixel The pixel location.\n * @param {import("./size.js").Size|undefined} mapSize The map size.\n * @protected\n */\n\n\n Overlay.prototype.updateRenderedPosition = function (pixel, mapSize) {\n var style = this.element.style;\n var offset = this.getOffset();\n var positioning = this.getPositioning();\n this.setVisible(true);\n var x = Math.round(pixel[0] + offset[0]) + \'px\';\n var y = Math.round(pixel[1] + offset[1]) + \'px\';\n var posX = \'0%\';\n var posY = \'0%\';\n\n if (positioning == OverlayPositioning.BOTTOM_RIGHT || positioning == OverlayPositioning.CENTER_RIGHT || positioning == OverlayPositioning.TOP_RIGHT) {\n posX = \'-100%\';\n } else if (positioning == OverlayPositioning.BOTTOM_CENTER || positioning == OverlayPositioning.CENTER_CENTER || positioning == OverlayPositioning.TOP_CENTER) {\n posX = \'-50%\';\n }\n\n if (positioning == OverlayPositioning.BOTTOM_LEFT || positioning == OverlayPositioning.BOTTOM_CENTER || positioning == OverlayPositioning.BOTTOM_RIGHT) {\n posY = \'-100%\';\n } else if (positioning == OverlayPositioning.CENTER_LEFT || positioning == OverlayPositioning.CENTER_CENTER || positioning == OverlayPositioning.CENTER_RIGHT) {\n posY = \'-50%\';\n }\n\n var transform = "translate(" + posX + ", " + posY + ") translate(" + x + ", " + y + ")";\n\n if (this.rendered.transform_ != transform) {\n this.rendered.transform_ = transform;\n style.transform = transform; // @ts-ignore IE9\n\n style.msTransform = transform;\n }\n };\n /**\n * returns the options this Overlay has been created with\n * @return {Options} overlay options\n */\n\n\n Overlay.prototype.getOptions = function () {\n return this.options;\n };\n\n return Overlay;\n}(ol_Object);\n\n/* harmony default export */ var ol_Overlay = (Overlay);\n;// CONCATENATED MODULE: ./src/components/openlayersPopup.tsx\nvar OpenlayersPopup=function OpenlayersPopup(_ref){var map=_ref.map,selectedFeature=_ref.selectedFeature,position=_ref.position;var popupContainerElement=(0,react.useRef)(null);var popupCloserElement=(0,react.useRef)(null);var popupContentElement=(0,react.useRef)(null);var _useState=(0,react.useState)(),currentOverlay=_useState[0],setCurrentOverlay=_useState[1];(0,react.useEffect)(function(){popupCloserElement.current.onclick=function(){overlay.setPosition(undefined);popupCloserElement.current.blur();return false;};var overlay=new ol_Overlay({element:popupContainerElement.current,autoPan:true,autoPanAnimation:{duration:250}});setCurrentOverlay(overlay);map.addOverlay(overlay);},[]);(0,react.useEffect)(function(){if(position&¤tOverlay&&selectedFeature){// may be empty on first render\ncurrentOverlay.setPosition(position);}},[position]);return/*#__PURE__*/react.createElement(react.Fragment,null,/*#__PURE__*/react.createElement("div",{ref:popupContainerElement,className:popupContainer},/*#__PURE__*/react.createElement("a",{href:"#",ref:popupCloserElement,className:popupCloser}),/*#__PURE__*/react.createElement("div",{ref:popupContentElement,className:openlayersPopup_module_popupContent},/*#__PURE__*/react.createElement(popupContent,{properties:selectedFeature===null||selectedFeature===void 0?void 0:selectedFeature.getProperties()}))));};/* harmony default export */ var openlayersPopup = (OpenlayersPopup);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js\nvar classCallCheck = __webpack_require__(6610);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js\nvar inherits = __webpack_require__(379);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js + 1 modules\nvar possibleConstructorReturn = __webpack_require__(6616);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nvar getPrototypeOf = __webpack_require__(7608);\n// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js\nvar createClass = __webpack_require__(5991);\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/Units.js\n/**\n * @module ol/proj/Units\n */\n\n/**\n * Projection units: `\'degrees\'`, `\'ft\'`, `\'m\'`, `\'pixels\'`, `\'tile-pixels\'` or\n * `\'us-ft\'`.\n * @enum {string}\n */\nvar proj_Units_Units = {\n /**\n * Degrees\n * @api\n */\n DEGREES: \'degrees\',\n\n /**\n * Feet\n * @api\n */\n FEET: \'ft\',\n\n /**\n * Meters\n * @api\n */\n METERS: \'m\',\n\n /**\n * Pixels\n * @api\n */\n PIXELS: \'pixels\',\n\n /**\n * Tile Pixels\n * @api\n */\n TILE_PIXELS: \'tile-pixels\',\n\n /**\n * US Feet\n * @api\n */\n USFEET: \'us-ft\'\n};\n/**\n * Meters per unit lookup table.\n * @const\n * @type {Object<Units, number>}\n * @api\n */\n\nvar proj_Units_METERS_PER_UNIT = {}; // use the radius of the Normal sphere\n\nproj_Units_METERS_PER_UNIT[proj_Units_Units.DEGREES] = 2 * Math.PI * 6370997 / 360;\nproj_Units_METERS_PER_UNIT[proj_Units_Units.FEET] = 0.3048;\nproj_Units_METERS_PER_UNIT[proj_Units_Units.METERS] = 1;\nproj_Units_METERS_PER_UNIT[proj_Units_Units.USFEET] = 1200 / 3937;\n/* harmony default export */ var src_proj_Units = (proj_Units_Units);\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/Projection.js\n\n\n\n/**\n * @module ol/proj/Projection\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} code The SRS identifier code, e.g. `EPSG:4326`.\n * @property {import("./Units.js").default|string} [units] Units. Required unless a\n * proj4 projection is defined for `code`.\n * @property {import("../extent.js").Extent} [extent] The validity extent for the SRS.\n * @property {string} [axisOrientation=\'enu\'] The axis orientation as specified in Proj4.\n * @property {boolean} [global=false] Whether the projection is valid for the whole globe.\n * @property {number} [metersPerUnit] The meters per unit for the SRS.\n * If not provided, the `units` are used to get the meters per unit from the {@link module:ol/proj/Units~METERS_PER_UNIT}\n * lookup table.\n * @property {import("../extent.js").Extent} [worldExtent] The world extent for the SRS.\n * @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]\n * Function to determine resolution at a point. The function is called with a\n * `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns\n * the `{number}` resolution in projection units at the passed coordinate. If this is `undefined`,\n * the default {@link module:ol/proj#getPointResolution} function will be used.\n */\n\n/**\n * @classdesc\n * Projection definition class. One of these is created for each projection\n * supported in the application and stored in the {@link module:ol/proj} namespace.\n * You can use these in applications, but this is not required, as API params\n * and options use {@link module:ol/proj~ProjectionLike} which means the simple string\n * code will suffice.\n *\n * You can use {@link module:ol/proj~get} to retrieve the object for a particular\n * projection.\n *\n * The library includes definitions for `EPSG:4326` and `EPSG:3857`, together\n * with the following aliases:\n * * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,\n * urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,\n * http://www.opengis.net/gml/srs/epsg.xml#4326,\n * urn:x-ogc:def:crs:EPSG:4326\n * * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,\n * urn:ogc:def:crs:EPSG:6.18:3:3857,\n * http://www.opengis.net/gml/srs/epsg.xml#3857\n *\n * If you use [proj4js](https://github.com/proj4js/proj4js), aliases can\n * be added using `proj4.defs()`. After all required projection definitions are\n * added, call the {@link module:ol/proj/proj4~register} function.\n *\n * @api\n */\n\nvar Projection_Projection = /*#__PURE__*/function () {\n /**\n * @param {Options} options Projection options.\n */\n function Projection(options) {\n (0,classCallCheck/* default */.Z)(this, Projection);\n\n /**\n * @private\n * @type {string}\n */\n this.code_ = options.code;\n /**\n * Units of projected coordinates. When set to `TILE_PIXELS`, a\n * `this.extent_` and `this.worldExtent_` must be configured properly for each\n * tile.\n * @private\n * @type {import("./Units.js").default}\n */\n\n this.units_ =\n /** @type {import("./Units.js").default} */\n options.units;\n /**\n * Validity extent of the projection in projected coordinates. For projections\n * with `TILE_PIXELS` units, this is the extent of the tile in\n * tile pixel space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.extent_ = options.extent !== undefined ? options.extent : null;\n /**\n * Extent of the world in EPSG:4326. For projections with\n * `TILE_PIXELS` units, this is the extent of the tile in\n * projected coordinate space.\n * @private\n * @type {import("../extent.js").Extent}\n */\n\n this.worldExtent_ = options.worldExtent !== undefined ? options.worldExtent : null;\n /**\n * @private\n * @type {string}\n */\n\n this.axisOrientation_ = options.axisOrientation !== undefined ? options.axisOrientation : \'enu\';\n /**\n * @private\n * @type {boolean}\n */\n\n this.global_ = options.global !== undefined ? options.global : false;\n /**\n * @private\n * @type {boolean}\n */\n\n this.canWrapX_ = !!(this.global_ && this.extent_);\n /**\n * @private\n * @type {function(number, import("../coordinate.js").Coordinate):number|undefined}\n */\n\n this.getPointResolutionFunc_ = options.getPointResolution;\n /**\n * @private\n * @type {import("../tilegrid/TileGrid.js").default}\n */\n\n this.defaultTileGrid_ = null;\n /**\n * @private\n * @type {number|undefined}\n */\n\n this.metersPerUnit_ = options.metersPerUnit;\n }\n /**\n * @return {boolean} The projection is suitable for wrapping the x-axis\n */\n\n\n (0,createClass/* default */.Z)(Projection, [{\n key: "canWrapX",\n value: function canWrapX() {\n return this.canWrapX_;\n }\n /**\n * Get the code for this projection, e.g. \'EPSG:4326\'.\n * @return {string} Code.\n * @api\n */\n\n }, {\n key: "getCode",\n value: function getCode() {\n return this.code_;\n }\n /**\n * Get the validity extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n }, {\n key: "getExtent",\n value: function getExtent() {\n return this.extent_;\n }\n /**\n * Get the units of this projection.\n * @return {import("./Units.js").default} Units.\n * @api\n */\n\n }, {\n key: "getUnits",\n value: function getUnits() {\n return this.units_;\n }\n /**\n * Get the amount of meters per unit of this projection. If the projection is\n * not configured with `metersPerUnit` or a units identifier, the return is\n * `undefined`.\n * @return {number|undefined} Meters.\n * @api\n */\n\n }, {\n key: "getMetersPerUnit",\n value: function getMetersPerUnit() {\n return this.metersPerUnit_ || proj_Units_METERS_PER_UNIT[this.units_];\n }\n /**\n * Get the world extent for this projection.\n * @return {import("../extent.js").Extent} Extent.\n * @api\n */\n\n }, {\n key: "getWorldExtent",\n value: function getWorldExtent() {\n return this.worldExtent_;\n }\n /**\n * Get the axis orientation of this projection.\n * Example values are:\n * enu - the default easting, northing, elevation.\n * neu - northing, easting, up - useful for "lat/long" geographic coordinates,\n * or south orientated transverse mercator.\n * wnu - westing, northing, up - some planetary coordinate systems have\n * "west positive" coordinate systems\n * @return {string} Axis orientation.\n * @api\n */\n\n }, {\n key: "getAxisOrientation",\n value: function getAxisOrientation() {\n return this.axisOrientation_;\n }\n /**\n * Is this projection a global projection which spans the whole world?\n * @return {boolean} Whether the projection is global.\n * @api\n */\n\n }, {\n key: "isGlobal",\n value: function isGlobal() {\n return this.global_;\n }\n /**\n * Set if the projection is a global projection which spans the whole world\n * @param {boolean} global Whether the projection is global.\n * @api\n */\n\n }, {\n key: "setGlobal",\n value: function setGlobal(global) {\n this.global_ = global;\n this.canWrapX_ = !!(global && this.extent_);\n }\n /**\n * @return {import("../tilegrid/TileGrid.js").default} The default tile grid.\n */\n\n }, {\n key: "getDefaultTileGrid",\n value: function getDefaultTileGrid() {\n return this.defaultTileGrid_;\n }\n /**\n * @param {import("../tilegrid/TileGrid.js").default} tileGrid The default tile grid.\n */\n\n }, {\n key: "setDefaultTileGrid",\n value: function setDefaultTileGrid(tileGrid) {\n this.defaultTileGrid_ = tileGrid;\n }\n /**\n * Set the validity extent for this projection.\n * @param {import("../extent.js").Extent} extent Extent.\n * @api\n */\n\n }, {\n key: "setExtent",\n value: function setExtent(extent) {\n this.extent_ = extent;\n this.canWrapX_ = !!(this.global_ && extent);\n }\n /**\n * Set the world extent for this projection.\n * @param {import("../extent.js").Extent} worldExtent World extent\n * [minlon, minlat, maxlon, maxlat].\n * @api\n */\n\n }, {\n key: "setWorldExtent",\n value: function setWorldExtent(worldExtent) {\n this.worldExtent_ = worldExtent;\n }\n /**\n * Set the getPointResolution function (see {@link module:ol/proj~getPointResolution}\n * for this projection.\n * @param {function(number, import("../coordinate.js").Coordinate):number} func Function\n * @api\n */\n\n }, {\n key: "setGetPointResolution",\n value: function setGetPointResolution(func) {\n this.getPointResolutionFunc_ = func;\n }\n /**\n * Get the custom point resolution function for this projection (if set).\n * @return {function(number, import("../coordinate.js").Coordinate):number|undefined} The custom point\n * resolution function (if set).\n */\n\n }, {\n key: "getPointResolutionFunc",\n value: function getPointResolutionFunc() {\n return this.getPointResolutionFunc_;\n }\n }]);\n\n return Projection;\n}();\n\n/* harmony default export */ var src_proj_Projection = (Projection_Projection);\n;// CONCATENATED MODULE: ./node_modules/ol/src/math.js\n/**\n * @module ol/math\n */\n\n/**\n * Takes a number and clamps it to within the provided bounds.\n * @param {number} value The input number.\n * @param {number} min The minimum value to return.\n * @param {number} max The maximum value to return.\n * @return {number} The input number if it is within bounds, or the nearest\n * number within the bounds.\n */\nfunction src_math_clamp(value, min, max) {\n return Math.min(Math.max(value, min), max);\n}\n/**\n * Return the hyperbolic cosine of a given number. The method will use the\n * native `Math.cosh` function if it is available, otherwise the hyperbolic\n * cosine will be calculated via the reference implementation of the Mozilla\n * developer network.\n *\n * @param {number} x X.\n * @return {number} Hyperbolic cosine of x.\n */\n\nvar math_cosh = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var cosh;\n\n if (\'cosh\' in Math) {\n // The environment supports the native Math.cosh function, use it…\n cosh = Math.cosh;\n } else {\n // … else, use the reference implementation of MDN:\n cosh = function cosh(x) {\n var y =\n /** @type {Math} */\n Math.exp(x);\n return (y + 1 / y) / 2;\n };\n }\n\n return cosh;\n}();\n/**\n * Return the base 2 logarithm of a given number. The method will use the\n * native `Math.log2` function if it is available, otherwise the base 2\n * logarithm will be calculated via the reference implementation of the\n * Mozilla developer network.\n *\n * @param {number} x X.\n * @return {number} Base 2 logarithm of x.\n */\n\nvar math_log2 = function () {\n // Wrapped in a iife, to save the overhead of checking for the native\n // implementation on every invocation.\n var log2;\n\n if (\'log2\' in Math) {\n // The environment supports the native Math.log2 function, use it…\n log2 = Math.log2;\n } else {\n // … else, use the reference implementation of MDN:\n log2 = function log2(x) {\n return Math.log(x) * Math.LOG2E;\n };\n }\n\n return log2;\n}();\n/**\n * Returns the square of the closest distance between the point (x, y) and the\n * line segment (x1, y1) to (x2, y2).\n * @param {number} x X.\n * @param {number} y Y.\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction math_squaredSegmentDistance(x, y, x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n\n if (dx !== 0 || dy !== 0) {\n var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n if (t > 1) {\n x1 = x2;\n y1 = y2;\n } else if (t > 0) {\n x1 += dx * t;\n y1 += dy * t;\n }\n }\n\n return src_math_squaredDistance(x, y, x1, y1);\n}\n/**\n * Returns the square of the distance between the points (x1, y1) and (x2, y2).\n * @param {number} x1 X1.\n * @param {number} y1 Y1.\n * @param {number} x2 X2.\n * @param {number} y2 Y2.\n * @return {number} Squared distance.\n */\n\nfunction src_math_squaredDistance(x1, y1, x2, y2) {\n var dx = x2 - x1;\n var dy = y2 - y1;\n return dx * dx + dy * dy;\n}\n/**\n * Solves system of linear equations using Gaussian elimination method.\n *\n * @param {Array<Array<number>>} mat Augmented matrix (n x n + 1 column)\n * in row-major order.\n * @return {Array<number>} The resulting vector.\n */\n\nfunction math_solveLinearSystem(mat) {\n var n = mat.length;\n\n for (var i = 0; i < n; i++) {\n // Find max in the i-th column (ignoring i - 1 first rows)\n var maxRow = i;\n var maxEl = Math.abs(mat[i][i]);\n\n for (var r = i + 1; r < n; r++) {\n var absValue = Math.abs(mat[r][i]);\n\n if (absValue > maxEl) {\n maxEl = absValue;\n maxRow = r;\n }\n }\n\n if (maxEl === 0) {\n return null; // matrix is singular\n } // Swap max row with i-th (current) row\n\n\n var tmp = mat[maxRow];\n mat[maxRow] = mat[i];\n mat[i] = tmp; // Subtract the i-th row to make all the remaining rows 0 in the i-th column\n\n for (var j = i + 1; j < n; j++) {\n var coef = -mat[j][i] / mat[i][i];\n\n for (var k = i; k < n + 1; k++) {\n if (i == k) {\n mat[j][k] = 0;\n } else {\n mat[j][k] += coef * mat[i][k];\n }\n }\n }\n } // Solve Ax=b for upper triangular matrix A (mat)\n\n\n var x = new Array(n);\n\n for (var l = n - 1; l >= 0; l--) {\n x[l] = mat[l][n] / mat[l][l];\n\n for (var m = l - 1; m >= 0; m--) {\n mat[m][n] -= mat[m][l] * x[l];\n }\n }\n\n return x;\n}\n/**\n * Converts radians to to degrees.\n *\n * @param {number} angleInRadians Angle in radians.\n * @return {number} Angle in degrees.\n */\n\nfunction src_math_toDegrees(angleInRadians) {\n return angleInRadians * 180 / Math.PI;\n}\n/**\n * Converts degrees to radians.\n *\n * @param {number} angleInDegrees Angle in degrees.\n * @return {number} Angle in radians.\n */\n\nfunction src_math_toRadians(angleInDegrees) {\n return angleInDegrees * Math.PI / 180;\n}\n/**\n * Returns the modulo of a / b, depending on the sign of b.\n *\n * @param {number} a Dividend.\n * @param {number} b Divisor.\n * @return {number} Modulo.\n */\n\nfunction src_math_modulo(a, b) {\n var r = a % b;\n return r * b < 0 ? r + b : r;\n}\n/**\n * Calculates the linearly interpolated value of x between a and b.\n *\n * @param {number} a Number\n * @param {number} b Number\n * @param {number} x Value to be interpolated.\n * @return {number} Interpolated value.\n */\n\nfunction math_lerp(a, b, x) {\n return a + x * (b - a);\n}\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/epsg3857.js\n\n\n\n\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0,getPrototypeOf/* default */.Z)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0,getPrototypeOf/* default */.Z)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0,possibleConstructorReturn/* default */.Z)(this, result); }; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n/**\n * @module ol/proj/epsg3857\n */\n\n\n\n/**\n * Radius of WGS84 sphere\n *\n * @const\n * @type {number}\n */\n\nvar epsg3857_RADIUS = 6378137;\n/**\n * @const\n * @type {number}\n */\n\nvar epsg3857_HALF_SIZE = Math.PI * epsg3857_RADIUS;\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar epsg3857_EXTENT = [-epsg3857_HALF_SIZE, -epsg3857_HALF_SIZE, epsg3857_HALF_SIZE, epsg3857_HALF_SIZE];\n/**\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar epsg3857_WORLD_EXTENT = [-180, -85, 180, 85];\n/**\n * Maximum safe value in y direction\n * @const\n * @type {number}\n */\n\nvar epsg3857_MAX_SAFE_Y = epsg3857_RADIUS * Math.log(Math.tan(Math.PI / 2));\n/**\n * @classdesc\n * Projection object for web/spherical Mercator (EPSG:3857).\n */\n\nvar epsg3857_EPSG3857Projection = /*#__PURE__*/function (_Projection) {\n (0,inherits/* default */.Z)(EPSG3857Projection, _Projection);\n\n var _super = _createSuper(EPSG3857Projection);\n\n /**\n * @param {string} code Code.\n */\n function EPSG3857Projection(code) {\n (0,classCallCheck/* default */.Z)(this, EPSG3857Projection);\n\n return _super.call(this, {\n code: code,\n units: src_proj_Units.METERS,\n extent: epsg3857_EXTENT,\n global: true,\n worldExtent: epsg3857_WORLD_EXTENT,\n getPointResolution: function getPointResolution(resolution, point) {\n return resolution / math_cosh(point[1] / epsg3857_RADIUS);\n }\n });\n }\n\n return EPSG3857Projection;\n}(src_proj_Projection);\n/**\n * Projections equal to EPSG:3857.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar epsg3857_PROJECTIONS = [new epsg3857_EPSG3857Projection(\'EPSG:3857\'), new epsg3857_EPSG3857Projection(\'EPSG:102100\'), new epsg3857_EPSG3857Projection(\'EPSG:102113\'), new epsg3857_EPSG3857Projection(\'EPSG:900913\'), new epsg3857_EPSG3857Projection(\'http://www.opengis.net/gml/srs/epsg.xml#3857\')];\n/**\n * Transformation from EPSG:4326 to EPSG:3857.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction epsg3857_fromEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = epsg3857_HALF_SIZE * input[i] / 180;\n var y = epsg3857_RADIUS * Math.log(Math.tan(Math.PI * (+input[i + 1] + 90) / 360));\n\n if (y > epsg3857_MAX_SAFE_Y) {\n y = epsg3857_MAX_SAFE_Y;\n } else if (y < -epsg3857_MAX_SAFE_Y) {\n y = -epsg3857_MAX_SAFE_Y;\n }\n\n output[i + 1] = y;\n }\n\n return output;\n}\n/**\n * Transformation from EPSG:3857 to EPSG:4326.\n *\n * @param {Array<number>} input Input array of coordinate values.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension (default is `2`).\n * @return {Array<number>} Output array of coordinate values.\n */\n\nfunction epsg3857_toEPSG4326(input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension > 1 ? opt_dimension : 2;\n var output = opt_output;\n\n if (output === undefined) {\n if (dimension > 2) {\n // preserve values beyond second dimension\n output = input.slice();\n } else {\n output = new Array(length);\n }\n }\n\n for (var i = 0; i < length; i += dimension) {\n output[i] = 180 * input[i] / epsg3857_HALF_SIZE;\n output[i + 1] = 360 * Math.atan(Math.exp(input[i + 1] / epsg3857_RADIUS)) / Math.PI - 90;\n }\n\n return output;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/epsg4326.js\n\n\n\n\n\nfunction epsg4326_createSuper(Derived) { var hasNativeReflectConstruct = epsg4326_isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0,getPrototypeOf/* default */.Z)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0,getPrototypeOf/* default */.Z)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0,possibleConstructorReturn/* default */.Z)(this, result); }; }\n\nfunction epsg4326_isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }\n\n/**\n * @module ol/proj/epsg4326\n */\n\n\n/**\n * Semi-major radius of the WGS84 ellipsoid.\n *\n * @const\n * @type {number}\n */\n\nvar proj_epsg4326_RADIUS = 6378137;\n/**\n * Extent of the EPSG:4326 projection which is the whole world.\n *\n * @const\n * @type {import("../extent.js").Extent}\n */\n\nvar proj_epsg4326_EXTENT = [-180, -90, 180, 90];\n/**\n * @const\n * @type {number}\n */\n\nvar proj_epsg4326_METERS_PER_UNIT = Math.PI * proj_epsg4326_RADIUS / 180;\n/**\n * @classdesc\n * Projection object for WGS84 geographic coordinates (EPSG:4326).\n *\n * Note that OpenLayers does not strictly comply with the EPSG definition.\n * The EPSG registry defines 4326 as a CRS for Latitude,Longitude (y,x).\n * OpenLayers treats EPSG:4326 as a pseudo-projection, with x,y coordinates.\n */\n\nvar epsg4326_EPSG4326Projection = /*#__PURE__*/function (_Projection) {\n (0,inherits/* default */.Z)(EPSG4326Projection, _Projection);\n\n var _super = epsg4326_createSuper(EPSG4326Projection);\n\n /**\n * @param {string} code Code.\n * @param {string=} opt_axisOrientation Axis orientation.\n */\n function EPSG4326Projection(code, opt_axisOrientation) {\n (0,classCallCheck/* default */.Z)(this, EPSG4326Projection);\n\n return _super.call(this, {\n code: code,\n units: src_proj_Units.DEGREES,\n extent: proj_epsg4326_EXTENT,\n axisOrientation: opt_axisOrientation,\n global: true,\n metersPerUnit: proj_epsg4326_METERS_PER_UNIT,\n worldExtent: proj_epsg4326_EXTENT\n });\n }\n\n return EPSG4326Projection;\n}(src_proj_Projection);\n/**\n * Projections equal to EPSG:4326.\n *\n * @const\n * @type {Array<import("./Projection.js").default>}\n */\n\n\nvar proj_epsg4326_PROJECTIONS = [new epsg4326_EPSG4326Projection(\'CRS:84\'), new epsg4326_EPSG4326Projection(\'EPSG:4326\', \'neu\'), new epsg4326_EPSG4326Projection(\'urn:ogc:def:crs:OGC:1.3:CRS84\'), new epsg4326_EPSG4326Projection(\'urn:ogc:def:crs:OGC:2:84\'), new epsg4326_EPSG4326Projection(\'http://www.opengis.net/gml/srs/epsg.xml#4326\', \'neu\')];\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/projections.js\n/**\n * @module ol/proj/projections\n */\n\n/**\n * @type {Object<string, import("./Projection.js").default>}\n */\nvar projections_cache = {};\n/**\n * Clear the projections cache.\n */\n\nfunction proj_projections_clear() {\n projections_cache = {};\n}\n/**\n * Get a cached projection by code.\n * @param {string} code The code for the projection.\n * @return {import("./Projection.js").default} The projection (if cached).\n */\n\nfunction projections_get(code) {\n return projections_cache[code] || projections_cache[code.replace(/urn:(x-)?ogc:def:crs:EPSG:(.*:)?(\\w+)$/, \'EPSG:$3\')] || null;\n}\n/**\n * Add a projection to the cache.\n * @param {string} code The projection code.\n * @param {import("./Projection.js").default} projection The projection to cache.\n */\n\nfunction proj_projections_add(code, projection) {\n projections_cache[code] = projection;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj/transforms.js\n/**\n * @module ol/proj/transforms\n */\n\n/**\n * @private\n * @type {!Object<string, Object<string, import("../proj.js").TransformFunction>>}\n */\n\nvar transforms_transforms = {};\n/**\n * Clear the transform cache.\n */\n\nfunction proj_transforms_clear() {\n transforms_transforms = {};\n}\n/**\n * Registers a conversion function to convert coordinates from the source\n * projection to the destination projection.\n *\n * @param {import("./Projection.js").default} source Source.\n * @param {import("./Projection.js").default} destination Destination.\n * @param {import("../proj.js").TransformFunction} transformFn Transform.\n */\n\nfunction proj_transforms_add(source, destination, transformFn) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n\n if (!(sourceCode in transforms_transforms)) {\n transforms_transforms[sourceCode] = {};\n }\n\n transforms_transforms[sourceCode][destinationCode] = transformFn;\n}\n/**\n * Unregisters the conversion function to convert coordinates from the source\n * projection to the destination projection. This method is used to clean up\n * cached transforms during testing.\n *\n * @param {import("./Projection.js").default} source Source projection.\n * @param {import("./Projection.js").default} destination Destination projection.\n * @return {import("../proj.js").TransformFunction} transformFn The unregistered transform.\n */\n\nfunction proj_transforms_remove(source, destination) {\n var sourceCode = source.getCode();\n var destinationCode = destination.getCode();\n var transform = transforms_transforms[sourceCode][destinationCode];\n delete transforms_transforms[sourceCode][destinationCode];\n\n if (isEmpty(transforms_transforms[sourceCode])) {\n delete transforms_transforms[sourceCode];\n }\n\n return transform;\n}\n/**\n * Get a transform given a source code and a destination code.\n * @param {string} sourceCode The code for the source projection.\n * @param {string} destinationCode The code for the destination projection.\n * @return {import("../proj.js").TransformFunction|undefined} The transform function (if found).\n */\n\nfunction proj_transforms_get(sourceCode, destinationCode) {\n var transform;\n\n if (sourceCode in transforms_transforms && destinationCode in transforms_transforms[sourceCode]) {\n transform = transforms_transforms[sourceCode][destinationCode];\n }\n\n return transform;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/src/extent.js\n/**\n * @module ol/extent\n */\n\n\n\n/**\n * An array of numbers representing an extent: `[minx, miny, maxx, maxy]`.\n * @typedef {Array<number>} Extent\n * @api\n */\n\n/**\n * Build an extent that includes all given coordinates.\n *\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Bounding extent.\n * @api\n */\n\nfunction extent_boundingExtent(coordinates) {\n var extent = extent_createEmpty();\n\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extent_extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Array<number>} xs Xs.\n * @param {Array<number>} ys Ys.\n * @param {Extent=} opt_extent Destination extent.\n * @private\n * @return {Extent} Extent.\n */\n\nfunction extent_boundingExtentXYs(xs, ys, opt_extent) {\n var minX = Math.min.apply(null, xs);\n var minY = Math.min.apply(null, ys);\n var maxX = Math.max.apply(null, xs);\n var maxY = Math.max.apply(null, ys);\n return extent_createOrUpdate(minX, minY, maxX, maxY, opt_extent);\n}\n/**\n * Return extent increased by the provided value.\n * @param {Extent} extent Extent.\n * @param {number} value The amount by which the extent should be buffered.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n * @api\n */\n\n\nfunction extent_buffer(extent, value, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0] - value;\n opt_extent[1] = extent[1] - value;\n opt_extent[2] = extent[2] + value;\n opt_extent[3] = extent[3] + value;\n return opt_extent;\n } else {\n return [extent[0] - value, extent[1] - value, extent[2] + value, extent[3] + value];\n }\n}\n/**\n * Creates a clone of an extent.\n *\n * @param {Extent} extent Extent to clone.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} The clone.\n */\n\nfunction extent_clone(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent.slice();\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n * @return {number} Closest squared distance.\n */\n\nfunction extent_closestSquaredDistanceXY(extent, x, y) {\n var dx, dy;\n\n if (x < extent[0]) {\n dx = extent[0] - x;\n } else if (extent[2] < x) {\n dx = x - extent[2];\n } else {\n dx = 0;\n }\n\n if (y < extent[1]) {\n dy = extent[1] - y;\n } else if (extent[3] < y) {\n dy = y - extent[3];\n } else {\n dy = 0;\n }\n\n return dx * dx + dy * dy;\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @return {boolean} The coordinate is contained in the extent.\n * @api\n */\n\nfunction extent_containsCoordinate(extent, coordinate) {\n return extent_containsXY(extent, coordinate[0], coordinate[1]);\n}\n/**\n * Check if one extent contains another.\n *\n * An extent is deemed contained if it lies completely within the other extent,\n * including if they share one or more edges.\n *\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The second extent is contained by or on the edge of the\n * first.\n * @api\n */\n\nfunction extent_containsExtent(extent1, extent2) {\n return extent1[0] <= extent2[0] && extent2[2] <= extent1[2] && extent1[1] <= extent2[1] && extent2[3] <= extent1[3];\n}\n/**\n * Check if the passed coordinate is contained or on the edge of the extent.\n *\n * @param {Extent} extent Extent.\n * @param {number} x X coordinate.\n * @param {number} y Y coordinate.\n * @return {boolean} The x, y values are contained in the extent.\n * @api\n */\n\nfunction extent_containsXY(extent, x, y) {\n return extent[0] <= x && x <= extent[2] && extent[1] <= y && y <= extent[3];\n}\n/**\n * Get the relationship between a coordinate and extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} coordinate The coordinate.\n * @return {import("./extent/Relationship.js").default} The relationship (bitwise compare with\n * import("./extent/Relationship.js").Relationship).\n */\n\nfunction extent_coordinateRelationship(extent, coordinate) {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var x = coordinate[0];\n var y = coordinate[1];\n var relationship = Relationship.UNKNOWN;\n\n if (x < minX) {\n relationship = relationship | Relationship.LEFT;\n } else if (x > maxX) {\n relationship = relationship | Relationship.RIGHT;\n }\n\n if (y < minY) {\n relationship = relationship | Relationship.BELOW;\n } else if (y > maxY) {\n relationship = relationship | Relationship.ABOVE;\n }\n\n if (relationship === Relationship.UNKNOWN) {\n relationship = Relationship.INTERSECTING;\n }\n\n return relationship;\n}\n/**\n * Create an empty extent.\n * @return {Extent} Empty extent.\n * @api\n */\n\nfunction extent_createEmpty() {\n return [Infinity, Infinity, -Infinity, -Infinity];\n}\n/**\n * Create a new extent or update the provided extent.\n * @param {number} minX Minimum X.\n * @param {number} minY Minimum Y.\n * @param {number} maxX Maximum X.\n * @param {number} maxY Maximum Y.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdate(minX, minY, maxX, maxY, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = minX;\n opt_extent[1] = minY;\n opt_extent[2] = maxX;\n opt_extent[3] = maxY;\n return opt_extent;\n } else {\n return [minX, minY, maxX, maxY];\n }\n}\n/**\n * Create a new empty extent or make the provided one empty.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdateEmpty(opt_extent) {\n return extent_createOrUpdate(Infinity, Infinity, -Infinity, -Infinity, opt_extent);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdateFromCoordinate(coordinate, opt_extent) {\n var x = coordinate[0];\n var y = coordinate[1];\n return extent_createOrUpdate(x, y, x, y, opt_extent);\n}\n/**\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdateFromCoordinates(coordinates, opt_extent) {\n var extent = extent_createOrUpdateEmpty(opt_extent);\n return extent_extendCoordinates(extent, coordinates);\n}\n/**\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdateFromFlatCoordinates(flatCoordinates, offset, end, stride, opt_extent) {\n var extent = extent_createOrUpdateEmpty(opt_extent);\n return extent_extendFlatCoordinates(extent, flatCoordinates, offset, end, stride);\n}\n/**\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_createOrUpdateFromRings(rings, opt_extent) {\n var extent = extent_createOrUpdateEmpty(opt_extent);\n return extent_extendRings(extent, rings);\n}\n/**\n * Determine if two extents are equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {boolean} The two extents are equivalent.\n * @api\n */\n\nfunction src_extent_equals(extent1, extent2) {\n return extent1[0] == extent2[0] && extent1[2] == extent2[2] && extent1[1] == extent2[1] && extent1[3] == extent2[3];\n}\n/**\n * Determine if two extents are approximately equivalent.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {number} tolerance Tolerance in extent coordinate units.\n * @return {boolean} The two extents differ by less than the tolerance.\n */\n\nfunction extent_approximatelyEquals(extent1, extent2, tolerance) {\n return Math.abs(extent1[0] - extent2[0]) < tolerance && Math.abs(extent1[2] - extent2[2]) < tolerance && Math.abs(extent1[1] - extent2[1]) < tolerance && Math.abs(extent1[3] - extent2[3]) < tolerance;\n}\n/**\n * Modify an extent to include another extent.\n * @param {Extent} extent1 The extent to be modified.\n * @param {Extent} extent2 The extent that will be included in the first.\n * @return {Extent} A reference to the first (extended) extent.\n * @api\n */\n\nfunction src_extent_extend(extent1, extent2) {\n if (extent2[0] < extent1[0]) {\n extent1[0] = extent2[0];\n }\n\n if (extent2[2] > extent1[2]) {\n extent1[2] = extent2[2];\n }\n\n if (extent2[1] < extent1[1]) {\n extent1[1] = extent2[1];\n }\n\n if (extent2[3] > extent1[3]) {\n extent1[3] = extent2[3];\n }\n\n return extent1;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n */\n\nfunction extent_extendCoordinate(extent, coordinate) {\n if (coordinate[0] < extent[0]) {\n extent[0] = coordinate[0];\n }\n\n if (coordinate[0] > extent[2]) {\n extent[2] = coordinate[0];\n }\n\n if (coordinate[1] < extent[1]) {\n extent[1] = coordinate[1];\n }\n\n if (coordinate[1] > extent[3]) {\n extent[3] = coordinate[1];\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<import("./coordinate.js").Coordinate>} coordinates Coordinates.\n * @return {Extent} Extent.\n */\n\nfunction extent_extendCoordinates(extent, coordinates) {\n for (var i = 0, ii = coordinates.length; i < ii; ++i) {\n extent_extendCoordinate(extent, coordinates[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<number>} flatCoordinates Flat coordinates.\n * @param {number} offset Offset.\n * @param {number} end End.\n * @param {number} stride Stride.\n * @return {Extent} Extent.\n */\n\nfunction extent_extendFlatCoordinates(extent, flatCoordinates, offset, end, stride) {\n for (; offset < end; offset += stride) {\n extent_extendXY(extent, flatCoordinates[offset], flatCoordinates[offset + 1]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Array<Array<import("./coordinate.js").Coordinate>>} rings Rings.\n * @return {Extent} Extent.\n */\n\nfunction extent_extendRings(extent, rings) {\n for (var i = 0, ii = rings.length; i < ii; ++i) {\n extent_extendCoordinates(extent, rings[i]);\n }\n\n return extent;\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} x X.\n * @param {number} y Y.\n */\n\nfunction extent_extendXY(extent, x, y) {\n extent[0] = Math.min(extent[0], x);\n extent[1] = Math.min(extent[1], y);\n extent[2] = Math.max(extent[2], x);\n extent[3] = Math.max(extent[3], y);\n}\n/**\n * This function calls `callback` for each corner of the extent. If the\n * callback returns a truthy value the function returns that value\n * immediately. Otherwise the function returns `false`.\n * @param {Extent} extent Extent.\n * @param {function(import("./coordinate.js").Coordinate): S} callback Callback.\n * @return {S|boolean} Value.\n * @template S\n */\n\nfunction extent_forEachCorner(extent, callback) {\n var val;\n val = callback(extent_getBottomLeft(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(extent_getBottomRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(extent_getTopRight(extent));\n\n if (val) {\n return val;\n }\n\n val = callback(extent_getTopLeft(extent));\n\n if (val) {\n return val;\n }\n\n return false;\n}\n/**\n * Get the size of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Area.\n * @api\n */\n\nfunction extent_getArea(extent) {\n var area = 0;\n\n if (!src_extent_isEmpty(extent)) {\n area = src_extent_getWidth(extent) * extent_getHeight(extent);\n }\n\n return area;\n}\n/**\n * Get the bottom left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom left coordinate.\n * @api\n */\n\nfunction extent_getBottomLeft(extent) {\n return [extent[0], extent[1]];\n}\n/**\n * Get the bottom right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Bottom right coordinate.\n * @api\n */\n\nfunction extent_getBottomRight(extent) {\n return [extent[2], extent[1]];\n}\n/**\n * Get the center coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Center.\n * @api\n */\n\nfunction extent_getCenter(extent) {\n return [(extent[0] + extent[2]) / 2, (extent[1] + extent[3]) / 2];\n}\n/**\n * Get a corner coordinate of an extent.\n * @param {Extent} extent Extent.\n * @param {import("./extent/Corner.js").default} corner Corner.\n * @return {import("./coordinate.js").Coordinate} Corner coordinate.\n */\n\nfunction extent_getCorner(extent, corner) {\n var coordinate;\n\n if (corner === Corner.BOTTOM_LEFT) {\n coordinate = extent_getBottomLeft(extent);\n } else if (corner === Corner.BOTTOM_RIGHT) {\n coordinate = extent_getBottomRight(extent);\n } else if (corner === Corner.TOP_LEFT) {\n coordinate = extent_getTopLeft(extent);\n } else if (corner === Corner.TOP_RIGHT) {\n coordinate = extent_getTopRight(extent);\n } else {\n assert(false, 13); // Invalid corner\n }\n\n return coordinate;\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Enlarged area.\n */\n\nfunction extent_getEnlargedArea(extent1, extent2) {\n var minX = Math.min(extent1[0], extent2[0]);\n var minY = Math.min(extent1[1], extent2[1]);\n var maxX = Math.max(extent1[2], extent2[2]);\n var maxY = Math.max(extent1[3], extent2[3]);\n return (maxX - minX) * (maxY - minY);\n}\n/**\n * @param {import("./coordinate.js").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import("./size.js").Size} size Size.\n * @param {Extent=} opt_extent Destination extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_getForViewAndSize(center, resolution, rotation, size, opt_extent) {\n var dx = resolution * size[0] / 2;\n var dy = resolution * size[1] / 2;\n var cosRotation = Math.cos(rotation);\n var sinRotation = Math.sin(rotation);\n var xCos = dx * cosRotation;\n var xSin = dx * sinRotation;\n var yCos = dy * cosRotation;\n var ySin = dy * sinRotation;\n var x = center[0];\n var y = center[1];\n var x0 = x - xCos + ySin;\n var x1 = x - xCos - ySin;\n var x2 = x + xCos - ySin;\n var x3 = x + xCos + ySin;\n var y0 = y - xSin - yCos;\n var y1 = y - xSin + yCos;\n var y2 = y + xSin + yCos;\n var y3 = y + xSin - yCos;\n return extent_createOrUpdate(Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3), Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3), opt_extent);\n}\n/**\n * Get the height of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Height.\n * @api\n */\n\nfunction extent_getHeight(extent) {\n return extent[3] - extent[1];\n}\n/**\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @return {number} Intersection area.\n */\n\nfunction extent_getIntersectionArea(extent1, extent2) {\n var intersection = extent_getIntersection(extent1, extent2);\n return extent_getArea(intersection);\n}\n/**\n * Get the intersection of two extents.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent 2.\n * @param {Extent=} opt_extent Optional extent to populate with intersection.\n * @return {Extent} Intersecting extent.\n * @api\n */\n\nfunction extent_getIntersection(extent1, extent2, opt_extent) {\n var intersection = opt_extent ? opt_extent : extent_createEmpty();\n\n if (extent_intersects(extent1, extent2)) {\n if (extent1[0] > extent2[0]) {\n intersection[0] = extent1[0];\n } else {\n intersection[0] = extent2[0];\n }\n\n if (extent1[1] > extent2[1]) {\n intersection[1] = extent1[1];\n } else {\n intersection[1] = extent2[1];\n }\n\n if (extent1[2] < extent2[2]) {\n intersection[2] = extent1[2];\n } else {\n intersection[2] = extent2[2];\n }\n\n if (extent1[3] < extent2[3]) {\n intersection[3] = extent1[3];\n } else {\n intersection[3] = extent2[3];\n }\n } else {\n extent_createOrUpdateEmpty(intersection);\n }\n\n return intersection;\n}\n/**\n * @param {Extent} extent Extent.\n * @return {number} Margin.\n */\n\nfunction extent_getMargin(extent) {\n return src_extent_getWidth(extent) + extent_getHeight(extent);\n}\n/**\n * Get the size (width, height) of an extent.\n * @param {Extent} extent The extent.\n * @return {import("./size.js").Size} The extent size.\n * @api\n */\n\nfunction extent_getSize(extent) {\n return [extent[2] - extent[0], extent[3] - extent[1]];\n}\n/**\n * Get the top left coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top left coordinate.\n * @api\n */\n\nfunction extent_getTopLeft(extent) {\n return [extent[0], extent[3]];\n}\n/**\n * Get the top right coordinate of an extent.\n * @param {Extent} extent Extent.\n * @return {import("./coordinate.js").Coordinate} Top right coordinate.\n * @api\n */\n\nfunction extent_getTopRight(extent) {\n return [extent[2], extent[3]];\n}\n/**\n * Get the width of an extent.\n * @param {Extent} extent Extent.\n * @return {number} Width.\n * @api\n */\n\nfunction src_extent_getWidth(extent) {\n return extent[2] - extent[0];\n}\n/**\n * Determine if one extent intersects another.\n * @param {Extent} extent1 Extent 1.\n * @param {Extent} extent2 Extent.\n * @return {boolean} The two extents intersect.\n * @api\n */\n\nfunction extent_intersects(extent1, extent2) {\n return extent1[0] <= extent2[2] && extent1[2] >= extent2[0] && extent1[1] <= extent2[3] && extent1[3] >= extent2[1];\n}\n/**\n * Determine if an extent is empty.\n * @param {Extent} extent Extent.\n * @return {boolean} Is empty.\n * @api\n */\n\nfunction src_extent_isEmpty(extent) {\n return extent[2] < extent[0] || extent[3] < extent[1];\n}\n/**\n * @param {Extent} extent Extent.\n * @param {Extent=} opt_extent Extent.\n * @return {Extent} Extent.\n */\n\nfunction extent_returnOrUpdate(extent, opt_extent) {\n if (opt_extent) {\n opt_extent[0] = extent[0];\n opt_extent[1] = extent[1];\n opt_extent[2] = extent[2];\n opt_extent[3] = extent[3];\n return opt_extent;\n } else {\n return extent;\n }\n}\n/**\n * @param {Extent} extent Extent.\n * @param {number} value Value.\n */\n\nfunction extent_scaleFromCenter(extent, value) {\n var deltaX = (extent[2] - extent[0]) / 2 * (value - 1);\n var deltaY = (extent[3] - extent[1]) / 2 * (value - 1);\n extent[0] -= deltaX;\n extent[2] += deltaX;\n extent[1] -= deltaY;\n extent[3] += deltaY;\n}\n/**\n * Determine if the segment between two coordinates intersects (crosses,\n * touches, or is contained by) the provided extent.\n * @param {Extent} extent The extent.\n * @param {import("./coordinate.js").Coordinate} start Segment start coordinate.\n * @param {import("./coordinate.js").Coordinate} end Segment end coordinate.\n * @return {boolean} The segment intersects the extent.\n */\n\nfunction extent_intersectsSegment(extent, start, end) {\n var intersects = false;\n var startRel = extent_coordinateRelationship(extent, start);\n var endRel = extent_coordinateRelationship(extent, end);\n\n if (startRel === Relationship.INTERSECTING || endRel === Relationship.INTERSECTING) {\n intersects = true;\n } else {\n var minX = extent[0];\n var minY = extent[1];\n var maxX = extent[2];\n var maxY = extent[3];\n var startX = start[0];\n var startY = start[1];\n var endX = end[0];\n var endY = end[1];\n var slope = (endY - startY) / (endX - startX);\n var x, y;\n\n if (!!(endRel & Relationship.ABOVE) && !(startRel & Relationship.ABOVE)) {\n // potentially intersects top\n x = endX - (endY - maxY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & Relationship.RIGHT) && !(startRel & Relationship.RIGHT)) {\n // potentially intersects right\n y = endY - (endX - maxX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n\n if (!intersects && !!(endRel & Relationship.BELOW) && !(startRel & Relationship.BELOW)) {\n // potentially intersects bottom\n x = endX - (endY - minY) / slope;\n intersects = x >= minX && x <= maxX;\n }\n\n if (!intersects && !!(endRel & Relationship.LEFT) && !(startRel & Relationship.LEFT)) {\n // potentially intersects left\n y = endY - (endX - minX) * slope;\n intersects = y >= minY && y <= maxY;\n }\n }\n\n return intersects;\n}\n/**\n * Apply a transform function to the extent.\n * @param {Extent} extent Extent.\n * @param {import("./proj.js").TransformFunction} transformFn Transform function.\n * Called with `[minX, minY, maxX, maxY]` extent coordinates.\n * @param {Extent=} opt_extent Destination extent.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {Extent} Extent.\n * @api\n */\n\nfunction extent_applyTransform(extent, transformFn, opt_extent, opt_stops) {\n var coordinates = [];\n\n if (opt_stops > 1) {\n var width = extent[2] - extent[0];\n var height = extent[3] - extent[1];\n\n for (var i = 0; i < opt_stops; ++i) {\n coordinates.push(extent[0] + width * i / opt_stops, extent[1], extent[2], extent[1] + height * i / opt_stops, extent[2] - width * i / opt_stops, extent[3], extent[0], extent[3] - height * i / opt_stops);\n }\n } else {\n coordinates = [extent[0], extent[1], extent[2], extent[1], extent[2], extent[3], extent[0], extent[3]];\n }\n\n transformFn(coordinates, coordinates, 2);\n var xs = [];\n var ys = [];\n\n for (var _i = 0, l = coordinates.length; _i < l; _i += 2) {\n xs.push(coordinates[_i]);\n ys.push(coordinates[_i + 1]);\n }\n\n return extent_boundingExtentXYs(xs, ys, opt_extent);\n}\n/**\n * Modifies the provided extent in-place to be within the real world\n * extent.\n *\n * @param {Extent} extent Extent.\n * @param {import("./proj/Projection.js").default} projection Projection\n * @return {Extent} The extent within the real world extent.\n */\n\nfunction extent_wrapX(extent, projection) {\n var projectionExtent = projection.getExtent();\n var center = extent_getCenter(extent);\n\n if (projection.canWrapX() && (center[0] < projectionExtent[0] || center[0] >= projectionExtent[2])) {\n var worldWidth = src_extent_getWidth(projectionExtent);\n var worldsAway = Math.floor((center[0] - projectionExtent[0]) / worldWidth);\n var offset = worldsAway * worldWidth;\n extent[0] -= offset;\n extent[2] -= offset;\n }\n\n return extent;\n}\n;// CONCATENATED MODULE: ./node_modules/ol/src/proj.js\n/**\n * @module ol/proj\n */\n\n/**\n * The ol/proj module stores:\n * * a list of {@link module:ol/proj/Projection}\n * objects, one for each projection supported by the application\n * * a list of transform functions needed to convert coordinates in one projection\n * into another.\n *\n * The static functions are the methods used to maintain these.\n * Each transform function can handle not only simple coordinate pairs, but also\n * large arrays of coordinates such as vector geometries.\n *\n * When loaded, the library adds projection objects for EPSG:4326 (WGS84\n * geographic coordinates) and EPSG:3857 (Web or Spherical Mercator, as used\n * for example by Bing Maps or OpenStreetMap), together with the relevant\n * transform functions.\n *\n * Additional transforms may be added by using the http://proj4js.org/\n * library (version 2.2 or later). You can use the full build supplied by\n * Proj4js, or create a custom build to support those projections you need; see\n * the Proj4js website for how to do this. You also need the Proj4js definitions\n * for the required projections. These definitions can be obtained from\n * https://epsg.io/, and are a JS function, so can be loaded in a script\n * tag (as in the examples) or pasted into your application.\n *\n * After all required projection definitions are added to proj4\'s registry (by\n * using `proj4.defs()`), simply call `register(proj4)` from the `ol/proj/proj4`\n * package. Existing transforms are not changed by this function. See\n * examples/wms-image-custom-proj for an example of this.\n *\n * Additional projection definitions can be registered with `proj4.defs()` any\n * time. Just make sure to call `register(proj4)` again; for example, with user-supplied data where you don\'t\n * know in advance what projections are needed, you can initially load minimal\n * support and then load whichever are requested.\n *\n * Note that Proj4js does not support projection extents. If you want to add\n * one for creating default tile grids, you can add it after the Projection\n * object has been created with `setExtent`, for example,\n * `get(\'EPSG:1234\').setExtent(extent)`.\n *\n * In addition to Proj4js support, any transform functions can be added with\n * {@link module:ol/proj~addCoordinateTransforms}. To use this, you must first create\n * a {@link module:ol/proj/Projection} object for the new projection and add it with\n * {@link module:ol/proj~addProjection}. You can then add the forward and inverse\n * functions with {@link module:ol/proj~addCoordinateTransforms}. See\n * examples/wms-custom-proj for an example of this.\n *\n * Note that if no transforms are needed and you only need to define the\n * projection, just add a {@link module:ol/proj/Projection} with\n * {@link module:ol/proj~addProjection}. See examples/wms-no-proj for an example of\n * this.\n */\n\n\n\n\n\n\n\n\n\n\n/**\n * A projection as {@link module:ol/proj/Projection}, SRS identifier\n * string or undefined.\n * @typedef {Projection|string|undefined} ProjectionLike\n * @api\n */\n\n/**\n * A transform function accepts an array of input coordinate values, an optional\n * output array, and an optional dimension (default should be 2). The function\n * transforms the input coordinate values, populates the output array, and\n * returns the output array.\n *\n * @typedef {function(Array<number>, Array<number>=, number=): Array<number>} TransformFunction\n * @api\n */\n\n\n\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output coordinate array (new array, same coordinate\n * values).\n */\n\nfunction proj_cloneTransform(input, opt_output, opt_dimension) {\n var output;\n\n if (opt_output !== undefined) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n output = opt_output;\n } else {\n output = input.slice();\n }\n\n return output;\n}\n/**\n * @param {Array<number>} input Input coordinate array.\n * @param {Array<number>=} opt_output Output array of coordinate values.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Input coordinate array (same array as input).\n */\n\nfunction proj_identityTransform(input, opt_output, opt_dimension) {\n if (opt_output !== undefined && input !== opt_output) {\n for (var i = 0, ii = input.length; i < ii; ++i) {\n opt_output[i] = input[i];\n }\n\n input = opt_output;\n }\n\n return input;\n}\n/**\n * Add a Projection object to the list of supported projections that can be\n * looked up by their code.\n *\n * @param {Projection} projection Projection instance.\n * @api\n */\n\nfunction proj_addProjection(projection) {\n proj_projections_add(projection.getCode(), projection);\n proj_transforms_add(projection, projection, proj_cloneTransform);\n}\n/**\n * @param {Array<Projection>} projections Projections.\n */\n\nfunction proj_addProjections(projections) {\n projections.forEach(proj_addProjection);\n}\n/**\n * Fetches a Projection object for the code specified.\n *\n * @param {ProjectionLike} projectionLike Either a code string which is\n * a combination of authority and identifier such as "EPSG:4326", or an\n * existing projection object, or undefined.\n * @return {Projection} Projection object, or null if not in list.\n * @api\n */\n\nfunction src_proj_get(projectionLike) {\n return typeof projectionLike === \'string\' ? projections_get(\n /** @type {string} */\n projectionLike) :\n /** @type {Projection} */\n projectionLike || null;\n}\n/**\n * Get the resolution of the point in degrees or distance units.\n * For projections with degrees as the unit this will simply return the\n * provided resolution. For other projections the point resolution is\n * by default estimated by transforming the \'point\' pixel to EPSG:4326,\n * measuring its width and height on the normal sphere,\n * and taking the average of the width and height.\n * A custom function can be provided for a specific projection, either\n * by setting the `getPointResolution` option in the\n * {@link module:ol/proj/Projection~Projection} constructor or by using\n * {@link module:ol/proj/Projection~Projection#setGetPointResolution} to change an existing\n * projection object.\n * @param {ProjectionLike} projection The projection.\n * @param {number} resolution Nominal resolution in projection units.\n * @param {import("./coordinate.js").Coordinate} point Point to find adjusted resolution at.\n * @param {import("./proj/Units.js").default=} opt_units Units to get the point resolution in.\n * Default is the projection\'s units.\n * @return {number} Point resolution.\n * @api\n */\n\nfunction proj_getPointResolution(projection, resolution, point, opt_units) {\n projection = src_proj_get(projection);\n var pointResolution;\n var getter = projection.getPointResolutionFunc();\n\n if (getter) {\n pointResolution = getter(resolution, point);\n\n if (opt_units && opt_units !== projection.getUnits()) {\n var metersPerUnit = projection.getMetersPerUnit();\n\n if (metersPerUnit) {\n pointResolution = pointResolution * metersPerUnit / METERS_PER_UNIT[opt_units];\n }\n }\n } else {\n var units = projection.getUnits();\n\n if (units == Units.DEGREES && !opt_units || opt_units == Units.DEGREES) {\n pointResolution = resolution;\n } else {\n // Estimate point resolution by transforming the center pixel to EPSG:4326,\n // measuring its width and height on the normal sphere, and taking the\n // average of the width and height.\n var _toEPSG = proj_getTransformFromProjections(projection, src_proj_get(\'EPSG:4326\'));\n\n if (_toEPSG === proj_identityTransform && units !== Units.DEGREES) {\n // no transform is available\n pointResolution = resolution * projection.getMetersPerUnit();\n } else {\n var vertices = [point[0] - resolution / 2, point[1], point[0] + resolution / 2, point[1], point[0], point[1] - resolution / 2, point[0], point[1] + resolution / 2];\n vertices = _toEPSG(vertices, vertices, 2);\n var width = getDistance(vertices.slice(0, 2), vertices.slice(2, 4));\n var height = getDistance(vertices.slice(4, 6), vertices.slice(6, 8));\n pointResolution = (width + height) / 2;\n }\n\n var _metersPerUnit = opt_units ? METERS_PER_UNIT[opt_units] : projection.getMetersPerUnit();\n\n if (_metersPerUnit !== undefined) {\n pointResolution /= _metersPerUnit;\n }\n }\n }\n\n return pointResolution;\n}\n/**\n * Registers transformation functions that don\'t alter coordinates. Those allow\n * to transform between projections with equal meaning.\n *\n * @param {Array<Projection>} projections Projections.\n * @api\n */\n\nfunction proj_addEquivalentProjections(projections) {\n proj_addProjections(projections);\n projections.forEach(function (source) {\n projections.forEach(function (destination) {\n if (source !== destination) {\n proj_transforms_add(source, destination, proj_cloneTransform);\n }\n });\n });\n}\n/**\n * Registers transformation functions to convert coordinates in any projection\n * in projection1 to any projection in projection2.\n *\n * @param {Array<Projection>} projections1 Projections with equal\n * meaning.\n * @param {Array<Projection>} projections2 Projections with equal\n * meaning.\n * @param {TransformFunction} forwardTransform Transformation from any\n * projection in projection1 to any projection in projection2.\n * @param {TransformFunction} inverseTransform Transform from any projection\n * in projection2 to any projection in projection1..\n */\n\nfunction proj_addEquivalentTransforms(projections1, projections2, forwardTransform, inverseTransform) {\n projections1.forEach(function (projection1) {\n projections2.forEach(function (projection2) {\n proj_transforms_add(projection1, projection2, forwardTransform);\n proj_transforms_add(projection2, projection1, inverseTransform);\n });\n });\n}\n/**\n * Clear all cached projections and transforms.\n */\n\nfunction proj_clearAllProjections() {\n clearProj();\n clearTransformFuncs();\n}\n/**\n * @param {Projection|string|undefined} projection Projection.\n * @param {string} defaultCode Default code.\n * @return {Projection} Projection.\n */\n\nfunction proj_createProjection(projection, defaultCode) {\n if (!projection) {\n return src_proj_get(defaultCode);\n } else if (typeof projection === \'string\') {\n return src_proj_get(projection);\n } else {\n return (\n /** @type {Projection} */\n projection\n );\n }\n}\n/**\n * Creates a {@link module:ol/proj~TransformFunction} from a simple 2D coordinate transform\n * function.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} coordTransform Coordinate\n * transform.\n * @return {TransformFunction} Transform function.\n */\n\nfunction proj_createTransformFromCoordinateTransform(coordTransform) {\n return (\n /**\n * @param {Array<number>} input Input.\n * @param {Array<number>=} opt_output Output.\n * @param {number=} opt_dimension Dimension.\n * @return {Array<number>} Output.\n */\n function (input, opt_output, opt_dimension) {\n var length = input.length;\n var dimension = opt_dimension !== undefined ? opt_dimension : 2;\n var output = opt_output !== undefined ? opt_output : new Array(length);\n\n for (var i = 0; i < length; i += dimension) {\n var point = coordTransform([input[i], input[i + 1]]);\n output[i] = point[0];\n output[i + 1] = point[1];\n\n for (var j = dimension - 1; j >= 2; --j) {\n output[i + j] = input[i + j];\n }\n }\n\n return output;\n }\n );\n}\n/**\n * Registers coordinate transform functions to convert coordinates between the\n * source projection and the destination projection.\n * The forward and inverse functions convert coordinate pairs; this function\n * converts these into the functions used internally which also handle\n * extents and coordinate arrays.\n *\n * @param {ProjectionLike} source Source projection.\n * @param {ProjectionLike} destination Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} forward The forward transform\n * function (that is, from the source projection to the destination\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} inverse The inverse transform\n * function (that is, from the destination projection to the source\n * projection) that takes a {@link module:ol/coordinate~Coordinate} as argument and returns\n * the transformed {@link module:ol/coordinate~Coordinate}.\n * @api\n */\n\nfunction proj_addCoordinateTransforms(source, destination, forward, inverse) {\n var sourceProj = src_proj_get(source);\n var destProj = src_proj_get(destination);\n addTransformFunc(sourceProj, destProj, proj_createTransformFromCoordinateTransform(forward));\n addTransformFunc(destProj, sourceProj, proj_createTransformFromCoordinateTransform(inverse));\n}\n/**\n * Transforms a coordinate from longitude/latitude to a different projection.\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate as longitude and latitude, i.e.\n * an array with longitude as 1st and latitude as 2nd element.\n * @param {ProjectionLike=} opt_projection Target projection. The\n * default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate projected to the target projection.\n * @api\n */\n\nfunction proj_fromLonLat(coordinate, opt_projection) {\n return proj_transform(coordinate, \'EPSG:4326\', opt_projection !== undefined ? opt_projection : \'EPSG:3857\');\n}\n/**\n * Transforms a coordinate to longitude/latitude.\n * @param {import("./coordinate.js").Coordinate} coordinate Projected coordinate.\n * @param {ProjectionLike=} opt_projection Projection of the coordinate.\n * The default is Web Mercator, i.e. \'EPSG:3857\'.\n * @return {import("./coordinate.js").Coordinate} Coordinate as longitude and latitude, i.e. an array\n * with longitude as 1st and latitude as 2nd element.\n * @api\n */\n\nfunction proj_toLonLat(coordinate, opt_projection) {\n var lonLat = proj_transform(coordinate, opt_projection !== undefined ? opt_projection : \'EPSG:3857\', \'EPSG:4326\');\n var lon = lonLat[0];\n\n if (lon < -180 || lon > 180) {\n lonLat[0] = modulo(lon + 180, 360) - 180;\n }\n\n return lonLat;\n}\n/**\n * Checks if two projections are the same, that is every coordinate in one\n * projection does represent the same geographic point as the same coordinate in\n * the other projection.\n *\n * @param {Projection} projection1 Projection 1.\n * @param {Projection} projection2 Projection 2.\n * @return {boolean} Equivalent.\n * @api\n */\n\nfunction proj_equivalent(projection1, projection2) {\n if (projection1 === projection2) {\n return true;\n }\n\n var equalUnits = projection1.getUnits() === projection2.getUnits();\n\n if (projection1.getCode() === projection2.getCode()) {\n return equalUnits;\n } else {\n var transformFunc = proj_getTransformFromProjections(projection1, projection2);\n return transformFunc === proj_cloneTransform && equalUnits;\n }\n}\n/**\n * Searches in the list of transform functions for the function for converting\n * coordinates from the source projection to the destination projection.\n *\n * @param {Projection} sourceProjection Source Projection object.\n * @param {Projection} destinationProjection Destination Projection\n * object.\n * @return {TransformFunction} Transform function.\n */\n\nfunction proj_getTransformFromProjections(sourceProjection, destinationProjection) {\n var sourceCode = sourceProjection.getCode();\n var destinationCode = destinationProjection.getCode();\n var transformFunc = proj_transforms_get(sourceCode, destinationCode);\n\n if (!transformFunc) {\n transformFunc = proj_identityTransform;\n }\n\n return transformFunc;\n}\n/**\n * Given the projection-like objects, searches for a transformation\n * function to convert a coordinates array from the source projection to the\n * destination projection.\n *\n * @param {ProjectionLike} source Source.\n * @param {ProjectionLike} destination Destination.\n * @return {TransformFunction} Transform function.\n * @api\n */\n\nfunction proj_getTransform(source, destination) {\n var sourceProjection = src_proj_get(source);\n var destinationProjection = src_proj_get(destination);\n return proj_getTransformFromProjections(sourceProjection, destinationProjection);\n}\n/**\n * Transforms a coordinate from source projection to destination projection.\n * This returns a new coordinate (and does not modify the original).\n *\n * See {@link module:ol/proj~transformExtent} for extent transformation.\n * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its\n * subclasses for geometry transforms.\n *\n * @param {import("./coordinate.js").Coordinate} coordinate Coordinate.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @return {import("./coordinate.js").Coordinate} Coordinate.\n * @api\n */\n\nfunction proj_transform(coordinate, source, destination) {\n var transformFunc = proj_getTransform(source, destination);\n return transformFunc(coordinate, undefined, coordinate.length);\n}\n/**\n * Transforms an extent from source projection to destination projection. This\n * returns a new extent (and does not modify the original).\n *\n * @param {import("./extent.js").Extent} extent The extent to transform.\n * @param {ProjectionLike} source Source projection-like.\n * @param {ProjectionLike} destination Destination projection-like.\n * @param {number=} opt_stops Number of stops per side used for the transform.\n * By default only the corners are used.\n * @return {import("./extent.js").Extent} The transformed extent.\n * @api\n */\n\nfunction src_proj_transformExtent(extent, source, destination, opt_stops) {\n var transformFunc = proj_getTransform(source, destination);\n return extent_applyTransform(extent, transformFunc, undefined, opt_stops);\n}\n/**\n * Transforms the given point to the destination projection.\n *\n * @param {import("./coordinate.js").Coordinate} point Point.\n * @param {Projection} sourceProjection Source projection.\n * @param {Projection} destinationProjection Destination projection.\n * @return {import("./coordinate.js").Coordinate} Point.\n */\n\nfunction proj_transformWithProjections(point, sourceProjection, destinationProjection) {\n var transformFunc = proj_getTransformFromProjections(sourceProjection, destinationProjection);\n return transformFunc(point);\n}\n/**\n * @type {?Projection}\n */\n\nvar proj_userProjection = null;\n/**\n * Set the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @param {ProjectionLike} projection The user projection.\n */\n\nfunction proj_setUserProjection(projection) {\n proj_userProjection = src_proj_get(projection);\n}\n/**\n * Clear the user projection if set. Note that this method is not yet a part of\n * the stable API. Support for user projections is not yet complete and should\n * be considered experimental.\n */\n\nfunction proj_clearUserProjection() {\n proj_userProjection = null;\n}\n/**\n * Get the projection for coordinates supplied from and returned by API methods.\n * Note that this method is not yet a part of the stable API. Support for user\n * projections is not yet complete and should be considered experimental.\n * @returns {?Projection} The user projection (or null if not set).\n */\n\nfunction proj_getUserProjection() {\n return proj_userProjection;\n}\n/**\n * Use geographic coordinates (WGS-84 datum) in API methods. Note that this\n * method is not yet a part of the stable API. Support for user projections is\n * not yet complete and should be considered experimental.\n */\n\nfunction proj_useGeographic() {\n proj_setUserProjection(\'EPSG:4326\');\n}\n/**\n * Return a coordinate transformed into the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} sourceProjection The input coordinate projection.\n * @returns {Array<number>} The input coordinate in the user projection.\n */\n\nfunction proj_toUserCoordinate(coordinate, sourceProjection) {\n if (!proj_userProjection) {\n return coordinate;\n }\n\n return proj_transform(coordinate, sourceProjection, proj_userProjection);\n}\n/**\n * Return a coordinate transformed from the user projection. If no user projection\n * is set, the original coordinate is returned.\n * @param {Array<number>} coordinate Input coordinate.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {Array<number>} The input coordinate transformed.\n */\n\nfunction proj_fromUserCoordinate(coordinate, destProjection) {\n if (!proj_userProjection) {\n return coordinate;\n }\n\n return proj_transform(coordinate, proj_userProjection, destProjection);\n}\n/**\n * Return an extent transformed into the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} sourceProjection The input extent projection.\n * @returns {import("./extent.js").Extent} The input extent in the user projection.\n */\n\nfunction proj_toUserExtent(extent, sourceProjection) {\n if (!proj_userProjection) {\n return extent;\n }\n\n return src_proj_transformExtent(extent, sourceProjection, proj_userProjection);\n}\n/**\n * Return an extent transformed from the user projection. If no user projection\n * is set, the original extent is returned.\n * @param {import("./extent.js").Extent} extent Input extent.\n * @param {ProjectionLike} destProjection The destination projection.\n * @returns {import("./extent.js").Extent} The input extent transformed.\n */\n\nfunction proj_fromUserExtent(extent, destProjection) {\n if (!proj_userProjection) {\n return extent;\n }\n\n return src_proj_transformExtent(extent, proj_userProjection, destProjection);\n}\n/**\n * Creates a safe coordinate transform function from a coordinate transform function.\n * "Safe" means that it can handle wrapping of x-coordinates for global projections,\n * and that coordinates exceeding the source projection validity extent\'s range will be\n * clamped to the validity range.\n * @param {Projection} sourceProj Source projection.\n * @param {Projection} destProj Destination projection.\n * @param {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} transform Transform function (source to destiation).\n * @return {function(import("./coordinate.js").Coordinate): import("./coordinate.js").Coordinate} Safe transform function (source to destiation).\n */\n\nfunction proj_createSafeCoordinateTransform(sourceProj, destProj, transform) {\n return function (coord) {\n var sourceX = coord[0];\n var sourceY = coord[1];\n var transformed, worldsAway;\n\n if (sourceProj.canWrapX()) {\n var sourceExtent = sourceProj.getExtent();\n var sourceExtentWidth = getWidth(sourceExtent);\n worldsAway = getWorldsAway(coord, sourceProj, sourceExtentWidth);\n\n if (worldsAway) {\n // Move x to the real world\n sourceX = sourceX - worldsAway * sourceExtentWidth;\n }\n\n sourceX = clamp(sourceX, sourceExtent[0], sourceExtent[2]);\n sourceY = clamp(sourceY, sourceExtent[1], sourceExtent[3]);\n transformed = transform([sourceX, sourceY]);\n } else {\n transformed = transform(coord);\n }\n\n if (worldsAway && destProj.canWrapX()) {\n // Move transformed coordinate back to the offset world\n transformed[0] += worldsAway * getWidth(destProj.getExtent());\n }\n\n return transformed;\n };\n}\n/**\n * Add transforms to and from EPSG:4326 and EPSG:3857. This function is called\n * by when this module is executed and should only need to be called again after\n * `clearAllProjections()` is called (e.g. in tests).\n */\n\nfunction proj_addCommon() {\n // Add transformations that don\'t alter coordinates to convert within set of\n // projections with equal meaning.\n proj_addEquivalentProjections(epsg3857_PROJECTIONS);\n proj_addEquivalentProjections(proj_epsg4326_PROJECTIONS); // Add transformations to convert EPSG:4326 like coordinates to EPSG:3857 like\n // coordinates and back.\n\n proj_addEquivalentTransforms(proj_epsg4326_PROJECTIONS, epsg3857_PROJECTIONS, epsg3857_fromEPSG4326, epsg3857_toEPSG4326);\n}\nproj_addCommon();\n;// CONCATENATED MODULE: ./src/components/openlayersMap.module.scss\n// extracted by mini-css-extract-plugin\nvar mapContainer = "openlayersMap-module--mapContainer--1V7bt";\n;// CONCATENATED MODULE: ./src/components/openlayersMap.tsx\n// The below adapted from\n// https://taylor.callsen.me/using-openlayers-with-react-functional-components/\nvar MapWrapper=function MapWrapper(_ref){var features=_ref.features;var _useState=(0,react.useState)(),map=_useState[0],setMap=_useState[1];var _useState2=(0,react.useState)(),featuresLayer=_useState2[0],setFeaturesLayer=_useState2[1];var _useState3=(0,react.useState)(),selectedFeature=_useState3[0],setSelectedFeature=_useState3[1];var _useState4=(0,react.useState)(4),currentZoom=_useState4[0],setCurrentZoom=_useState4[1];var _useState5=(0,react.useState)([]),currentOverlayPosition=_useState5[0],setCurrentOverlayPosition=_useState5[1];var mapElement=(0,react.useRef)();// create state ref that can be accessed in OpenLayers onclick callback function\n// https://stackoverflow.com/a/60643670\nvar mapRef=(0,react.useRef)();if(map){mapRef.current=map;}var transform=function transform(extent){return src_proj_transformExtent(extent,\'EPSG:4326\',\'EPSG:3857\');};(0,react.useEffect)(function(){var view=new ol_View({center:fromLonLat(DEFAULT_CENTER),zoom:4,maxZoom:GLOBAL_MAX_ZOOM,minZoom:GLOBAL_MIN_ZOOM,extent:transform(GLOBAL_MAX_BOUNDS.flat())});// create and add initial vector source layer, to be replaced layer\nvar initialFeaturesLayer=new Vector({source:new source_Vector()});var initialMap=new ol_Map({target:mapElement.current,view:view,controls:[]});var currentZoom=Math.floor(initialMap.getView().getZoom()||GLOBAL_MIN_ZOOM);initialMap.on(\'moveend\',handleMoveEnd);initialMap.on(\'click\',handleMapClick);setMap(initialMap);setCurrentZoom(currentZoom);setFeaturesLayer(initialFeaturesLayer);olms(initialMap,data_mapStyle);},[]);// update map if features prop changes\n(0,react.useEffect)(function(){if(features.length){// may be empty on first render\n// set features to map\nfeaturesLayer===null||featuresLayer===void 0?void 0:featuresLayer.setSource(new source_Vector({features:features}));var extent=featuresLayer===null||featuresLayer===void 0?void 0:featuresLayer.getSource().getExtent();if(extent){// fit map to feature extent (with 100px of padding)\nmap===null||map===void 0?void 0:map.getView().fit(extent,{padding:[100,100,100,100]});}}},[features]);var handleMapClick=function handleMapClick(event){var clickedCoord=mapRef.current.getCoordinateFromPixel(event.pixel);var featureFound=false;mapRef.current.forEachFeatureAtPixel(event.pixel,function(feature){featureFound=true;setSelectedFeature(feature);return true;});if(!featureFound){setSelectedFeature(undefined);}setCurrentOverlayPosition(clickedCoord);};var handleMoveEnd=function handleMoveEnd(){var newZoom=Math.floor(mapRef.current.getView().getZoom()||GLOBAL_MIN_ZOOM);if(currentZoom!=newZoom){setCurrentZoom(newZoom);}};return/*#__PURE__*/react.createElement(react.Fragment,null,/*#__PURE__*/react.createElement("div",{ref:mapElement,className:mapContainer}),map?/*#__PURE__*/react.createElement(openlayersPopup,{selectedFeature:selectedFeature,map:map,position:currentOverlayPosition}):\'\',/*#__PURE__*/react.createElement(components_zoomWarning,{zoomLevel:currentZoom}));};/* harmony default export */ var openlayersMap = (MapWrapper);\n;// CONCATENATED MODULE: ./src/components/mapWrapper.tsx\nvar mapWrapper_MapWrapper=function MapWrapper(){var flags=(0,FlagContext/* useFlags */.Vb)();return/*#__PURE__*/react.createElement("div",null,flags.includes(\'mb\')?/*#__PURE__*/react.createElement(mapboxMap,null):/*#__PURE__*/react.createElement(openlayersMap,{features:[]}));};/* harmony default export */ var mapWrapper = (mapWrapper_MapWrapper);\n;// CONCATENATED MODULE: ./src/components/HowYouCanHelp.module.scss\n// extracted by mini-css-extract-plugin\nvar howYouCanHelpContainer = "HowYouCanHelp-module--howYouCanHelpContainer--2kqBa";\n;// CONCATENATED MODULE: ./src/components/HowYouCanHelp.tsx\nvar HowYouCanHelp=function HowYouCanHelp(){return/*#__PURE__*/react.createElement("div",{className:howYouCanHelpContainer},/*#__PURE__*/react.createElement("h2",null,"How You Can Help Improve the Tool"),/*#__PURE__*/react.createElement("ul",null,/*#__PURE__*/react.createElement("li",null,"If you have information that could help, we\\u2019d love to hear from you."),/*#__PURE__*/react.createElement("li",null,"View our full set of data sources and methodology where you can add or download sources and check statuses on our data roadmap."),/*#__PURE__*/react.createElement("li",null,"Check out our timeline and send feedback or attend relevant events."),/*#__PURE__*/react.createElement("li",null,"Contact us and share the stories of your community.")));};/* harmony default export */ var components_HowYouCanHelp = (HowYouCanHelp);\n;// CONCATENATED MODULE: ./src/components/legend.module.scss\n// extracted by mini-css-extract-plugin\nvar legendContainer = "legend-module--legendContainer--3X460";\nvar swatchContainer = "legend-module--swatchContainer--2GoXi";\nvar legendItem = "legend-module--legendItem--1CJp2";\nvar colorSwatch = "legend-module--colorSwatch--2x6kz";\nvar prioritized = "legend-module--prioritized--1LWQU";\nvar threshold = "legend-module--threshold--11V_A";\nvar nonPrioritized = "legend-module--nonPrioritized--AJqhp";\n;// CONCATENATED MODULE: ./src/components/legend.tsx\nvar Legend=function Legend(){return/*#__PURE__*/react.createElement("div",{className:legendContainer},/*#__PURE__*/react.createElement("h3",{className:legend_module_namespaceObject.legendHeader},"COLOR KEY"),/*#__PURE__*/react.createElement("div",{className:swatchContainer},/*#__PURE__*/react.createElement("div",{className:legendItem},/*#__PURE__*/react.createElement("div",{className:colorSwatch,id:prioritized}),/*#__PURE__*/react.createElement("span",null,"Prioritized Community")),/*#__PURE__*/react.createElement("div",{className:legendItem},/*#__PURE__*/react.createElement("div",{className:colorSwatch,id:threshold}),/*#__PURE__*/react.createElement("span",null,"Threshold Community")),/*#__PURE__*/react.createElement("div",{className:legendItem},/*#__PURE__*/react.createElement("div",{className:colorSwatch,id:nonPrioritized}),/*#__PURE__*/react.createElement("span",null,"Non-Prioritized Community"))));};/* harmony default export */ var legend = (Legend);\n// EXTERNAL MODULE: ./node_modules/@trussworks/react-uswds/lib/index.js\nvar lib = __webpack_require__(2593);\n;// CONCATENATED MODULE: ./src/pages/cejst.module.scss\n// extracted by mini-css-extract-plugin\nvar disclaimer = "cejst-module--disclaimer--3LC1y";\n;// CONCATENATED MODULE: ./src/pages/cejst.tsx\n// import MapWrapper from \'../components/map\';\nvar CEJSTPage=function CEJSTPage(_ref){var location=_ref.location;// We temporarily removed MapControls, which would enable you to `setFeatures` also, for now\n// We will bring back later when we have interactive controls.\nreturn/*#__PURE__*/react.createElement(layout/* default */.Z,{location:location},/*#__PURE__*/react.createElement("main",{id:"main-content",role:"main"},/*#__PURE__*/react.createElement("p",{className:disclaimer},"The Climate and Economic Justice Screening Tool helps identify and prioritize communities across the United States and US territories that have been historically overburdened and underserved so that they may receive 40% of the benefits from investments in six key areas as outlined in the ",/*#__PURE__*/react.createElement("a",{href:\'https://www.whitehouse.gov/briefing-room/\'+\'presidential-actions/2021/01/27/\'+\'executive-order-on-tackling-the-climate-\'+\'crisis-at-home-and-abroad/\',target:\'_blank\',rel:\'noreferrer\'},"Executive Order on Tackling the Climate Crisis at Home and Abroad"),". Explore the map below or learn more about the methodology and data indicators used to prioritize Justice40 communities."),/*#__PURE__*/react.createElement(lib.Alert,{type:"warning",heading:"Limited Data Sources"},/*#__PURE__*/react.createElement("p",null,"In this tool, we are using data sources that our combined by our cumulative impact methodology. Our sources were selected because sit amet, consectetur adipiscing. See all the sources we are investigating on our data roadmap.")),/*#__PURE__*/react.createElement("h2",null,"Explore the Tool"),/*#__PURE__*/react.createElement(mapWrapper,null),/*#__PURE__*/react.createElement(legend,null),/*#__PURE__*/react.createElement(components_HowYouCanHelp,null)));};/* harmony default export */ var cejst = (CEJSTPage);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9kYXRhL2NvbnN0YW50cy50c3g/YmU1YSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9kYXRhL21hcFN0eWxlLnRzeD85ZDk2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvem9vbVdhcm5pbmcubW9kdWxlLnNjc3M/NGIwMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy91c3dkcy9kaXN0L2ltZy91c2EtaWNvbnMvem9vbV9pbi5zdmc/YzM3YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL3pvb21XYXJuaW5nLnRzeD9lYzcxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvcG9wdXBDb250ZW50Lm1vZHVsZS5zY3NzP2Y2NmIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9zcmMvY29tcG9uZW50cy9wb3B1cENvbnRlbnQudHN4PzEwYjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9zcmMvY29tcG9uZW50cy9tYXBib3hNYXAubW9kdWxlLnNjc3M/Nzg0ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL21hcGJveE1hcC50c3g/ZGM5MyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9EaXNwb3NhYmxlLmpzP2I0NDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvYXJyYXkuanM/ZjQyZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9mdW5jdGlvbnMuanM/YTRlZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC91dGlsLmpzP2FkNjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvQXNzZXJ0aW9uRXJyb3IuanM/YzE5YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9hc3NlcnRzLmpzPzdlYWUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvdHJhbnNmb3JtLmpzPzllZGQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZXh0ZW50L0Nvcm5lci5qcz8xMzJjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V4dGVudC9SZWxhdGlvbnNoaXAuanM/NWY0NiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9leHRlbnQuanM/YWI5ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9tYXRoLmpzPzQwODMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvY29sb3IuanM/ZWEzOSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9JY29uSW1hZ2VDYWNoZS5qcz8yODdjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9FdmVudC5qcz8yMzA2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL09iamVjdEV2ZW50VHlwZS5qcz8zM2FkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL29iai5qcz9jM2M5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9UYXJnZXQuanM/M2Y3YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9ldmVudHMvRXZlbnRUeXBlLmpzPzc0NmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZXZlbnRzLmpzP2ZiMmMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvT2JzZXJ2YWJsZS5qcz83MDRkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL09iamVjdC5qcz8zM2FiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1Byb3BlcnR5LmpzPzA3OTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvbGF5ZXIvQmFzZS5qcz9lMjBmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9FdmVudFR5cGUuanM/NDYyMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvU3RhdGUuanM/NTM5NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9MYXllci5qcz9hMjUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Nvb3JkaW5hdGUuanM/OGVjZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXJlci9NYXAuanM/NDAwYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvRXZlbnQuanM/N2Y0ZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9jc3MuanM/NDcwMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9oYXMuanM/ZGMwMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9kb20uanM/YzQxYSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzLmpzPzkxZTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvQ29tcG9zaXRlLmpzPzc2NWMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvQ29sbGVjdGlvbkV2ZW50VHlwZS5qcz81YzJkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL0NvbGxlY3Rpb24uanM/MzA1ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9sYXllci9Hcm91cC5qcz85ZDBiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcEV2ZW50LmpzPzcxYmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50LmpzPzY0NjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50VHlwZS5qcz83M2RkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3BvaW50ZXIvRXZlbnRUeXBlLmpzP2NiMDYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvTWFwQnJvd3NlckV2ZW50SGFuZGxlci5qcz9kMGMxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcEV2ZW50VHlwZS5qcz8xNjUzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcFByb3BlcnR5LmpzP2ZkOWQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3RydWN0cy9Qcmlvcml0eVF1ZXVlLmpzP2Y2MTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZVN0YXRlLmpzP2MzMGYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVGlsZVF1ZXVlLmpzPzk3OTUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9HZW9tZXRyeVR5cGUuanM/MmQyMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL1VuaXRzLmpzPzA1MmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVmlld0hpbnQuanM/NWRkZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9WaWV3UHJvcGVydHkuanM/YTI1ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxlZ3JpZC9jb21tb24uanM/OTQwZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL1Byb2plY3Rpb24uanM/MjM4MCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL2Vwc2czODU3LmpzPzZlMDAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcHJvai9lcHNnNDMyNi5qcz84ODY3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3Byb2ovcHJvamVjdGlvbnMuanM/ZDUzMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qL3RyYW5zZm9ybXMuanM/ZmMxNiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcGhlcmUuanM/ZmIzMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9wcm9qLmpzP2UxZTQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvY2VudGVyY29uc3RyYWludC5qcz9mMjgyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3Jlc29sdXRpb25jb25zdHJhaW50LmpzPzcyYzYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcm90YXRpb25jb25zdHJhaW50LmpzP2I1MDgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZWFzaW5nLmpzPzkxYzUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9HZW9tZXRyeUxheW91dC5qcz9lZjU4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC90cmFuc2Zvcm0uanM/MzQ2MyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL0dlb21ldHJ5LmpzPzc1MjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9TaW1wbGVHZW9tZXRyeS5qcz9iMDQwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9jbG9zZXN0LmpzPzA1MjIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2RlZmxhdGUuanM/OTI3OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvc2ltcGxpZnkuanM/ZTdlYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvaW5mbGF0ZS5qcz8yZDk1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9hcmVhLmpzPzUwZWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9MaW5lYXJSaW5nLmpzPzc3NGYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9Qb2ludC5qcz9mMGFjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9jb250YWlucy5qcz9lNmUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9pbnRlcmlvcnBvaW50LmpzPzg3NDUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L3NlZ21lbnRzLmpzP2ZhMGMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2ludGVyc2VjdHNleHRlbnQuanM/NTU5MSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL2ZsYXQvcmV2ZXJzZS5qcz80MWNmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9vcmllbnQuanM/OWZmMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL1BvbHlnb24uanM/MDc5OCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9WaWV3LmpzP2QxOTciLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc2l6ZS5qcz8xMzE1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL1BsdWdnYWJsZU1hcC5qcz83YTNhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvQ29udHJvbC5qcz9iNzJhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvQXR0cmlidXRpb24uanM/ZTk2NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9jb250cm9sL1JvdGF0ZS5qcz9mNGI1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wvWm9vbS5qcz8xYTFhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbnRyb2wuanM/MjJhMSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9Qcm9wZXJ0eS5qcz8yZDgxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzPzM5MmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRG91YmxlQ2xpY2tab29tLmpzPzQ1YmQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vUG9pbnRlci5qcz80OTBjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2V2ZW50cy9jb25kaXRpb24uanM/YzgyYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9EcmFnUGFuLmpzP2RkYWQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZS5qcz8yMjg4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9Cb3guanM/OTdiZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9EcmFnQm94LmpzPzlmMjAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vRHJhZ1pvb20uanM/MmJjZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9ldmVudHMvS2V5Q29kZS5qcz85NWNmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL0tleWJvYXJkUGFuLmpzPzhhMWIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vS2V5Ym9hcmRab29tLmpzPzEzMjEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvS2luZXRpYy5qcz9mZTBiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2ludGVyYWN0aW9uL01vdXNlV2hlZWxab29tLmpzP2ZhYjEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvaW50ZXJhY3Rpb24vUGluY2hSb3RhdGUuanM/YjYwZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi9QaW5jaFpvb20uanM/MjZiMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9pbnRlcmFjdGlvbi5qcz82MDVmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL01hcC5qcz8xMzdjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL0ltYWdlU3RhdGUuanM/ZmQ2MSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9JbWFnZS5qcz9lNDAyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2NvbG9ybGlrZS5qcz9iZjJiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL1JlZ3VsYXJTaGFwZS5qcz8zNjliIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0NpcmNsZS5qcz8xY2E3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ZpbGwuanM/MDRlMiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9TdHJva2UuanM/NDU4OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9TdHlsZS5qcz85YTRhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL0Jhc2VWZWN0b3IuanM/MWQ2NyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0luc3RydWN0aW9uLmpzP2I3MzAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyL1ZlY3RvckNvbnRleHQuanM/OWVjOCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0J1aWxkZXIuanM/ZjZkMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0ltYWdlQnVpbGRlci5qcz85NmYwIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvTGluZVN0cmluZ0J1aWxkZXIuanM/MzVhMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL1BvbHlnb25CdWlsZGVyLmpzP2E1YWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3R5bGUvVGV4dFBsYWNlbWVudC5qcz85YjZkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vZmxhdC9zdHJhaWdodGNodW5rLmpzPzUxZDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyL2NhbnZhcy9UZXh0QnVpbGRlci5qcz9kZTBkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzP2JjNjUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvTGF5ZXIuanM/MjgzMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXJlci9jYW52YXMvTGF5ZXIuanM/MmVlNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0J1aWxkZXJUeXBlLmpzPzkyMjciLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L3RleHRwYXRoLmpzP2Q0MTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2xlbmd0aC5qcz9mMDJiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9jYW52YXMvRXhlY3V0b3IuanM/YWFmMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXAuanM/ODIyZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL0ltbWVkaWF0ZS5qcz9kZmZiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25BbmNob3JVbml0cy5qcz9kNGQzIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25PcmlnaW4uanM/YWY5YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9JbWFnZUJhc2UuanM/NzRiZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9JbWFnZS5qcz8yYTlkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb25JbWFnZS5qcz9kNDAxIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0eWxlL0ljb24uanM/MjUxMyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXIvY2FudmFzL2hpdGRldGVjdC5qcz8xNzA3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlcmVyL3ZlY3Rvci5qcz83MDY1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlcmVyL2NhbnZhcy9WZWN0b3JMYXllci5qcz81MzVlIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1ZlY3Rvci5qcz9jODBjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3N0cnVjdHMvUkJ1c2guanM/MzEyNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvU291cmNlLmpzP2U0YzkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1ZlY3RvckV2ZW50VHlwZS5qcz83NTlhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xvYWRpbmdzdHJhdGVneS5qcz84OWVjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2Zvcm1hdC9Gb3JtYXRUeXBlLmpzPzExYjgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZmVhdHVyZWxvYWRlci5qcz9lYzUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NvdXJjZS9WZWN0b3IuanM/YTZmZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zdHlsZS9UZXh0LmpzPzZjODMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2ludGVycG9sYXRlLmpzPzcyNWEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZ2VvbS9mbGF0L2NlbnRlci5qcz82NjQ5Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlbmRlci9GZWF0dXJlLmpzPzcyN2QiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wtbWFwYm94LXN0eWxlL2Rpc3QvdXRpbC5qcz83N2FiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sLW1hcGJveC1zdHlsZS9kaXN0L3N0eWxlZnVuY3Rpb24uanM/NzM4NyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9UaWxlUmFuZ2UuanM/NmQ2ZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxlY29vcmQuanM/NTVmZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxlZ3JpZC9UaWxlR3JpZC5qcz9mN2ZkIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3RpbGVncmlkLmpzP2VjNGUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvRmVhdHVyZS5qcz8yODkyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzP2FjNTkiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZm9ybWF0L0ZlYXR1cmUuanM/MDgwNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9mb3JtYXQvSlNPTkZlYXR1cmUuanM/MWE3ZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL0xpbmVTdHJpbmcuanM/MzIxMCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9nZW9tL011bHRpTGluZVN0cmluZy5qcz8wYWRhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vTXVsdGlQb2ludC5qcz82MzA3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2dlb20vTXVsdGlQb2x5Z29uLmpzPzQzMTUiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvZm9ybWF0L0dlb0pTT04uanM/MDQ3NiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9mb3JtYXQvTVZULmpzP2ZhOWQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvbGF5ZXIvVGlsZVByb3BlcnR5LmpzPzQ0ZjQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvbGF5ZXIvQmFzZVRpbGUuanM/ODA3YyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9yZW5kZXJlci9jYW52YXMvVGlsZUxheWVyLmpzP2RiMjgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvbGF5ZXIvVGlsZS5qcz9hZTFlIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1ZlY3RvclRpbGVSZW5kZXJUeXBlLmpzPzU2NTIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVuZGVyZXIvY2FudmFzL1ZlY3RvclRpbGVMYXllci5qcz84MDI3Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL2xheWVyL1ZlY3RvclRpbGUuanM/ZDlhZSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9UaWxlLmpzPzkzMTAiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvSW1hZ2VUaWxlLmpzP2NmYmYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvcmVwcm9qL2NvbW1vbi5qcz9kMTUyIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlcHJvai9Ucmlhbmd1bGF0aW9uLmpzP2Q5MTEiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL2NvbW1vbi5qcz8xMDU2Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlcHJvai5qcz8xMzU4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3JlcHJvai9UaWxlLmpzPzBmMDIiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3RydWN0cy9MUlVDYWNoZS5qcz9mNGM1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL1RpbGVDYWNoZS5qcz9iMTJiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NvdXJjZS9UaWxlRXZlbnRUeXBlLmpzP2Y4ZjQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc291cmNlL1RpbGUuanM/MDBlNSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC90aWxldXJsZnVuY3Rpb24uanM/OTVhNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvVXJsVGlsZS5qcz82MDRmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NvdXJjZS9UaWxlSW1hZ2UuanM/NjY4NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9uZXQuanM/OTg4NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zb3VyY2UvVGlsZUpTT04uanM/MDRhYyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9WZWN0b3JUaWxlLmpzP2M3MjQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvVmVjdG9yUmVuZGVyVGlsZS5qcz84Nzk1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NvdXJjZS9WZWN0b3JUaWxlLmpzPzFhOGMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wtbWFwYm94LXN0eWxlL2Rpc3QvaW5kZXguanM/NDM4NCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL29wZW5sYXllcnNQb3B1cC5tb2R1bGUuc2Nzcz80MDg0Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL092ZXJsYXlQb3NpdGlvbmluZy5qcz84OGFjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL092ZXJsYXkuanM/OGMzZiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL29wZW5sYXllcnNQb3B1cC50c3g/OTE2OSIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcmMvcHJvai9Vbml0cy5qcz9kOWQ1Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NyYy9wcm9qL1Byb2plY3Rpb24uanM/M2FlYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcmMvbWF0aC5qcz8yYzZhIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NyYy9wcm9qL2Vwc2czODU3LmpzPzM2OWYiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3JjL3Byb2ovZXBzZzQzMjYuanM/MDQyYiIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcmMvcHJvai9wcm9qZWN0aW9ucy5qcz8wZTI4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vbm9kZV9tb2R1bGVzL29sL3NyYy9wcm9qL3RyYW5zZm9ybXMuanM/OGJiNyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL25vZGVfbW9kdWxlcy9vbC9zcmMvZXh0ZW50LmpzP2M0ZjQiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9ub2RlX21vZHVsZXMvb2wvc3JjL3Byb2ouanM/ZWRmZCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL29wZW5sYXllcnNNYXAubW9kdWxlLnNjc3M/YjUyYyIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL29wZW5sYXllcnNNYXAudHN4P2ZkYjgiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9zcmMvY29tcG9uZW50cy9tYXBXcmFwcGVyLnRzeD8xNWI4Iiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvSG93WW91Q2FuSGVscC5tb2R1bGUuc2Nzcz9jY2NiIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvSG93WW91Q2FuSGVscC50c3g/OTBiNCIsIndlYnBhY2s6Ly9qdXN0aWNlNDAtdG9vbC8uL3NyYy9jb21wb25lbnRzL2xlZ2VuZC5tb2R1bGUuc2Nzcz82NjdjIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL2NvbXBvbmVudHMvbGVnZW5kLnRzeD82YjdmIiwid2VicGFjazovL2p1c3RpY2U0MC10b29sLy4vc3JjL3BhZ2VzL2NlanN0Lm1vZHVsZS5zY3NzPzYxZTMiLCJ3ZWJwYWNrOi8vanVzdGljZTQwLXRvb2wvLi9zcmMvcGFnZXMvY2Vqc3QudHN4P2UxZGYiXSwibmFtZXMiOlsiU0NPUkVfUFJPUEVSVFkiLCJHRU9JRF9QUk9QRVJUWSIsIkdMT0JBTF9NSU5fWk9PTSIsIkdMT0JBTF9NQVhfWk9PTSIsIkdMT0JBTF9NSU5fWk9PTV9MT1ciLCJHTE9CQUxfTUFYX1pPT01fTE9XIiwiR0xPQkFMX01JTl9aT09NX0hJR0giLCJHTE9CQUxfTUFYX1pPT01fSElHSCIsIkdMT0JBTF9NQVhfQk9VTkRTIiwiREVGQVVMVF9DRU5URVIiLCJERUZBVUxUX0xBWUVSX09QQUNJVFkiLCJERUZBVUxUX09VVExJTkVfQ09MT1IiLCJNSU5fQ09MT1IiLCJNRURfQ09MT1IiLCJNQVhfQ09MT1IiLCJoZXhUb0hTTEEiLCJoZXgiLCJhbHBoYSIsImNocm9tYSIsImNzcyIsIm1ha2VQYWludCIsImZpZWxkIiwibWluUmFtcCIsIm1lZFJhbXAiLCJtYXhSYW1wIiwiaGlnaCIsInBhaW50RGVzY3JpcHRvciIsImNvbnN0YW50cyIsIm1hcFN0eWxlIiwiWm9vbVdhcm5pbmciLCJ6b29tTGV2ZWwiLCJzdHlsZXMiLCJ6b29tSWNvbiIsIlBvcHVwQ29udGVudCIsInByb3BlcnRpZXMiLCJyZWFkYWJsZVBlcmNlbnQiLCJwZXJjZW50IiwidG9GaXhlZCIsImdldENhdGVnb3JpemF0aW9uIiwicGVyY2VudGlsZSIsImNhdGVnb3JpemF0aW9uIiwiZ2V0VGl0bGVDb250ZW50IiwiYmxvY2tHcm91cCIsInNjb3JlIiwiZ2V0Qm9keUNvbnRlbnQiLCJyb3dzIiwic29ydGVkS2V5cyIsIk9iamVjdCIsImVudHJpZXMiLCJzb3J0Iiwia2V5IiwidmFsdWUiLCJtYXRjaCIsInB1c2giLCJNYXBib3hNYXAiLCJtYXBDb250YWluZXIiLCJSZWFjdCIsIm1hcCIsInVzZVJlZiIsInVzZVN0YXRlIiwiem9vbSIsInNldFpvb20iLCJ1c2VFZmZlY3QiLCJjdXJyZW50IiwiaW5pdGlhbE1hcCIsIk1hcCIsImNvbnRhaW5lciIsInN0eWxlIiwiY2VudGVyIiwibWluWm9vbSIsIm1heFpvb20iLCJtYXhCb3VuZHMiLCJkcmFnUm90YXRlIiwiZGlzYWJsZSIsInRvdWNoWm9vbVJvdGF0ZSIsImRpc2FibGVSb3RhdGlvbiIsIm9uIiwiaGFuZGxlQ2xpY2siLCJhZGRDb250cm9sIiwiTmF2aWdhdGlvbkNvbnRyb2wiLCJzaG93Q29tcGFzcyIsImUiLCJ0YXJnZXQiLCJjbGlja2VkQ29vcmQiLCJwb2ludCIsImZlYXR1cmVzIiwicXVlcnlSZW5kZXJlZEZlYXR1cmVzIiwibGF5ZXJzIiwibGVuZ3RoIiwicGxhY2Vob2xkZXIiLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJSZWFjdERPTSIsIm9wdGlvbnMiLCJvZmZzZXQiLCJjbGFzc05hbWUiLCJmb2N1c0FmdGVyT3BlbiIsIlBvcHVwIiwic2V0TG5nTGF0IiwibG5nTGF0Iiwic2V0RE9NQ29udGVudCIsImFkZFRvIiwiZ2V0Wm9vbSIsImdldENhbnZhcyIsImN1cnNvciIsIk9wZW5sYXllcnNQb3B1cCIsInNlbGVjdGVkRmVhdHVyZSIsInBvc2l0aW9uIiwicG9wdXBDb250YWluZXJFbGVtZW50IiwicG9wdXBDbG9zZXJFbGVtZW50IiwicG9wdXBDb250ZW50RWxlbWVudCIsImN1cnJlbnRPdmVybGF5Iiwic2V0Q3VycmVudE92ZXJsYXkiLCJvbmNsaWNrIiwib3ZlcmxheSIsInNldFBvc2l0aW9uIiwidW5kZWZpbmVkIiwiYmx1ciIsIk92ZXJsYXkiLCJlbGVtZW50IiwiYXV0b1BhbiIsImF1dG9QYW5BbmltYXRpb24iLCJkdXJhdGlvbiIsImFkZE92ZXJsYXkiLCJnZXRQcm9wZXJ0aWVzIiwiTWFwV3JhcHBlciIsInNldE1hcCIsImZlYXR1cmVzTGF5ZXIiLCJzZXRGZWF0dXJlc0xheWVyIiwic2V0U2VsZWN0ZWRGZWF0dXJlIiwiY3VycmVudFpvb20iLCJzZXRDdXJyZW50Wm9vbSIsImN1cnJlbnRPdmVybGF5UG9zaXRpb24iLCJzZXRDdXJyZW50T3ZlcmxheVBvc2l0aW9uIiwibWFwRWxlbWVudCIsIm1hcFJlZiIsInRyYW5zZm9ybSIsImV4dGVudCIsInRyYW5zZm9ybUV4dGVudCIsInZpZXciLCJWaWV3IiwiZnJvbUxvbkxhdCIsImluaXRpYWxGZWF0dXJlc0xheWVyIiwiVmVjdG9yTGF5ZXIiLCJzb3VyY2UiLCJWZWN0b3JTb3VyY2UiLCJjb250cm9scyIsIk1hdGgiLCJmbG9vciIsImdldFZpZXciLCJoYW5kbGVNb3ZlRW5kIiwiaGFuZGxlTWFwQ2xpY2siLCJvbG1zIiwic2V0U291cmNlIiwiZ2V0U291cmNlIiwiZ2V0RXh0ZW50IiwiZml0IiwicGFkZGluZyIsImV2ZW50IiwiZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbCIsInBpeGVsIiwiZmVhdHVyZUZvdW5kIiwiZm9yRWFjaEZlYXR1cmVBdFBpeGVsIiwiZmVhdHVyZSIsIm5ld1pvb20iLCJmbGFncyIsInVzZUZsYWdzIiwiaW5jbHVkZXMiLCJIb3dZb3VD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Q0FBRSxZQU5TLHNFQU5sQiw2SEFERixjQW9CRSxvQkFBQyxTQUFELEVBQ0UsSUFBSSxDQUFDLFNBRFAsQ0FFRSxPQUFPLENBQUMsc0JBRlYsZUFHRSxpUUFIRixDQXBCRixjQStCRSxpREEvQkYsY0FnQ0Usb0JBQUMsVUFBRCxNQWhDRixjQWlDRSxvQkFBQyxNQUFELE1BakNGLGNBa0NFLG9CQUFDLHdCQUFELE1BbENGLENBREYsQ0FERixDQXdDRCxDQTNDRCxDQTZDQSwwQ0FBZTJJLFNBQWYiLCJmaWxlIjoiNzk5OC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFByb3BlcnRpZXNcbmV4cG9ydCBjb25zdCBTQ09SRV9QUk9QRVJUWSA9ICdTY29yZSBEIChwZXJjZW50aWxlKSc7XG5leHBvcnQgY29uc3QgR0VPSURfUFJPUEVSVFkgPSAnR0VPSUQxMCc7XG5leHBvcnQgdHlwZSBKNDBQcm9wZXJ0aWVzID0geyBba2V5OiBzdHJpbmddOiBhbnkgfTtcblxuXG4vLyBab29tXG5leHBvcnQgY29uc3QgR0xPQkFMX01JTl9aT09NID0gMztcbmV4cG9ydCBjb25zdCBHTE9CQUxfTUFYX1pPT00gPSAyMjtcbmV4cG9ydCBjb25zdCBHTE9CQUxfTUlOX1pPT01fTE9XID0gMztcbmV4cG9ydCBjb25zdCBHTE9CQUxfTUFYX1pPT01fTE9XID0gOTtcbmV4cG9ydCBjb25zdCBHTE9CQUxfTUlOX1pPT01fSElHSCA9IDk7XG5leHBvcnQgY29uc3QgR0xPQkFMX01BWF9aT09NX0hJR0ggPSAxMjtcblxuLy8gQm91bmRzXG5leHBvcnQgY29uc3QgR0xPQkFMX01BWF9CT1VORFMgPSBbWy0xNjcuMjc2NDEzLCA1LjQ5OTU1MF0sIFstNTIuMjMzMDQwLCA4My4xNjIxMDJdXTtcbmV4cG9ydCBjb25zdCBERUZBVUxUX0NFTlRFUiA9IFszMi40Njg3MTI2LCAtODYuNTAyMTM2XTtcblxuLy8gT3BhY2l0eVxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTEFZRVJfT1BBQ0lUWSA9IDAuNjtcblxuLy8gQ29sb3JzXG5leHBvcnQgY29uc3QgREVGQVVMVF9PVVRMSU5FX0NPTE9SID0gJyM0RUE1Q0YnO1xuZXhwb3J0IGNvbnN0IE1JTl9DT0xPUiA9ICcjRkZGRkZGJztcbmV4cG9ydCBjb25zdCBNRURfQ09MT1IgPSAnI0QxREFFNic7XG5leHBvcnQgY29uc3QgTUFYX0NPTE9SID0gJyM3NjhGQjMnO1xuIiwiaW1wb3J0IHtTdHlsZSwgRmlsbFBhaW50fSBmcm9tICdtYXBib3gtZ2wnO1xuaW1wb3J0IGNocm9tYSBmcm9tICdjaHJvbWEtanMnO1xuaW1wb3J0ICogYXMgY29uc3RhbnRzIGZyb20gJy4uL2RhdGEvY29uc3RhbnRzJztcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtanNkb2NcbmZ1bmN0aW9uIGhleFRvSFNMQShoZXg6c3RyaW5nLCBhbHBoYTpudW1iZXIpIHtcbiAgcmV0dXJuIGNocm9tYShoZXgpLmFscGhhKGFscGhhKS5jc3MoJ2hzbCcpO1xufVxuXG4vKipcbiAqIGBNYWtlUGFpbnRgIGdlbmVyYXRlcyBhIHpvb20tZmFkZWQgTWFwYm94IHN0eWxlIGZvcm1hdHRlZCBsYXllciBnaXZlbiBhIHNldCBvZiBwYXJhbWV0ZXJzLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWVsZCA6IHRoZSBmaWVsZCB3aXRoaW4gdGhlIGRhdGEgdG8gY29uc3VsdFxuICogQHBhcmFtIHtudW1iZXJ9IG1pblJhbXAgOiB0aGUgbWluaW11bSB2YWx1ZSB0aGlzIGNhbiBhc3N1bWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBtZWRSYW1wIDogdGhlIG1lZGl1bSB2YWx1ZSB0aGlzIGNhbiBhc3N1bWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhSYW1wIDogdGhlIG1heGltdW0gdmFsdWUgdGhpcyBjYW4gYXNzdW1lXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhpZ2ggOiB3aGV0aGVyIHRoaXMgaXMgYSBcImhpZ2hcIiBvciBcImxvd1wiIGxheWVyXG4gKiBAcmV0dXJuIHtGaWxsUGFpbnR9IGEgbWFwYm94Z2wgZmlsbCBsYXllclxuICoqL1xuZnVuY3Rpb24gbWFrZVBhaW50KHtcbiAgZmllbGQsXG4gIG1pblJhbXAsXG4gIG1lZFJhbXAsXG4gIG1heFJhbXAsXG4gIGhpZ2ggPSB0cnVlLFxufToge1xuICAgIGZpZWxkOiBzdHJpbmc7XG4gICAgbWluUmFtcDogbnVtYmVyO1xuICAgIG1lZFJhbXA6IG51bWJlcjtcbiAgICBtYXhSYW1wOiBudW1iZXI7XG4gICAgaGlnaDogYm9vbGVhbjtcbiAgfSk6IEZpbGxQYWludCB7XG4gIGNvbnN0IHBhaW50RGVzY3JpcHRvciA6IEZpbGxQYWludCA9IHtcbiAgICAnZmlsbC1jb2xvcic6IFtcbiAgICAgICdzdGVwJyxcbiAgICAgIFsnZ2V0JywgZmllbGRdLFxuICAgICAgaGV4VG9IU0xBKGNvbnN0YW50cy5NSU5fQ09MT1IsIGNvbnN0YW50cy5ERUZBVUxUX0xBWUVSX09QQUNJVFkgKSxcbiAgICAgIG1pblJhbXAsXG4gICAgICBoZXhUb0hTTEEoY29uc3RhbnRzLk1JTl9DT0xPUiwgY29uc3RhbnRzLkRFRkFVTFRfTEFZRVJfT1BBQ0lUWSApLFxuICAgICAgbWVkUmFtcCxcbiAgICAgIGhleFRvSFNMQShjb25zdGFudHMuTUVEX0NPTE9SLCBjb25zdGFudHMuREVGQVVMVF9MQVlFUl9PUEFDSVRZICksXG4gICAgICBtYXhSYW1wLFxuICAgICAgaGV4VG9IU0xBKGNvbnN0YW50cy5NQVhfQ09MT1IsIGNvbnN0YW50cy5ERUZBVUxUX0xBWUVSX09QQUNJVFkgKSxcbiAgICBdLFxuICB9O1xuICByZXR1cm4gcGFpbnREZXNjcmlwdG9yO1xufVxuXG5jb25zdCBtYXBTdHlsZSA6IFN0eWxlID0ge1xuICAndmVyc2lvbic6IDgsXG4gICdzb3VyY2VzJzoge1xuICAgICdjYXJ0byc6IHtcbiAgICAgICd0eXBlJzogJ3Jhc3RlcicsXG4gICAgICAndGlsZXMnOiBbXG4gICAgICAgICdodHRwczovL2EuYmFzZW1hcHMuY2FydG9jZG4uY29tL2xpZ2h0X25vbGFiZWxzL3t6fS97eH0ve3l9LnBuZycsXG4gICAgICAgICdodHRwczovL2IuYmFzZW1hcHMuY2FydG9jZG4uY29tL2xpZ2h0X25vbGFiZWxzL3t6fS97eH0ve3l9LnBuZycsXG4gICAgICAgICdodHRwczovL2MuYmFzZW1hcHMuY2FydG9jZG4uY29tL2xpZ2h0X25vbGFiZWxzL3t6fS97eH0ve3l9LnBuZycsXG4gICAgICAgICdodHRwczovL2QuYmFzZW1hcHMuY2FydG9jZG4uY29tL2xpZ2h0X25vbGFiZWxzL3t6fS97eH0ve3l9LnBuZycsXG4gICAgICBdLFxuICAgIH0sXG4gICAgJ2dlbyc6IHtcbiAgICAgICd0eXBlJzogJ3Jhc3RlcicsXG4gICAgICAndGlsZXMnOiBbXG4gICAgICAgICdodHRwczovL210MC5nb29nbGUuY29tL3Z0L2x5cnM9cCZobD1lbiZ4PXt4fSZ5PXt5fSZ6PXt6fScsXG4gICAgICBdLFxuICAgIH0sXG4gICAgJ3Njb3JlJzoge1xuICAgICAgJ3R5cGUnOiAndmVjdG9yJyxcbiAgICAgICd0aWxlcyc6IFtcbiAgICAgICAgJ2h0dHBzOi8vZDJ6amlkNm41amEycHQuY2xvdWRmcm9udC5uZXQvMDYyOV9kZW1vL3t6fS97eH0ve3l9LnBiZicsXG4gICAgICAgIC8vIEZvciBsb2NhbCBkZXZlbG9wbWVudCwgdXNlOlxuICAgICAgICAvLyAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL2RhdGEvdGxfMjAxMF9iZ193aXRoX2RhdGEve3p9L3t4fS97eX0ucGJmJyxcbiAgICAgIF0sXG4gICAgfSxcbiAgICAnbGFiZWxzJzoge1xuICAgICAgJ3R5cGUnOiAncmFzdGVyJyxcbiAgICAgICd0aWxlcyc6IFtcbiAgICAgICAgJ2h0dHBzOi8vY2FydG9kYi1iYXNlbWFwcy1hLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldC9saWdodF9vbmx5X2xhYmVscy97en0ve3h9L3t5fUAyeC5wbmcnLFxuICAgICAgICAnaHR0cHM6Ly9jYXJ0b2RiLWJhc2VtYXBzLWIuZ2xvYmFsLnNzbC5mYXN0bHkubmV0L2xpZ2h0X29ubHlfbGFiZWxzL3t6fS97eH0ve3l9QDJ4LnBuZycsXG4gICAgICAgICdodHRwczovL2NhcnRvZGItYmFzZW1hcHMtYy5nbG9iYWwuc3NsLmZhc3RseS5uZXQvbGlnaHRfb25seV9sYWJlbHMve3p9L3t4fS97eX1AMngucG5nJyxcbiAgICAgICAgJ2h0dHBzOi8vY2FydG9kYi1iYXNlbWFwcy1kLmdsb2JhbC5zc2wuZmFzdGx5Lm5ldC9saWdodF9vbmx5X2xhYmVscy97en0ve3h9L3t5fUAyeC5wbmcnLFxuICAgICAgXSxcbiAgICB9LFxuICB9LFxuICAnbGF5ZXJzJzogW1xuICAgIHtcbiAgICAgICdpZCc6ICdjYXJ0bycsXG4gICAgICAnc291cmNlJzogJ2NhcnRvJyxcbiAgICAgICd0eXBlJzogJ3Jhc3RlcicsXG4gICAgICAnbWluem9vbSc6IGNvbnN0YW50cy5HTE9CQUxfTUlOX1pPT00gLSAxLFxuICAgICAgJ21heHpvb20nOiBjb25zdGFudHMuR0xPQkFMX01BWF9aT09NICsgMSxcbiAgICB9LFxuICAgIHtcbiAgICAgICdpZCc6ICdnZW8nLFxuICAgICAgJ3NvdXJjZSc6ICdnZW8nLFxuICAgICAgJ3R5cGUnOiAncmFzdGVyJyxcbiAgICAgICdtaW56b29tJzogY29uc3RhbnRzLkdMT0JBTF9NSU5fWk9PTSAtIDEsXG4gICAgICAnbWF4em9vbSc6IGNvbnN0YW50cy5HTE9CQUxfTUFYX1pPT00gKyAxLFxuICAgICAgJ2xheW91dCc6IHtcbiAgICAgICAgLy8gTWFrZSB0aGUgbGF5ZXIgdmlzaWJsZSBieSBkZWZhdWx0LlxuICAgICAgICAndmlzaWJpbGl0eSc6ICdub25lJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICAnaWQnOiAnc2NvcmUnLFxuICAgICAgJ3NvdXJjZSc6ICdzY29yZScsXG4gICAgICAnc291cmNlLWxheWVyJzogJ2Jsb2NrcycsXG4gICAgICAndHlwZSc6ICdmaWxsJyxcbiAgICAgICdmaWx0ZXInOiBbJ2FsbCcsXG4gICAgICAgIFsnPicsIGNvbnN0YW50cy5TQ09SRV9QUk9QRVJUWSwgMC42XSxcbiAgICAgICAgLy8gWydpbicsICdTVEFURUZQMTAnLCAnMDEnLCAnMzAnLCAnMzQnLCAnMzUnLCAnMzYnXSxcbiAgICAgIF0sXG4gICAgICAncGFpbnQnOiBtYWtlUGFpbnQoe1xuICAgICAgICBmaWVsZDogY29uc3RhbnRzLlNDT1JFX1BST1BFUlRZLFxuICAgICAgICBtaW5SYW1wOiAwLFxuICAgICAgICBtZWRSYW1wOiAwLjYsXG4gICAgICAgIG1heFJhbXA6IDAuNzUsXG4gICAgICAgIGhpZ2g6IHRydWUsXG4gICAgICB9KSxcbiAgICAgICdtaW56b29tJzogY29uc3RhbnRzLkdMT0JBTF9NSU5fWk9PTSxcbiAgICAgICdtYXh6b29tJzogY29uc3RhbnRzLkdMT0JBTF9NQVhfWk9PTSxcbiAgICB9LFxuICAgIHtcbiAgICAgICdpZCc6ICdzY29yZS1oaWdobGlnaHRzJyxcbiAgICAgICdzb3VyY2UnOiAnc2NvcmUnLFxuICAgICAgJ3NvdXJjZS1sYXllcic6ICdibG9ja3MnLFxuICAgICAgJ3R5cGUnOiAnbGluZScsXG4gICAgICAnbWluem9vbSc6IGNvbnN0YW50cy5HTE9CQUxfTUlOX1pPT01fSElHSCxcbiAgICAgICdtYXh6b29tJzogY29uc3RhbnRzLkdMT0JBTF9NQVhfWk9PTV9ISUdILFxuICAgICAgJ2xheW91dCc6IHtcbiAgICAgICAgJ3Zpc2liaWxpdHknOiAndmlzaWJsZScsXG4gICAgICAgICdsaW5lLWpvaW4nOiAncm91bmQnLFxuICAgICAgICAnbGluZS1jYXAnOiAncm91bmQnLFxuICAgICAgfSxcbiAgICAgICdwYWludCc6IHtcbiAgICAgICAgJ2xpbmUtY29sb3InOiBjb25zdGFudHMuREVGQVVMVF9PVVRMSU5FX0NPTE9SLFxuICAgICAgICAnbGluZS13aWR0aCc6IDAuOCxcbiAgICAgICAgJ2xpbmUtb3BhY2l0eSc6IDAuNSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICAnaWQnOiAnbGFiZWxzLW9ubHknLFxuICAgICAgJ3R5cGUnOiAncmFzdGVyJyxcbiAgICAgICdzb3VyY2UnOiAnbGFiZWxzJyxcbiAgICAgICdtaW56b29tJzogY29uc3RhbnRzLkdMT0JBTF9NSU5fWk9PTSxcbiAgICAgICdtYXh6b29tJzogY29uc3RhbnRzLkdMT0JBTF9NQVhfWk9PTSxcbiAgICB9LFxuICBdLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgbWFwU3R5bGU7XG4iLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB2YXIgem9vbVdhcm5pbmcgPSBcInpvb21XYXJuaW5nLW1vZHVsZS0tem9vbVdhcm5pbmctLWpHZU9rXCI7IiwiZXhwb3J0IGRlZmF1bHQgXCJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJR2hsYVdkb2REMGlNalFpSUhacFpYZENiM2c5SWpBZ01DQXlOQ0F5TkNJZ2QybGtkR2c5SWpJMElqNDhjR0YwYUNCa1BTSk5NQ0F3YURJMGRqSTBTREJXTUhvaUlHWnBiR3c5SW01dmJtVWlMejQ4Y0dGMGFDQmtQU0pOTVRVdU5TQXhOR2d0TGpjNWJDMHVNamd0TGpJM1F6RTFMalF4SURFeUxqVTVJREUySURFeExqRXhJREUySURrdU5TQXhOaUExTGpreElERXpMakE1SURNZ09TNDFJRE5UTXlBMUxqa3hJRE1nT1M0MUlEVXVPVEVnTVRZZ09TNDFJREUyWXpFdU5qRWdNQ0F6TGpBNUxTNDFPU0EwTGpJekxURXVOVGRzTGpJM0xqSTRkaTQzT1d3MUlEUXVPVGxNTWpBdU5Ea2dNVGxzTFRRdU9Ua3ROWHB0TFRZZ01FTTNMakF4SURFMElEVWdNVEV1T1RrZ05TQTVMalZUTnk0d01TQTFJRGt1TlNBMUlERTBJRGN1TURFZ01UUWdPUzQxSURFeExqazVJREUwSURrdU5TQXhOSG9pTHo0OGNHRjBhQ0JrUFNKTk1USWdNVEJvTFRKMk1rZzVkaTB5U0RkV09XZ3lWamRvTVhZeWFESjJNWG9pTHo0OEwzTjJaejQ9XCIiLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi96b29tV2FybmluZy5tb2R1bGUuc2Nzcyc7XG5cbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB6b29tSWNvbiBmcm9tICcvbm9kZV9tb2R1bGVzL3Vzd2RzL2Rpc3QvaW1nL3VzYS1pY29ucy96b29tX2luLnN2Zyc7XG5cbmludGVyZmFjZSBJWm9vbVdhcm5pbmdQcm9wcyB7XG4gICAgem9vbUxldmVsOiBudW1iZXJcbn1cblxuY29uc3QgWm9vbVdhcm5pbmcgPSAoe3pvb21MZXZlbH06IElab29tV2FybmluZ1Byb3BzKSA9PiB7XG4gIHJldHVybiAoXG4gICAgPD5cbiAgICAgIHt6b29tTGV2ZWwgPD0gNSA/IChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9e3N0eWxlcy56b29tV2FybmluZ30+XG4gICAgICAgICAgPGltZyBzcmM9e3pvb21JY29ufSBhbHQ9eyd6b29tIGljb24nfS8+XG4gICAgICAgICAgWm9vbSBpbiB0byB0aGUgc3RhdGUgb3IgcmVnaW9uYWwgbGV2ZWwgdG8gc2VlIHByaW9yaXRpemVkIGNvbW11bml0aWVzIG9uIHRoZSBtYXAuXG4gICAgICAgIDwvZGl2PlxuICAgICAgICApIDpcbiAgICAgICAgJydcbiAgICAgIH1cbiAgICA8Lz5cbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFpvb21XYXJuaW5nO1xuIiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIHBvcHVwQ29udGVudFRhYmxlID0gXCJwb3B1cENvbnRlbnQtbW9kdWxlLS1wb3B1cENvbnRlbnRUYWJsZS0tMXk0YzlcIjtcbmV4cG9ydCB2YXIgdGl0bGVDb250YWluZXIgPSBcInBvcHVwQ29udGVudC1tb2R1bGUtLXRpdGxlQ29udGFpbmVyLS0xN095OVwiO1xuZXhwb3J0IHZhciB0aXRsZUluZGljYXRvck5hbWUgPSBcInBvcHVwQ29udGVudC1tb2R1bGUtLXRpdGxlSW5kaWNhdG9yTmFtZS0tM3lvRGhcIjsiLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgKiBhcyBjb25zdGFudHMgZnJvbSAnLi4vZGF0YS9jb25zdGFudHMnO1xuaW1wb3J0ICogYXMgc3R5bGVzIGZyb20gJy4vcG9wdXBDb250ZW50Lm1vZHVsZS5zY3NzJztcblxuaW50ZXJmYWNlIElQb3B1cENvbnRlbnRQcm9wcyB7XG4gIHByb3BlcnRpZXM6IGNvbnN0YW50cy5KNDBQcm9wZXJ0aWVzLFxufVxuXG5cbmNvbnN0IFBvcHVwQ29udGVudCA9ICh7cHJvcGVydGllc306SVBvcHVwQ29udGVudFByb3BzKSA9PiB7XG4gIGNvbnN0IHJlYWRhYmxlUGVyY2VudCA9IChwZXJjZW50OiBudW1iZXIpID0+IHtcbiAgICByZXR1cm4gYCR7KHBlcmNlbnQgKiAxMDApLnRvRml4ZWQoMil9YDtcbiAgfTtcblxuICBjb25zdCBnZXRDYXRlZ29yaXphdGlvbiA9IChwZXJjZW50aWxlOiBudW1iZXIpID0+IHtcbiAgICBsZXQgY2F0ZWdvcml6YXRpb247XG4gICAgaWYgKHBlcmNlbnRpbGUgPj0gMC43NSApIHtcbiAgICAgIGNhdGVnb3JpemF0aW9uID0gJ1ByaW9yaXRpemVkJztcbiAgICB9IGVsc2UgaWYgKDAuNjAgPD0gcGVyY2VudGlsZSAmJiBwZXJjZW50aWxlIDwgMC43NSkge1xuICAgICAgY2F0ZWdvcml6YXRpb24gPSAnVGhyZXNob2xkJztcbiAgICB9IGVsc2Uge1xuICAgICAgY2F0ZWdvcml6YXRpb24gPSAnTm9uLXByaW9yaXRpemVkJztcbiAgICB9XG4gICAgcmV0dXJuIGNhdGVnb3JpemF0aW9uO1xuICB9O1xuXG4gIGNvbnN0IGdldFRpdGxlQ29udGVudCA9IChwcm9wZXJ0aWVzOiBjb25zdGFudHMuSjQwUHJvcGVydGllcykgPT4ge1xuICAgIGNvbnN0IGJsb2NrR3JvdXAgPSBwcm9wZXJ0aWVzW2NvbnN0YW50cy5HRU9JRF9QUk9QRVJUWV07XG4gICAgY29uc3Qgc2NvcmUgPSBwcm9wZXJ0aWVzW2NvbnN0YW50cy5TQ09SRV9QUk9QRVJUWV0gYXMgbnVtYmVyO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLnRpdGxlQ29udGFpbmVyfT5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9e3N0eWxlcy50aXRsZUluZGljYXRvck5hbWV9PkNlbnN1cyBCbG9jayBHcm91cDogPC9zcGFuPlxuICAgICAgICAgIDxzcGFuPntibG9ja0dyb3VwfTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPXtzdHlsZXMudGl0bGVJbmRpY2F0b3JOYW1lfT5KdXN0IFByb2dyZXNzIENhdGVnb3JpemF0aW9uOiA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4+e2dldENhdGVnb3JpemF0aW9uKHNjb3JlKX08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT17c3R5bGVzLnRpdGxlSW5kaWNhdG9yTmFtZX0+Q3VtdWxhdGl2ZSBJbmRleCBTY29yZTogPC9zcGFuPlxuICAgICAgICAgIDxzcGFuPntyZWFkYWJsZVBlcmNlbnQoc2NvcmUpfTwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGdldEJvZHlDb250ZW50ID0gKHByb3BlcnRpZXM6IGNvbnN0YW50cy5KNDBQcm9wZXJ0aWVzKSA9PiB7XG4gICAgY29uc3Qgcm93cyA9IFtdO1xuICAgIGNvbnN0IHNvcnRlZEtleXMgPSBPYmplY3QuZW50cmllcyhwcm9wZXJ0aWVzKS5zb3J0KCk7XG4gICAgZm9yIChsZXQgW2tleSwgdmFsdWVdIG9mIHNvcnRlZEtleXMpIHtcbiAgICAgIC8vIFdlIHNob3VsZCBvbmx5IGZvcm1hdCBmbG9hdHNcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmIHZhbHVlICUgMSAhPT0gMCkge1xuICAgICAgICB2YWx1ZSA9IHJlYWRhYmxlUGVyY2VudCh2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZpbHRlciBvdXQgYWxsIGNhcHNcbiAgICAgIGlmICgha2V5Lm1hdGNoKC9eW0EtWjAtOV0rJC8pKSB7XG4gICAgICAgIHJvd3MucHVzaCg8dHIga2V5PXtrZXl9ID5cbiAgICAgICAgICA8dGQ+e2tleX08L3RkPlxuICAgICAgICAgIDx0ZD57dmFsdWV9PC90ZD5cbiAgICAgICAgPC90cj4pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcm93cztcbiAgfTtcblxuXG4gIHJldHVybiAoXG4gICAgPD5cbiAgICAgIHtwcm9wZXJ0aWVzID9cbiAgICAgIDxkaXYgaWQ9J3BvcHVwQ29udGFpbmVyJz5cbiAgICAgICAge2dldFRpdGxlQ29udGVudChwcm9wZXJ0aWVzKX1cbiAgICAgICAgPHRhYmxlIGNsYXNzTmFtZT17J3VzYS10YWJsZSB1c2EtdGFibGUtLWJvcmRlcmxlc3MgJyArIHN0eWxlcy5wb3B1cENvbnRlbnRUYWJsZX0+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5JTkRJQ0FUT1I8L3RoPlxuICAgICAgICAgICAgICA8dGggc2NvcGU9XCJjb2xcIj5WQUxVRTwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAge2dldEJvZHlDb250ZW50KHByb3BlcnRpZXMpfVxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj4gOlxuICAgICcnIH1cbiAgICA8Lz5cbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFBvcHVwQ29udGVudDtcbiIsIi8vIGV4dHJhY3RlZCBieSBtaW5pLWNzcy1leHRyYWN0LXBsdWdpblxuZXhwb3J0IHZhciBtYXBDb250YWluZXIgPSBcIm1hcGJveE1hcC1tb2R1bGUtLW1hcENvbnRhaW5lci0tM3JHRDZcIjtcbmV4cG9ydCB2YXIgajQwUG9wdXAgPSBcIm1hcGJveE1hcC1tb2R1bGUtLWo0MFBvcHVwLS1tdDZsQlwiOyIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5pbXBvcnQgUmVhY3QsIHt1c2VSZWYsIHVzZUVmZmVjdCwgdXNlU3RhdGV9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7TG5nTGF0Qm91bmRzTGlrZSxcbiAgTWFwLFxuICBOYXZpZ2F0aW9uQ29udHJvbCxcbiAgUG9wdXBPcHRpb25zLFxuICBQb3B1cCxcbiAgTG5nTGF0TGlrZX0gZnJvbSAnbWFwYm94LWdsJztcbmltcG9ydCBtYXBTdHlsZSBmcm9tICcuLi9kYXRhL21hcFN0eWxlJztcbmltcG9ydCBab29tV2FybmluZyBmcm9tICcuL3pvb21XYXJuaW5nJztcbmltcG9ydCBQb3B1cENvbnRlbnQgZnJvbSAnLi9wb3B1cENvbnRlbnQnO1xuaW1wb3J0ICogYXMgY29uc3RhbnRzIGZyb20gJy4uL2RhdGEvY29uc3RhbnRzJztcbmltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0ICdtYXBib3gtZ2wvZGlzdC9tYXBib3gtZ2wuY3NzJztcbmltcG9ydCAqIGFzIHN0eWxlcyBmcm9tICcuL21hcGJveE1hcC5tb2R1bGUuc2Nzcyc7XG5cbnR5cGUgQ2xpY2tFdmVudCA9IG1hcGJveGdsLk1hcE1vdXNlRXZlbnQgJiBtYXBib3hnbC5FdmVudERhdGE7XG5cbmNvbnN0IE1hcGJveE1hcCA9ICgpID0+IHtcbiAgY29uc3QgbWFwQ29udGFpbmVyID0gUmVhY3QudXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgbWFwID0gdXNlUmVmPE1hcD4oKSBhcyBSZWFjdC5NdXRhYmxlUmVmT2JqZWN0PE1hcD47XG4gIGNvbnN0IFt6b29tLCBzZXRab29tXSA9IHVzZVN0YXRlKGNvbnN0YW50cy5HTE9CQUxfTUlOX1pPT00pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gT25seSBpbml0aWFsaXplIG9uY2VcbiAgICBpZiAobWFwLmN1cnJlbnQgJiYgbWFwQ29udGFpbmVyLmN1cnJlbnQpIHJldHVybjtcblxuICAgIGNvbnN0IGluaXRpYWxNYXAgPSBuZXcgTWFwKHtcbiAgICAgIGNvbnRhaW5lcjogbWFwQ29udGFpbmVyLmN1cnJlbnQhLFxuICAgICAgc3R5bGU6IG1hcFN0eWxlLFxuICAgICAgY2VudGVyOiBjb25zdGFudHMuREVGQVVMVF9DRU5URVIgYXMgTG5nTGF0TGlrZSxcbiAgICAgIHpvb206IHpvb20sXG4gICAgICBtaW5ab29tOiBjb25zdGFudHMuR0xPQkFMX01JTl9aT09NLFxuICAgICAgbWF4Wm9vbTogY29uc3RhbnRzLkdMT0JBTF9NQVhfWk9PTSxcbiAgICAgIG1heEJvdW5kczogY29uc3RhbnRzLkdMT0JBTF9NQVhfQk9VTkRTIGFzIExuZ0xhdEJvdW5kc0xpa2UsXG4gICAgfSk7XG4gICAgLy8gZGlzYWJsZSBtYXAgcm90YXRpb24gdXNpbmcgcmlnaHQgY2xpY2sgKyBkcmFnXG4gICAgaW5pdGlhbE1hcC5kcmFnUm90YXRlLmRpc2FibGUoKTtcblxuICAgIC8vIGRpc2FibGUgbWFwIHJvdGF0aW9uIHVzaW5nIHRvdWNoIHJvdGF0aW9uIGdlc3R1cmVcbiAgICBpbml0aWFsTWFwLnRvdWNoWm9vbVJvdGF0ZS5kaXNhYmxlUm90YXRpb24oKTtcblxuICAgIGluaXRpYWxNYXAub24oJ2NsaWNrJywgaGFuZGxlQ2xpY2spO1xuICAgIGluaXRpYWxNYXAuYWRkQ29udHJvbChuZXcgTmF2aWdhdGlvbkNvbnRyb2woe3Nob3dDb21wYXNzOiBmYWxzZX0pLCAndG9wLWxlZnQnKTtcbiAgICBtYXAuY3VycmVudCA9IGluaXRpYWxNYXA7XG4gIH0pO1xuXG4gIGNvbnN0IGhhbmRsZUNsaWNrID0gKGU6IENsaWNrRXZlbnQpID0+IHtcbiAgICBjb25zdCBtYXAgPSBlLnRhcmdldDtcbiAgICBjb25zdCBjbGlja2VkQ29vcmQgPSBlLnBvaW50O1xuICAgIGNvbnN0IGZlYXR1cmVzID0gbWFwLnF1ZXJ5UmVuZGVyZWRGZWF0dXJlcyhjbGlja2VkQ29vcmQsIHtcbiAgICAgIGxheWVyczogWydzY29yZSddLFxuICAgIH0pO1xuXG4gICAgaWYgKGZlYXR1cmVzLmxlbmd0aCAmJiBmZWF0dXJlc1swXS5wcm9wZXJ0aWVzKSB7XG4gICAgICBjb25zdCBwbGFjZWhvbGRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgUmVhY3RET00ucmVuZGVyKDxQb3B1cENvbnRlbnQgcHJvcGVydGllcz17ZmVhdHVyZXNbMF0ucHJvcGVydGllc30gLz4sIHBsYWNlaG9sZGVyKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgOiBQb3B1cE9wdGlvbnMgPSB7XG4gICAgICAgIG9mZnNldDogWzAsIDBdLFxuICAgICAgICBjbGFzc05hbWU6IHN0eWxlcy5qNDBQb3B1cCxcbiAgICAgICAgZm9jdXNBZnRlck9wZW46IGZhbHNlLFxuICAgICAgfTtcbiAgICAgIG5ldyBQb3B1cChvcHRpb25zKVxuICAgICAgICAgIC5zZXRMbmdMYXQoZS5sbmdMYXQpXG4gICAgICAgICAgLnNldERPTUNvbnRlbnQocGxhY2Vob2xkZXIpXG4gICAgICAgICAgLmFkZFRvKG1hcCk7XG4gICAgfVxuICB9O1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFtYXAuY3VycmVudCkgcmV0dXJuOyAvLyB3YWl0IGZvciBtYXAgdG8gaW5pdGlhbGl6ZVxuICAgIG1hcC5jdXJyZW50Lm9uKCdtb3ZlJywgKCkgPT4ge1xuICAgICAgc2V0Wm9vbShtYXAuY3VycmVudC5nZXRab29tKCkpO1xuICAgIH0pO1xuICAgIG1hcC5jdXJyZW50Lm9uKCdtb3VzZWVudGVyJywgJ3Njb3JlJywgKCkgPT4ge1xuICAgICAgbWFwLmN1cnJlbnQuZ2V0Q2FudmFzKCkuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgIH0pO1xuICAgIG1hcC5jdXJyZW50Lm9uKCdtb3VzZWxlYXZlJywgJ3Njb3JlJywgKCkgPT4ge1xuICAgICAgbWFwLmN1cnJlbnQuZ2V0Q2FudmFzKCkuc3R5bGUuY3Vyc29yID0gJyc7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdj5cbiAgICAgIDxkaXYgcmVmPXttYXBDb250YWluZXJ9IGNsYXNzTmFtZT17c3R5bGVzLm1hcENvbnRhaW5lcn0vPlxuICAgICAgPFpvb21XYXJuaW5nIHpvb21MZXZlbD17em9vbX0gLz5cbiAgICA8L2Rpdj5cbiAgKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IE1hcGJveE1hcDtcbiIsIi8qKlxuICogQG1vZHVsZSBvbC9EaXNwb3NhYmxlXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBPYmplY3RzIHRoYXQgbmVlZCB0byBjbGVhbiB1cCBhZnRlciB0aGVtc2VsdmVzLlxuICovXG52YXIgRGlzcG9zYWJsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIERpc3Bvc2FibGUoKSB7XG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCBoYXMgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cbiAgICB0aGlzLmRpc3Bvc2VkID0gZmFsc2U7XG4gIH1cbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIERpc3Bvc2FibGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgIHRoaXMuZGlzcG9zZUludGVybmFsKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogRXh0ZW5zaW9uIHBvaW50IGZvciBkaXNwb3NhYmxlIG9iamVjdHMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBEaXNwb3NhYmxlLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7fTtcblxuICByZXR1cm4gRGlzcG9zYWJsZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgRGlzcG9zYWJsZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvYXJyYXlcbiAqL1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgYmluYXJ5IHNlYXJjaCBvbiB0aGUgcHJvdmlkZWQgc29ydGVkIGxpc3QgYW5kIHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBpdGVtIGlmIGZvdW5kLiBJZiBpdCBjYW4ndCBiZSBmb3VuZCBpdCdsbCByZXR1cm4gLTEuXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZGFya3NreWFwcC9iaW5hcnktc2VhcmNoXG4gKlxuICogQHBhcmFtIHtBcnJheTwqPn0gaGF5c3RhY2sgSXRlbXMgdG8gc2VhcmNoIHRocm91Z2guXG4gKiBAcGFyYW0geyp9IG5lZWRsZSBUaGUgaXRlbSB0byBsb29rIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb249fSBvcHRfY29tcGFyYXRvciBDb21wYXJhdG9yIGZ1bmN0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgaW5kZXggb2YgdGhlIGl0ZW0gaWYgZm91bmQsIC0xIGlmIG5vdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJpbmFyeVNlYXJjaChoYXlzdGFjaywgbmVlZGxlLCBvcHRfY29tcGFyYXRvcikge1xuICB2YXIgbWlkLCBjbXA7XG4gIHZhciBjb21wYXJhdG9yID0gb3B0X2NvbXBhcmF0b3IgfHwgbnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbjtcbiAgdmFyIGxvdyA9IDA7XG4gIHZhciBoaWdoID0gaGF5c3RhY2subGVuZ3RoO1xuICB2YXIgZm91bmQgPSBmYWxzZTtcblxuICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgIC8qIE5vdGUgdGhhdCBcIihsb3cgKyBoaWdoKSA+Pj4gMVwiIG1heSBvdmVyZmxvdywgYW5kIHJlc3VsdHMgaW4gYSB0eXBlY2FzdFxuICAgICAqIHRvIGRvdWJsZSAod2hpY2ggZ2l2ZXMgdGhlIHdyb25nIHJlc3VsdHMpLiAqL1xuICAgIG1pZCA9IGxvdyArIChoaWdoIC0gbG93ID4+IDEpO1xuICAgIGNtcCA9ICtjb21wYXJhdG9yKGhheXN0YWNrW21pZF0sIG5lZWRsZSk7XG5cbiAgICBpZiAoY21wIDwgMC4wKSB7XG4gICAgICAvKiBUb28gbG93LiAqL1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgLyogS2V5IGZvdW5kIG9yIHRvbyBoaWdoICovXG4gICAgICBoaWdoID0gbWlkO1xuICAgICAgZm91bmQgPSAhY21wO1xuICAgIH1cbiAgfVxuICAvKiBLZXkgbm90IGZvdW5kLiAqL1xuXG5cbiAgcmV0dXJuIGZvdW5kID8gbG93IDogfmxvdztcbn1cbi8qKlxuICogQ29tcGFyZSBmdW5jdGlvbiBmb3IgYXJyYXkgc29ydCB0aGF0IGlzIHNhZmUgZm9yIG51bWJlcnMuXG4gKiBAcGFyYW0geyp9IGEgVGhlIGZpcnN0IG9iamVjdCB0byBiZSBjb21wYXJlZC5cbiAqIEBwYXJhbSB7Kn0gYiBUaGUgc2Vjb25kIG9iamVjdCB0byBiZSBjb21wYXJlZC5cbiAqIEByZXR1cm4ge251bWJlcn0gQSBuZWdhdGl2ZSBudW1iZXIsIHplcm8sIG9yIGEgcG9zaXRpdmUgbnVtYmVyIGFzIHRoZSBmaXJzdFxuICogICAgIGFyZ3VtZW50IGlzIGxlc3MgdGhhbiwgZXF1YWwgdG8sIG9yIGdyZWF0ZXIgdGhhbiB0aGUgc2Vjb25kLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgPiBiID8gMSA6IGEgPCBiID8gLTEgOiAwO1xufVxuLyoqXG4gKiBXaGV0aGVyIHRoZSBhcnJheSBjb250YWlucyB0aGUgZ2l2ZW4gb2JqZWN0LlxuICogQHBhcmFtIHtBcnJheTwqPn0gYXJyIFRoZSBhcnJheSB0byB0ZXN0IGZvciB0aGUgcHJlc2VuY2Ugb2YgdGhlIGVsZW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iaiBUaGUgb2JqZWN0IGZvciB3aGljaCB0byB0ZXN0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIG9iamVjdCBpcyBpbiB0aGUgYXJyYXkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGluY2x1ZGVzKGFyciwgb2JqKSB7XG4gIHJldHVybiBhcnIuaW5kZXhPZihvYmopID49IDA7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gYXJyIEFycmF5LlxuICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldCBUYXJnZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZGlyZWN0aW9uIDAgbWVhbnMgcmV0dXJuIHRoZSBuZWFyZXN0LCA+IDBcbiAqICAgIG1lYW5zIHJldHVybiB0aGUgbGFyZ2VzdCBuZWFyZXN0LCA8IDAgbWVhbnMgcmV0dXJuIHRoZVxuICogICAgc21hbGxlc3QgbmVhcmVzdC5cbiAqIEByZXR1cm4ge251bWJlcn0gSW5kZXguXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhckZpbmROZWFyZXN0KGFyciwgdGFyZ2V0LCBkaXJlY3Rpb24pIHtcbiAgdmFyIG4gPSBhcnIubGVuZ3RoO1xuXG4gIGlmIChhcnJbMF0gPD0gdGFyZ2V0KSB7XG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSBpZiAodGFyZ2V0IDw9IGFycltuIC0gMV0pIHtcbiAgICByZXR1cm4gbiAtIDE7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGkgPSB2b2lkIDA7XG5cbiAgICBpZiAoZGlyZWN0aW9uID4gMCkge1xuICAgICAgZm9yIChpID0gMTsgaSA8IG47ICsraSkge1xuICAgICAgICBpZiAoYXJyW2ldIDwgdGFyZ2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGkgLSAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPCAwKSB7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmIChhcnJbaV0gPD0gdGFyZ2V0KSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMTsgaSA8IG47ICsraSkge1xuICAgICAgICBpZiAoYXJyW2ldID09IHRhcmdldCkge1xuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9IGVsc2UgaWYgKGFycltpXSA8IHRhcmdldCkge1xuICAgICAgICAgIGlmIChhcnJbaSAtIDFdIC0gdGFyZ2V0IDwgdGFyZ2V0IC0gYXJyW2ldKSB7XG4gICAgICAgICAgICByZXR1cm4gaSAtIDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBuIC0gMTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBhcnIgQXJyYXkuXG4gKiBAcGFyYW0ge251bWJlcn0gYmVnaW4gQmVnaW4gaW5kZXguXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZCBpbmRleC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmV2ZXJzZVN1YkFycmF5KGFyciwgYmVnaW4sIGVuZCkge1xuICB3aGlsZSAoYmVnaW4gPCBlbmQpIHtcbiAgICB2YXIgdG1wID0gYXJyW2JlZ2luXTtcbiAgICBhcnJbYmVnaW5dID0gYXJyW2VuZF07XG4gICAgYXJyW2VuZF0gPSB0bXA7XG4gICAgKytiZWdpbjtcbiAgICAtLWVuZDtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PFZBTFVFPn0gYXJyIFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0geyFBcnJheTxWQUxVRT58VkFMVUV9IGRhdGEgVGhlIGVsZW1lbnRzIG9yIGFycmF5cyBvZiBlbGVtZW50cyB0byBhZGQgdG8gYXJyLlxuICogQHRlbXBsYXRlIFZBTFVFXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZChhcnIsIGRhdGEpIHtcbiAgdmFyIGV4dGVuc2lvbiA9IEFycmF5LmlzQXJyYXkoZGF0YSkgPyBkYXRhIDogW2RhdGFdO1xuICB2YXIgbGVuZ3RoID0gZXh0ZW5zaW9uLmxlbmd0aDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgYXJyW2Fyci5sZW5ndGhdID0gZXh0ZW5zaW9uW2ldO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8VkFMVUU+fSBhcnIgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7VkFMVUV9IG9iaiBUaGUgZWxlbWVudCB0byByZW1vdmUuXG4gKiBAdGVtcGxhdGUgVkFMVUVcbiAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBlbGVtZW50IHdhcyByZW1vdmVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmUoYXJyLCBvYmopIHtcbiAgdmFyIGkgPSBhcnIuaW5kZXhPZihvYmopO1xuICB2YXIgZm91bmQgPSBpID4gLTE7XG5cbiAgaWYgKGZvdW5kKSB7XG4gICAgYXJyLnNwbGljZShpLCAxKTtcbiAgfVxuXG4gIHJldHVybiBmb3VuZDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxWQUxVRT59IGFyciBUaGUgYXJyYXkgdG8gc2VhcmNoIGluLlxuICogQHBhcmFtIHtmdW5jdGlvbihWQUxVRSwgbnVtYmVyLCA/KSA6IGJvb2xlYW59IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNvbXBhcmUuXG4gKiBAdGVtcGxhdGUgVkFMVUVcbiAqIEByZXR1cm4ge1ZBTFVFfG51bGx9IFRoZSBlbGVtZW50IGZvdW5kIG9yIG51bGwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmQoYXJyLCBmdW5jKSB7XG4gIHZhciBsZW5ndGggPSBhcnIubGVuZ3RoID4+PiAwO1xuICB2YXIgdmFsdWU7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHZhbHVlID0gYXJyW2ldO1xuXG4gICAgaWYgKGZ1bmModmFsdWUsIGksIGFycikpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheXxVaW50OENsYW1wZWRBcnJheX0gYXJyMSBUaGUgZmlyc3QgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl8VWludDhDbGFtcGVkQXJyYXl9IGFycjIgVGhlIHNlY29uZCBhcnJheSB0byBjb21wYXJlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgdHdvIGFycmF5cyBhcmUgZXF1YWwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhhcnIxLCBhcnIyKSB7XG4gIHZhciBsZW4xID0gYXJyMS5sZW5ndGg7XG5cbiAgaWYgKGxlbjEgIT09IGFycjIubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW4xOyBpKyspIHtcbiAgICBpZiAoYXJyMVtpXSAhPT0gYXJyMltpXSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBTb3J0IHRoZSBwYXNzZWQgYXJyYXkgc3VjaCB0aGF0IHRoZSByZWxhdGl2ZSBvcmRlciBvZiBlcXVhbCBlbGVtZW50cyBpcyBwcmV2ZXJ2ZWQuXG4gKiBTZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU29ydGluZ19hbGdvcml0aG0jU3RhYmlsaXR5IGZvciBkZXRhaWxzLlxuICogQHBhcmFtIHtBcnJheTwqPn0gYXJyIFRoZSBhcnJheSB0byBzb3J0IChtb2RpZmllcyBvcmlnaW5hbCkuXG4gKiBAcGFyYW0geyFmdW5jdGlvbigqLCAqKTogbnVtYmVyfSBjb21wYXJlRm5jIENvbXBhcmlzb24gZnVuY3Rpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YWJsZVNvcnQoYXJyLCBjb21wYXJlRm5jKSB7XG4gIHZhciBsZW5ndGggPSBhcnIubGVuZ3RoO1xuICB2YXIgdG1wID0gQXJyYXkoYXJyLmxlbmd0aCk7XG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHRtcFtpXSA9IHtcbiAgICAgIGluZGV4OiBpLFxuICAgICAgdmFsdWU6IGFycltpXVxuICAgIH07XG4gIH1cblxuICB0bXAuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBjb21wYXJlRm5jKGEudmFsdWUsIGIudmFsdWUpIHx8IGEuaW5kZXggLSBiLmluZGV4O1xuICB9KTtcblxuICBmb3IgKGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgYXJyW2ldID0gdG1wW2ldLnZhbHVlO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8Kj59IGFyciBUaGUgYXJyYXkgdG8gc2VhcmNoIGluLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBDb21wYXJpc29uIGZ1bmN0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBSZXR1cm4gaW5kZXguXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRJbmRleChhcnIsIGZ1bmMpIHtcbiAgdmFyIGluZGV4O1xuICB2YXIgZm91bmQgPSAhYXJyLmV2ZXJ5KGZ1bmN0aW9uIChlbCwgaWR4KSB7XG4gICAgaW5kZXggPSBpZHg7XG4gICAgcmV0dXJuICFmdW5jKGVsLCBpZHgsIGFycik7XG4gIH0pO1xuICByZXR1cm4gZm91bmQgPyBpbmRleCA6IC0xO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PCo+fSBhcnIgVGhlIGFycmF5IHRvIHRlc3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9uPX0gb3B0X2Z1bmMgQ29tcGFyaXNvbiBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zdHJpY3QgU3RyaWN0bHkgc29ydGVkIChkZWZhdWx0IGZhbHNlKS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFJldHVybiBpbmRleC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNTb3J0ZWQoYXJyLCBvcHRfZnVuYywgb3B0X3N0cmljdCkge1xuICB2YXIgY29tcGFyZSA9IG9wdF9mdW5jIHx8IG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb247XG4gIHJldHVybiBhcnIuZXZlcnkoZnVuY3Rpb24gKGN1cnJlbnRWYWwsIGluZGV4KSB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgcmVzID0gY29tcGFyZShhcnJbaW5kZXggLSAxXSwgY3VycmVudFZhbCk7XG4gICAgcmV0dXJuICEocmVzID4gMCB8fCBvcHRfc3RyaWN0ICYmIHJlcyA9PT0gMCk7XG4gIH0pO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9mdW5jdGlvbnNcbiAqL1xuaW1wb3J0IHsgZXF1YWxzIGFzIGFycmF5RXF1YWxzIH0gZnJvbSAnLi9hcnJheS5qcyc7XG4vKipcbiAqIEFsd2F5cyByZXR1cm5zIHRydWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gVFJVRSgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEFsd2F5cyByZXR1cm5zIGZhbHNlLlxuICogQHJldHVybnMge2Jvb2xlYW59IGZhbHNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBGQUxTRSgpIHtcbiAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBBIHJldXNhYmxlIGZ1bmN0aW9uLCB1c2VkIGUuZy4gYXMgYSBkZWZhdWx0IGZvciBjYWxsYmFja3MuXG4gKlxuICogQHJldHVybiB7dm9pZH0gTm90aGluZy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gVk9JRCgpIHt9XG4vKipcbiAqIFdyYXAgYSBmdW5jdGlvbiBpbiBhbm90aGVyIGZ1bmN0aW9uIHRoYXQgcmVtZW1iZXJzIHRoZSBsYXN0IHJldHVybi4gIElmIHRoZVxuICogcmV0dXJuZWQgZnVuY3Rpb24gaXMgY2FsbGVkIHR3aWNlIGluIGEgcm93IHdpdGggdGhlIHNhbWUgYXJndW1lbnRzIGFuZCB0aGUgc2FtZVxuICogdGhpcyBvYmplY3QsIGl0IHdpbGwgcmV0dXJuIHRoZSB2YWx1ZSBmcm9tIHRoZSBmaXJzdCBjYWxsIGluIHRoZSBzZWNvbmQgY2FsbC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKC4uLmFueSk6IFJldHVyblR5cGV9IGZuIFRoZSBmdW5jdGlvbiB0byBtZW1vaXplLlxuICogQHJldHVybiB7ZnVuY3Rpb24oLi4uYW55KTogUmV0dXJuVHlwZX0gVGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICogQHRlbXBsYXRlIFJldHVyblR5cGVcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWVtb2l6ZU9uZShmbikge1xuICB2YXIgY2FsbGVkID0gZmFsc2U7XG4gIC8qKiBAdHlwZSB7UmV0dXJuVHlwZX0gKi9cblxuICB2YXIgbGFzdFJlc3VsdDtcbiAgLyoqIEB0eXBlIHtBcnJheTxhbnk+fSAqL1xuXG4gIHZhciBsYXN0QXJncztcbiAgdmFyIGxhc3RUaGlzO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBuZXh0QXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICBpZiAoIWNhbGxlZCB8fCB0aGlzICE9PSBsYXN0VGhpcyB8fCAhYXJyYXlFcXVhbHMobmV4dEFyZ3MsIGxhc3RBcmdzKSkge1xuICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgIGxhc3RUaGlzID0gdGhpcztcbiAgICAgIGxhc3RBcmdzID0gbmV4dEFyZ3M7XG4gICAgICBsYXN0UmVzdWx0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGFzdFJlc3VsdDtcbiAgfTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvdXRpbFxuICovXG5cbi8qKlxuICogQHJldHVybiB7P30gQW55IHJldHVybi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFic3RyYWN0KCkge1xuICByZXR1cm4gKFxuICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICBmdW5jdGlvbiAoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuaW1wbGVtZW50ZWQgYWJzdHJhY3QgbWV0aG9kLicpO1xuICAgIH0oKVxuICApO1xufVxuLyoqXG4gKiBDb3VudGVyIGZvciBnZXRVaWQuXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQHByaXZhdGVcbiAqL1xuXG52YXIgdWlkQ291bnRlcl8gPSAwO1xuLyoqXG4gKiBHZXRzIGEgdW5pcXVlIElEIGZvciBhbiBvYmplY3QuIFRoaXMgbXV0YXRlcyB0aGUgb2JqZWN0IHNvIHRoYXQgZnVydGhlciBjYWxsc1xuICogd2l0aCB0aGUgc2FtZSBvYmplY3QgYXMgYSBwYXJhbWV0ZXIgcmV0dXJucyB0aGUgc2FtZSB2YWx1ZS4gVW5pcXVlIElEcyBhcmUgZ2VuZXJhdGVkXG4gKiBhcyBhIHN0cmljdGx5IGluY3JlYXNpbmcgc2VxdWVuY2UuIEFkYXB0ZWQgZnJvbSBnb29nLmdldFVpZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gZ2V0IHRoZSB1bmlxdWUgSUQgZm9yLlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgdW5pcXVlIElEIGZvciB0aGUgb2JqZWN0LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRVaWQob2JqKSB7XG4gIHJldHVybiBvYmoub2xfdWlkIHx8IChvYmoub2xfdWlkID0gU3RyaW5nKCsrdWlkQ291bnRlcl8pKTtcbn1cbi8qKlxuICogT3BlbkxheWVycyB2ZXJzaW9uLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIFZFUlNJT04gPSAnNi41LjAnOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvQXNzZXJ0aW9uRXJyb3JcbiAqL1xuXG5cbmltcG9ydCB7IFZFUlNJT04gfSBmcm9tICcuL3V0aWwuanMnO1xuLyoqXG4gKiBFcnJvciBvYmplY3QgdGhyb3duIHdoZW4gYW4gYXNzZXJ0aW9uIGZhaWxlZC4gVGhpcyBpcyBhbiBFQ01BLTI2MiBFcnJvcixcbiAqIGV4dGVuZGVkIHdpdGggYSBgY29kZWAgcHJvcGVydHkuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRXJyb3IuXG4gKi9cblxudmFyIEFzc2VydGlvbkVycm9yID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEFzc2VydGlvbkVycm9yLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvZGUgRXJyb3IgY29kZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihjb2RlKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBwYXRoID0gVkVSU0lPTiA9PT0gJ2xhdGVzdCcgPyBWRVJTSU9OIDogJ3YnICsgVkVSU0lPTi5zcGxpdCgnLScpWzBdO1xuICAgIHZhciBtZXNzYWdlID0gJ0Fzc2VydGlvbiBmYWlsZWQuIFNlZSBodHRwczovL29wZW5sYXllcnMub3JnL2VuLycgKyBwYXRoICsgJy9kb2MvZXJyb3JzLyMnICsgY29kZSArICcgZm9yIGRldGFpbHMuJztcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIG1lc3NhZ2UpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogRXJyb3IgY29kZS4gVGhlIG1lYW5pbmcgb2YgdGhlIGNvZGUgY2FuIGJlIGZvdW5kIG9uXG4gICAgICogaHR0cHM6Ly9vcGVubGF5ZXJzLm9yZy9lbi9sYXRlc3QvZG9jL2Vycm9ycy8gKHJlcGxhY2UgYGxhdGVzdGAgd2l0aFxuICAgICAqIHRoZSB2ZXJzaW9uIGZvdW5kIGluIHRoZSBPcGVuTGF5ZXJzIHNjcmlwdCdzIGhlYWRlciBjb21tZW50IGlmIGEgdmVyc2lvblxuICAgICAqIG90aGVyIHRoYW4gdGhlIGxhdGVzdCBpcyB1c2VkKS5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLmNvZGUgPSBjb2RlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJzsgLy8gUmUtYXNzaWduIG1lc3NhZ2UsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vUmljaC1IYXJyaXMvYnVibGUvaXNzdWVzLzQwXG5cbiAgICBfdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gQXNzZXJ0aW9uRXJyb3I7XG59KEVycm9yKTtcblxuZXhwb3J0IGRlZmF1bHQgQXNzZXJ0aW9uRXJyb3I7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Fzc2VydHNcbiAqL1xuaW1wb3J0IEFzc2VydGlvbkVycm9yIGZyb20gJy4vQXNzZXJ0aW9uRXJyb3IuanMnO1xuLyoqXG4gKiBAcGFyYW0geyp9IGFzc2VydGlvbiBBc3NlcnRpb24gd2UgZXhwZWN0ZWQgdG8gYmUgdHJ1dGh5LlxuICogQHBhcmFtIHtudW1iZXJ9IGVycm9yQ29kZSBFcnJvciBjb2RlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoYXNzZXJ0aW9uLCBlcnJvckNvZGUpIHtcbiAgaWYgKCFhc3NlcnRpb24pIHtcbiAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoZXJyb3JDb2RlKTtcbiAgfVxufSIsIi8qKlxuICogQG1vZHVsZSBvbC90cmFuc2Zvcm1cbiAqL1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi9hc3NlcnRzLmpzJztcbi8qKlxuICogQW4gYXJyYXkgcmVwcmVzZW50aW5nIGFuIGFmZmluZSAyZCB0cmFuc2Zvcm1hdGlvbiBmb3IgdXNlIHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvdHJhbnNmb3JtfSBmdW5jdGlvbnMuIFRoZSBhcnJheSBoYXMgNiBlbGVtZW50cy5cbiAqIEB0eXBlZGVmIHshQXJyYXk8bnVtYmVyPn0gVHJhbnNmb3JtXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBDb2xsZWN0aW9uIG9mIGFmZmluZSAyZCB0cmFuc2Zvcm1hdGlvbiBmdW5jdGlvbnMuIFRoZSBmdW5jdGlvbnMgd29yayBvbiBhblxuICogYXJyYXkgb2YgNiBlbGVtZW50cy4gVGhlIGVsZW1lbnQgb3JkZXIgaXMgY29tcGF0aWJsZSB3aXRoIHRoZSBbU1ZHTWF0cml4XG4gKiBpbnRlcmZhY2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9TVkdNYXRyaXgpIGFuZCBpc1xuICogYSBzdWJzZXQgKGVsZW1lbnRzIGEgdG8gZikgb2YgYSAzw5czIG1hdHJpeDpcbiAqIGBgYFxuICogWyBhIGMgZSBdXG4gKiBbIGIgZCBmIF1cbiAqIFsgMCAwIDEgXVxuICogYGBgXG4gKi9cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHR5cGUge1RyYW5zZm9ybX1cbiAqL1xuXG52YXIgdG1wXyA9IG5ldyBBcnJheSg2KTtcbi8qKlxuICogQ3JlYXRlIGFuIGlkZW50aXR5IHRyYW5zZm9ybS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IElkZW50aXR5IHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlKCkge1xuICByZXR1cm4gWzEsIDAsIDAsIDEsIDAsIDBdO1xufVxuLyoqXG4gKiBSZXNldHMgdGhlIGdpdmVuIHRyYW5zZm9ybSB0byBhbiBpZGVudGl0eSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUcmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0KHRyYW5zZm9ybSkge1xuICByZXR1cm4gc2V0KHRyYW5zZm9ybSwgMSwgMCwgMCwgMSwgMCwgMCk7XG59XG4vKipcbiAqIE11bHRpcGx5IHRoZSB1bmRlcmx5aW5nIG1hdHJpY2VzIG9mIHR3byB0cmFuc2Zvcm1zIGFuZCByZXR1cm4gdGhlIHJlc3VsdCBpblxuICogdGhlIGZpcnN0IHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtMSBUcmFuc2Zvcm0gcGFyYW1ldGVycyBvZiBtYXRyaXggMS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtMiBUcmFuc2Zvcm0gcGFyYW1ldGVycyBvZiBtYXRyaXggMi5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IHRyYW5zZm9ybTEgbXVsdGlwbGllZCB3aXRoIHRyYW5zZm9ybTIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpcGx5KHRyYW5zZm9ybTEsIHRyYW5zZm9ybTIpIHtcbiAgdmFyIGExID0gdHJhbnNmb3JtMVswXTtcbiAgdmFyIGIxID0gdHJhbnNmb3JtMVsxXTtcbiAgdmFyIGMxID0gdHJhbnNmb3JtMVsyXTtcbiAgdmFyIGQxID0gdHJhbnNmb3JtMVszXTtcbiAgdmFyIGUxID0gdHJhbnNmb3JtMVs0XTtcbiAgdmFyIGYxID0gdHJhbnNmb3JtMVs1XTtcbiAgdmFyIGEyID0gdHJhbnNmb3JtMlswXTtcbiAgdmFyIGIyID0gdHJhbnNmb3JtMlsxXTtcbiAgdmFyIGMyID0gdHJhbnNmb3JtMlsyXTtcbiAgdmFyIGQyID0gdHJhbnNmb3JtMlszXTtcbiAgdmFyIGUyID0gdHJhbnNmb3JtMls0XTtcbiAgdmFyIGYyID0gdHJhbnNmb3JtMls1XTtcbiAgdHJhbnNmb3JtMVswXSA9IGExICogYTIgKyBjMSAqIGIyO1xuICB0cmFuc2Zvcm0xWzFdID0gYjEgKiBhMiArIGQxICogYjI7XG4gIHRyYW5zZm9ybTFbMl0gPSBhMSAqIGMyICsgYzEgKiBkMjtcbiAgdHJhbnNmb3JtMVszXSA9IGIxICogYzIgKyBkMSAqIGQyO1xuICB0cmFuc2Zvcm0xWzRdID0gYTEgKiBlMiArIGMxICogZjIgKyBlMTtcbiAgdHJhbnNmb3JtMVs1XSA9IGIxICogZTIgKyBkMSAqIGYyICsgZjE7XG4gIHJldHVybiB0cmFuc2Zvcm0xO1xufVxuLyoqXG4gKiBTZXQgdGhlIHRyYW5zZm9ybSBjb21wb25lbnRzIGEtZiBvbiBhIGdpdmVuIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhIFRoZSBhIGNvbXBvbmVudCBvZiB0aGUgdHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGIgVGhlIGIgY29tcG9uZW50IG9mIHRoZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gYyBUaGUgYyBjb21wb25lbnQgb2YgdGhlIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkIFRoZSBkIGNvbXBvbmVudCBvZiB0aGUgdHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGUgVGhlIGUgY29tcG9uZW50IG9mIHRoZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0gZiBUaGUgZiBjb21wb25lbnQgb2YgdGhlIHRyYW5zZm9ybS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IE1hdHJpeCB3aXRoIHRyYW5zZm9ybSBhcHBsaWVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXQodHJhbnNmb3JtLCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHRyYW5zZm9ybVswXSA9IGE7XG4gIHRyYW5zZm9ybVsxXSA9IGI7XG4gIHRyYW5zZm9ybVsyXSA9IGM7XG4gIHRyYW5zZm9ybVszXSA9IGQ7XG4gIHRyYW5zZm9ybVs0XSA9IGU7XG4gIHRyYW5zZm9ybVs1XSA9IGY7XG4gIHJldHVybiB0cmFuc2Zvcm07XG59XG4vKipcbiAqIFNldCB0cmFuc2Zvcm0gb24gb25lIG1hdHJpeCBmcm9tIGFub3RoZXIgbWF0cml4LlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0xIE1hdHJpeCB0byBzZXQgdHJhbnNmb3JtIHRvLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0yIE1hdHJpeCB0byBzZXQgdHJhbnNmb3JtIGZyb20uXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0xIHdpdGggdHJhbnNmb3JtIGZyb20gdHJhbnNmb3JtMiBhcHBsaWVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRGcm9tQXJyYXkodHJhbnNmb3JtMSwgdHJhbnNmb3JtMikge1xuICB0cmFuc2Zvcm0xWzBdID0gdHJhbnNmb3JtMlswXTtcbiAgdHJhbnNmb3JtMVsxXSA9IHRyYW5zZm9ybTJbMV07XG4gIHRyYW5zZm9ybTFbMl0gPSB0cmFuc2Zvcm0yWzJdO1xuICB0cmFuc2Zvcm0xWzNdID0gdHJhbnNmb3JtMlszXTtcbiAgdHJhbnNmb3JtMVs0XSA9IHRyYW5zZm9ybTJbNF07XG4gIHRyYW5zZm9ybTFbNV0gPSB0cmFuc2Zvcm0yWzVdO1xuICByZXR1cm4gdHJhbnNmb3JtMTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyB0aGUgZ2l2ZW4gY29vcmRpbmF0ZSB3aXRoIHRoZSBnaXZlbiB0cmFuc2Zvcm0gcmV0dXJuaW5nIHRoZVxuICogcmVzdWx0aW5nLCB0cmFuc2Zvcm1lZCBjb29yZGluYXRlLiBUaGUgY29vcmRpbmF0ZSB3aWxsIGJlIG1vZGlmaWVkIGluLXBsYWNlLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNmb3JtfSB0cmFuc2Zvcm0gVGhlIHRyYW5zZm9ybWF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXxpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBjb29yZGluYXRlIFRoZSBjb29yZGluYXRlIHRvIHRyYW5zZm9ybS5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfGltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHJldHVybiBjb29yZGluYXRlIHNvIHRoYXQgb3BlcmF0aW9ucyBjYW4gYmVcbiAqICAgICBjaGFpbmVkIHRvZ2V0aGVyLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseSh0cmFuc2Zvcm0sIGNvb3JkaW5hdGUpIHtcbiAgdmFyIHggPSBjb29yZGluYXRlWzBdO1xuICB2YXIgeSA9IGNvb3JkaW5hdGVbMV07XG4gIGNvb3JkaW5hdGVbMF0gPSB0cmFuc2Zvcm1bMF0gKiB4ICsgdHJhbnNmb3JtWzJdICogeSArIHRyYW5zZm9ybVs0XTtcbiAgY29vcmRpbmF0ZVsxXSA9IHRyYW5zZm9ybVsxXSAqIHggKyB0cmFuc2Zvcm1bM10gKiB5ICsgdHJhbnNmb3JtWzVdO1xuICByZXR1cm4gY29vcmRpbmF0ZTtcbn1cbi8qKlxuICogQXBwbGllcyByb3RhdGlvbiB0byB0aGUgZ2l2ZW4gdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlIEFuZ2xlIGluIHJhZGlhbnMuXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUaGUgcm90YXRlZCB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZSh0cmFuc2Zvcm0sIGFuZ2xlKSB7XG4gIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gIHZhciBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG4gIHJldHVybiBtdWx0aXBseSh0cmFuc2Zvcm0sIHNldCh0bXBfLCBjb3MsIHNpbiwgLXNpbiwgY29zLCAwLCAwKSk7XG59XG4vKipcbiAqIEFwcGxpZXMgc2NhbGUgdG8gYSBnaXZlbiB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcGFyYW0ge251bWJlcn0geCBTY2FsZSBmYWN0b3IgeC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFNjYWxlIGZhY3RvciB5LlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gVGhlIHNjYWxlZCB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKHRyYW5zZm9ybSwgeCwgeSkge1xuICByZXR1cm4gbXVsdGlwbHkodHJhbnNmb3JtLCBzZXQodG1wXywgeCwgMCwgMCwgeSwgMCwgMCkpO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgc2NhbGUgdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0YXJnZXQgVHJhbnNmb3JtIHRvIG92ZXJ3cml0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFNjYWxlIGZhY3RvciB4LlxuICogQHBhcmFtIHtudW1iZXJ9IHkgU2NhbGUgZmFjdG9yIHkuXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUaGUgc2NhbGUgdHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlU2NhbGUodGFyZ2V0LCB4LCB5KSB7XG4gIHJldHVybiBzZXQodGFyZ2V0LCB4LCAwLCAwLCB5LCAwLCAwKTtcbn1cbi8qKlxuICogQXBwbGllcyB0cmFuc2xhdGlvbiB0byB0aGUgZ2l2ZW4gdHJhbnNmb3JtLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICogQHBhcmFtIHtudW1iZXJ9IGR4IFRyYW5zbGF0aW9uIHguXG4gKiBAcGFyYW0ge251bWJlcn0gZHkgVHJhbnNsYXRpb24geS5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRoZSB0cmFuc2xhdGVkIHRyYW5zZm9ybS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNsYXRlKHRyYW5zZm9ybSwgZHgsIGR5KSB7XG4gIHJldHVybiBtdWx0aXBseSh0cmFuc2Zvcm0sIHNldCh0bXBfLCAxLCAwLCAwLCAxLCBkeCwgZHkpKTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIGNvbXBvc2l0ZSB0cmFuc2Zvcm0gZ2l2ZW4gYW4gaW5pdGlhbCB0cmFuc2xhdGlvbiwgc2NhbGUsIHJvdGF0aW9uLCBhbmRcbiAqIGZpbmFsIHRyYW5zbGF0aW9uIChpbiB0aGF0IG9yZGVyIG9ubHksIG5vdCBjb21tdXRhdGl2ZSkuXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRyYW5zZm9ybSBUaGUgdHJhbnNmb3JtICh3aWxsIGJlIG1vZGlmaWVkIGluIHBsYWNlKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBkeDEgSW5pdGlhbCB0cmFuc2xhdGlvbiB4LlxuICogQHBhcmFtIHtudW1iZXJ9IGR5MSBJbml0aWFsIHRyYW5zbGF0aW9uIHkuXG4gKiBAcGFyYW0ge251bWJlcn0gc3ggU2NhbGUgZmFjdG9yIHguXG4gKiBAcGFyYW0ge251bWJlcn0gc3kgU2NhbGUgZmFjdG9yIHkuXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgUm90YXRpb24gKGluIGNvdW50ZXItY2xvY2t3aXNlIHJhZGlhbnMpLlxuICogQHBhcmFtIHtudW1iZXJ9IGR4MiBGaW5hbCB0cmFuc2xhdGlvbiB4LlxuICogQHBhcmFtIHtudW1iZXJ9IGR5MiBGaW5hbCB0cmFuc2xhdGlvbiB5LlxuICogQHJldHVybiB7IVRyYW5zZm9ybX0gVGhlIGNvbXBvc2l0ZSB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2UodHJhbnNmb3JtLCBkeDEsIGR5MSwgc3gsIHN5LCBhbmdsZSwgZHgyLCBkeTIpIHtcbiAgdmFyIHNpbiA9IE1hdGguc2luKGFuZ2xlKTtcbiAgdmFyIGNvcyA9IE1hdGguY29zKGFuZ2xlKTtcbiAgdHJhbnNmb3JtWzBdID0gc3ggKiBjb3M7XG4gIHRyYW5zZm9ybVsxXSA9IHN5ICogc2luO1xuICB0cmFuc2Zvcm1bMl0gPSAtc3ggKiBzaW47XG4gIHRyYW5zZm9ybVszXSA9IHN5ICogY29zO1xuICB0cmFuc2Zvcm1bNF0gPSBkeDIgKiBzeCAqIGNvcyAtIGR5MiAqIHN4ICogc2luICsgZHgxO1xuICB0cmFuc2Zvcm1bNV0gPSBkeDIgKiBzeSAqIHNpbiArIGR5MiAqIHN5ICogY29zICsgZHkxO1xuICByZXR1cm4gdHJhbnNmb3JtO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcG9zaXRlIHRyYW5zZm9ybSBnaXZlbiBhbiBpbml0aWFsIHRyYW5zbGF0aW9uLCBzY2FsZSwgcm90YXRpb24sIGFuZFxuICogZmluYWwgdHJhbnNsYXRpb24gKGluIHRoYXQgb3JkZXIgb25seSwgbm90IGNvbW11dGF0aXZlKS4gVGhlIHJlc3VsdGluZyB0cmFuc2Zvcm1cbiAqIHN0cmluZyBjYW4gYmUgYXBwbGllZCBhcyBgdHJhbnNmb3JtYCBwb3JwZXJ0eSBvZiBhbiBIVE1MRWxlbWVudCdzIHN0eWxlLlxuICogQHBhcmFtIHtudW1iZXJ9IGR4MSBJbml0aWFsIHRyYW5zbGF0aW9uIHguXG4gKiBAcGFyYW0ge251bWJlcn0gZHkxIEluaXRpYWwgdHJhbnNsYXRpb24geS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeCBTY2FsZSBmYWN0b3IgeC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeSBTY2FsZSBmYWN0b3IgeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBhbmdsZSBSb3RhdGlvbiAoaW4gY291bnRlci1jbG9ja3dpc2UgcmFkaWFucykuXG4gKiBAcGFyYW0ge251bWJlcn0gZHgyIEZpbmFsIHRyYW5zbGF0aW9uIHguXG4gKiBAcGFyYW0ge251bWJlcn0gZHkyIEZpbmFsIHRyYW5zbGF0aW9uIHkuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBjb21wb3NpdGUgY3NzIHRyYW5zZm9ybS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZUNzc1RyYW5zZm9ybShkeDEsIGR5MSwgc3gsIHN5LCBhbmdsZSwgZHgyLCBkeTIpIHtcbiAgcmV0dXJuIHRvU3RyaW5nKGNvbXBvc2UoY3JlYXRlKCksIGR4MSwgZHkxLCBzeCwgc3ksIGFuZ2xlLCBkeDIsIGR5MikpO1xufVxuLyoqXG4gKiBJbnZlcnQgdGhlIGdpdmVuIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7IVRyYW5zZm9ybX0gc291cmNlIFRoZSBzb3VyY2UgdHJhbnNmb3JtIHRvIGludmVydC5cbiAqIEByZXR1cm4geyFUcmFuc2Zvcm19IFRoZSBpbnZlcnRlZCAoc291cmNlKSB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludmVydChzb3VyY2UpIHtcbiAgcmV0dXJuIG1ha2VJbnZlcnNlKHNvdXJjZSwgc291cmNlKTtcbn1cbi8qKlxuICogSW52ZXJ0IHRoZSBnaXZlbiB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHRhcmdldCBUcmFuc2Zvcm0gdG8gYmUgc2V0IGFzIHRoZSBpbnZlcnNlIG9mXG4gKiAgICAgdGhlIHNvdXJjZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IHNvdXJjZSBUaGUgc291cmNlIHRyYW5zZm9ybSB0byBpbnZlcnQuXG4gKiBAcmV0dXJuIHshVHJhbnNmb3JtfSBUaGUgaW52ZXJ0ZWQgKHRhcmdldCkgdHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlSW52ZXJzZSh0YXJnZXQsIHNvdXJjZSkge1xuICB2YXIgZGV0ID0gZGV0ZXJtaW5hbnQoc291cmNlKTtcbiAgYXNzZXJ0KGRldCAhPT0gMCwgMzIpOyAvLyBUcmFuc2Zvcm1hdGlvbiBtYXRyaXggY2Fubm90IGJlIGludmVydGVkXG5cbiAgdmFyIGEgPSBzb3VyY2VbMF07XG4gIHZhciBiID0gc291cmNlWzFdO1xuICB2YXIgYyA9IHNvdXJjZVsyXTtcbiAgdmFyIGQgPSBzb3VyY2VbM107XG4gIHZhciBlID0gc291cmNlWzRdO1xuICB2YXIgZiA9IHNvdXJjZVs1XTtcbiAgdGFyZ2V0WzBdID0gZCAvIGRldDtcbiAgdGFyZ2V0WzFdID0gLWIgLyBkZXQ7XG4gIHRhcmdldFsyXSA9IC1jIC8gZGV0O1xuICB0YXJnZXRbM10gPSBhIC8gZGV0O1xuICB0YXJnZXRbNF0gPSAoYyAqIGYgLSBkICogZSkgLyBkZXQ7XG4gIHRhcmdldFs1XSA9IC0oYSAqIGYgLSBiICogZSkgLyBkZXQ7XG4gIHJldHVybiB0YXJnZXQ7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGRldGVybWluYW50IG9mIHRoZSBnaXZlbiBtYXRyaXguXG4gKiBAcGFyYW0geyFUcmFuc2Zvcm19IG1hdCBNYXRyaXguXG4gKiBAcmV0dXJuIHtudW1iZXJ9IERldGVybWluYW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlcm1pbmFudChtYXQpIHtcbiAgcmV0dXJuIG1hdFswXSAqIG1hdFszXSAtIG1hdFsxXSAqIG1hdFsyXTtcbn1cbi8qKlxuICogQSBzdHJpbmcgdmVyc2lvbiBvZiB0aGUgdHJhbnNmb3JtLiAgVGhpcyBjYW4gYmUgdXNlZFxuICogZm9yIENTUyB0cmFuc2Zvcm1zLlxuICogQHBhcmFtIHshVHJhbnNmb3JtfSBtYXQgTWF0cml4LlxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgdHJhbnNmb3JtIGFzIGEgc3RyaW5nLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1N0cmluZyhtYXQpIHtcbiAgcmV0dXJuICdtYXRyaXgoJyArIG1hdC5qb2luKCcsICcpICsgJyknO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9leHRlbnQvQ29ybmVyXG4gKi9cblxuLyoqXG4gKiBFeHRlbnQgY29ybmVyLlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBCT1RUT01fTEVGVDogJ2JvdHRvbS1sZWZ0JyxcbiAgQk9UVE9NX1JJR0hUOiAnYm90dG9tLXJpZ2h0JyxcbiAgVE9QX0xFRlQ6ICd0b3AtbGVmdCcsXG4gIFRPUF9SSUdIVDogJ3RvcC1yaWdodCdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V4dGVudC9SZWxhdGlvbnNoaXBcbiAqL1xuXG4vKipcbiAqIFJlbGF0aW9uc2hpcCB0byBhbiBleHRlbnQuXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFVOS05PV046IDAsXG4gIElOVEVSU0VDVElORzogMSxcbiAgQUJPVkU6IDIsXG4gIFJJR0hUOiA0LFxuICBCRUxPVzogOCxcbiAgTEVGVDogMTZcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V4dGVudFxuICovXG5pbXBvcnQgQ29ybmVyIGZyb20gJy4vZXh0ZW50L0Nvcm5lci5qcyc7XG5pbXBvcnQgUmVsYXRpb25zaGlwIGZyb20gJy4vZXh0ZW50L1JlbGF0aW9uc2hpcC5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuLyoqXG4gKiBBbiBhcnJheSBvZiBudW1iZXJzIHJlcHJlc2VudGluZyBhbiBleHRlbnQ6IGBbbWlueCwgbWlueSwgbWF4eCwgbWF4eV1gLlxuICogQHR5cGVkZWYge0FycmF5PG51bWJlcj59IEV4dGVudFxuICogQGFwaVxuICovXG5cbi8qKlxuICogQnVpbGQgYW4gZXh0ZW50IHRoYXQgaW5jbHVkZXMgYWxsIGdpdmVuIGNvb3JkaW5hdGVzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEByZXR1cm4ge0V4dGVudH0gQm91bmRpbmcgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBib3VuZGluZ0V4dGVudChjb29yZGluYXRlcykge1xuICB2YXIgZXh0ZW50ID0gY3JlYXRlRW1wdHkoKTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgZXh0ZW5kQ29vcmRpbmF0ZShleHRlbnQsIGNvb3JkaW5hdGVzW2ldKTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQ7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geHMgWHMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHlzIFlzLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IERlc3RpbmF0aW9uIGV4dGVudC5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5mdW5jdGlvbiBfYm91bmRpbmdFeHRlbnRYWXMoeHMsIHlzLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBtaW5YID0gTWF0aC5taW4uYXBwbHkobnVsbCwgeHMpO1xuICB2YXIgbWluWSA9IE1hdGgubWluLmFwcGx5KG51bGwsIHlzKTtcbiAgdmFyIG1heFggPSBNYXRoLm1heC5hcHBseShudWxsLCB4cyk7XG4gIHZhciBtYXhZID0gTWF0aC5tYXguYXBwbHkobnVsbCwgeXMpO1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUobWluWCwgbWluWSwgbWF4WCwgbWF4WSwgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIFJldHVybiBleHRlbnQgaW5jcmVhc2VkIGJ5IHRoZSBwcm92aWRlZCB2YWx1ZS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBhbW91bnQgYnkgd2hpY2ggdGhlIGV4dGVudCBzaG91bGQgYmUgYnVmZmVyZWQuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gYnVmZmVyKGV4dGVudCwgdmFsdWUsIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gZXh0ZW50WzBdIC0gdmFsdWU7XG4gICAgb3B0X2V4dGVudFsxXSA9IGV4dGVudFsxXSAtIHZhbHVlO1xuICAgIG9wdF9leHRlbnRbMl0gPSBleHRlbnRbMl0gKyB2YWx1ZTtcbiAgICBvcHRfZXh0ZW50WzNdID0gZXh0ZW50WzNdICsgdmFsdWU7XG4gICAgcmV0dXJuIG9wdF9leHRlbnQ7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtleHRlbnRbMF0gLSB2YWx1ZSwgZXh0ZW50WzFdIC0gdmFsdWUsIGV4dGVudFsyXSArIHZhbHVlLCBleHRlbnRbM10gKyB2YWx1ZV07XG4gIH1cbn1cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGFuIGV4dGVudC5cbiAqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IFRoZSBjbG9uZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvbmUoZXh0ZW50LCBvcHRfZXh0ZW50KSB7XG4gIGlmIChvcHRfZXh0ZW50KSB7XG4gICAgb3B0X2V4dGVudFswXSA9IGV4dGVudFswXTtcbiAgICBvcHRfZXh0ZW50WzFdID0gZXh0ZW50WzFdO1xuICAgIG9wdF9leHRlbnRbMl0gPSBleHRlbnRbMl07XG4gICAgb3B0X2V4dGVudFszXSA9IGV4dGVudFszXTtcbiAgICByZXR1cm4gb3B0X2V4dGVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXh0ZW50LnNsaWNlKCk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEByZXR1cm4ge251bWJlcn0gQ2xvc2VzdCBzcXVhcmVkIGRpc3RhbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkoZXh0ZW50LCB4LCB5KSB7XG4gIHZhciBkeCwgZHk7XG5cbiAgaWYgKHggPCBleHRlbnRbMF0pIHtcbiAgICBkeCA9IGV4dGVudFswXSAtIHg7XG4gIH0gZWxzZSBpZiAoZXh0ZW50WzJdIDwgeCkge1xuICAgIGR4ID0geCAtIGV4dGVudFsyXTtcbiAgfSBlbHNlIHtcbiAgICBkeCA9IDA7XG4gIH1cblxuICBpZiAoeSA8IGV4dGVudFsxXSkge1xuICAgIGR5ID0gZXh0ZW50WzFdIC0geTtcbiAgfSBlbHNlIGlmIChleHRlbnRbM10gPCB5KSB7XG4gICAgZHkgPSB5IC0gZXh0ZW50WzNdO1xuICB9IGVsc2Uge1xuICAgIGR5ID0gMDtcbiAgfVxuXG4gIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHBhc3NlZCBjb29yZGluYXRlIGlzIGNvbnRhaW5lZCBvciBvbiB0aGUgZWRnZSBvZiB0aGUgZXh0ZW50LlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGNvb3JkaW5hdGUgaXMgY29udGFpbmVkIGluIHRoZSBleHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zQ29vcmRpbmF0ZShleHRlbnQsIGNvb3JkaW5hdGUpIHtcbiAgcmV0dXJuIGNvbnRhaW5zWFkoZXh0ZW50LCBjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdKTtcbn1cbi8qKlxuICogQ2hlY2sgaWYgb25lIGV4dGVudCBjb250YWlucyBhbm90aGVyLlxuICpcbiAqIEFuIGV4dGVudCBpcyBkZWVtZWQgY29udGFpbmVkIGlmIGl0IGxpZXMgY29tcGxldGVseSB3aXRoaW4gdGhlIG90aGVyIGV4dGVudCxcbiAqIGluY2x1ZGluZyBpZiB0aGV5IHNoYXJlIG9uZSBvciBtb3JlIGVkZ2VzLlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgc2Vjb25kIGV4dGVudCBpcyBjb250YWluZWQgYnkgb3Igb24gdGhlIGVkZ2Ugb2YgdGhlXG4gKiAgICAgZmlyc3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5zRXh0ZW50KGV4dGVudDEsIGV4dGVudDIpIHtcbiAgcmV0dXJuIGV4dGVudDFbMF0gPD0gZXh0ZW50MlswXSAmJiBleHRlbnQyWzJdIDw9IGV4dGVudDFbMl0gJiYgZXh0ZW50MVsxXSA8PSBleHRlbnQyWzFdICYmIGV4dGVudDJbM10gPD0gZXh0ZW50MVszXTtcbn1cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHBhc3NlZCBjb29yZGluYXRlIGlzIGNvbnRhaW5lZCBvciBvbiB0aGUgZWRnZSBvZiB0aGUgZXh0ZW50LlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHggWCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWSBjb29yZGluYXRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHgsIHkgdmFsdWVzIGFyZSBjb250YWluZWQgaW4gdGhlIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNYWShleHRlbnQsIHgsIHkpIHtcbiAgcmV0dXJuIGV4dGVudFswXSA8PSB4ICYmIHggPD0gZXh0ZW50WzJdICYmIGV4dGVudFsxXSA8PSB5ICYmIHkgPD0gZXh0ZW50WzNdO1xufVxuLyoqXG4gKiBHZXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGEgY29vcmRpbmF0ZSBhbmQgZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBUaGUgZXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBUaGUgY29vcmRpbmF0ZS5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50L1JlbGF0aW9uc2hpcC5qc1wiKS5kZWZhdWx0fSBUaGUgcmVsYXRpb25zaGlwIChiaXR3aXNlIGNvbXBhcmUgd2l0aFxuICogICAgIGltcG9ydChcIi4vZXh0ZW50L1JlbGF0aW9uc2hpcC5qc1wiKS5SZWxhdGlvbnNoaXApLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb29yZGluYXRlUmVsYXRpb25zaGlwKGV4dGVudCwgY29vcmRpbmF0ZSkge1xuICB2YXIgbWluWCA9IGV4dGVudFswXTtcbiAgdmFyIG1pblkgPSBleHRlbnRbMV07XG4gIHZhciBtYXhYID0gZXh0ZW50WzJdO1xuICB2YXIgbWF4WSA9IGV4dGVudFszXTtcbiAgdmFyIHggPSBjb29yZGluYXRlWzBdO1xuICB2YXIgeSA9IGNvb3JkaW5hdGVbMV07XG4gIHZhciByZWxhdGlvbnNoaXAgPSBSZWxhdGlvbnNoaXAuVU5LTk9XTjtcblxuICBpZiAoeCA8IG1pblgpIHtcbiAgICByZWxhdGlvbnNoaXAgPSByZWxhdGlvbnNoaXAgfCBSZWxhdGlvbnNoaXAuTEVGVDtcbiAgfSBlbHNlIGlmICh4ID4gbWF4WCkge1xuICAgIHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcCB8IFJlbGF0aW9uc2hpcC5SSUdIVDtcbiAgfVxuXG4gIGlmICh5IDwgbWluWSkge1xuICAgIHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcCB8IFJlbGF0aW9uc2hpcC5CRUxPVztcbiAgfSBlbHNlIGlmICh5ID4gbWF4WSkge1xuICAgIHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcCB8IFJlbGF0aW9uc2hpcC5BQk9WRTtcbiAgfVxuXG4gIGlmIChyZWxhdGlvbnNoaXAgPT09IFJlbGF0aW9uc2hpcC5VTktOT1dOKSB7XG4gICAgcmVsYXRpb25zaGlwID0gUmVsYXRpb25zaGlwLklOVEVSU0VDVElORztcbiAgfVxuXG4gIHJldHVybiByZWxhdGlvbnNoaXA7XG59XG4vKipcbiAqIENyZWF0ZSBhbiBlbXB0eSBleHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEVtcHR5IGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW1wdHkoKSB7XG4gIHJldHVybiBbSW5maW5pdHksIEluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eV07XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBleHRlbnQgb3IgdXBkYXRlIHRoZSBwcm92aWRlZCBleHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gbWluWCBNaW5pbXVtIFguXG4gKiBAcGFyYW0ge251bWJlcn0gbWluWSBNaW5pbXVtIFkuXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4WCBNYXhpbXVtIFguXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4WSBNYXhpbXVtIFkuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlKG1pblgsIG1pblksIG1heFgsIG1heFksIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gbWluWDtcbiAgICBvcHRfZXh0ZW50WzFdID0gbWluWTtcbiAgICBvcHRfZXh0ZW50WzJdID0gbWF4WDtcbiAgICBvcHRfZXh0ZW50WzNdID0gbWF4WTtcbiAgICByZXR1cm4gb3B0X2V4dGVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW21pblgsIG1pblksIG1heFgsIG1heFldO1xuICB9XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBlbXB0eSBleHRlbnQgb3IgbWFrZSB0aGUgcHJvdmlkZWQgb25lIGVtcHR5LlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZUVtcHR5KG9wdF9leHRlbnQpIHtcbiAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlKEluZmluaXR5LCBJbmZpbml0eSwgLUluZmluaXR5LCAtSW5maW5pdHksIG9wdF9leHRlbnQpO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgb3B0X2V4dGVudCkge1xuICB2YXIgeCA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5ID0gY29vcmRpbmF0ZVsxXTtcbiAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlKHgsIHksIHgsIHksIG9wdF9leHRlbnQpO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGVzKGNvb3JkaW5hdGVzLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBleHRlbnQgPSBjcmVhdGVPclVwZGF0ZUVtcHR5KG9wdF9leHRlbnQpO1xuICByZXR1cm4gZXh0ZW5kQ29vcmRpbmF0ZXMoZXh0ZW50LCBjb29yZGluYXRlcyk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlRW1wdHkob3B0X2V4dGVudCk7XG4gIHJldHVybiBleHRlbmRGbGF0Q29vcmRpbmF0ZXMoZXh0ZW50LCBmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IHJpbmdzIFJpbmdzLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZUZyb21SaW5ncyhyaW5ncywgb3B0X2V4dGVudCkge1xuICB2YXIgZXh0ZW50ID0gY3JlYXRlT3JVcGRhdGVFbXB0eShvcHRfZXh0ZW50KTtcbiAgcmV0dXJuIGV4dGVuZFJpbmdzKGV4dGVudCwgcmluZ3MpO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdHdvIGV4dGVudHMgYXJlIGVxdWl2YWxlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudCAyLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHR3byBleHRlbnRzIGFyZSBlcXVpdmFsZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbHMoZXh0ZW50MSwgZXh0ZW50Mikge1xuICByZXR1cm4gZXh0ZW50MVswXSA9PSBleHRlbnQyWzBdICYmIGV4dGVudDFbMl0gPT0gZXh0ZW50MlsyXSAmJiBleHRlbnQxWzFdID09IGV4dGVudDJbMV0gJiYgZXh0ZW50MVszXSA9PSBleHRlbnQyWzNdO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdHdvIGV4dGVudHMgYXJlIGFwcHJveGltYXRlbHkgZXF1aXZhbGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZSBpbiBleHRlbnQgY29vcmRpbmF0ZSB1bml0cy5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB0d28gZXh0ZW50cyBkaWZmZXIgYnkgbGVzcyB0aGFuIHRoZSB0b2xlcmFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcHJveGltYXRlbHlFcXVhbHMoZXh0ZW50MSwgZXh0ZW50MiwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiBNYXRoLmFicyhleHRlbnQxWzBdIC0gZXh0ZW50MlswXSkgPCB0b2xlcmFuY2UgJiYgTWF0aC5hYnMoZXh0ZW50MVsyXSAtIGV4dGVudDJbMl0pIDwgdG9sZXJhbmNlICYmIE1hdGguYWJzKGV4dGVudDFbMV0gLSBleHRlbnQyWzFdKSA8IHRvbGVyYW5jZSAmJiBNYXRoLmFicyhleHRlbnQxWzNdIC0gZXh0ZW50MlszXSkgPCB0b2xlcmFuY2U7XG59XG4vKipcbiAqIE1vZGlmeSBhbiBleHRlbnQgdG8gaW5jbHVkZSBhbm90aGVyIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIFRoZSBleHRlbnQgdG8gYmUgbW9kaWZpZWQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBUaGUgZXh0ZW50IHRoYXQgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgZmlyc3QuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEEgcmVmZXJlbmNlIHRvIHRoZSBmaXJzdCAoZXh0ZW5kZWQpIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kKGV4dGVudDEsIGV4dGVudDIpIHtcbiAgaWYgKGV4dGVudDJbMF0gPCBleHRlbnQxWzBdKSB7XG4gICAgZXh0ZW50MVswXSA9IGV4dGVudDJbMF07XG4gIH1cblxuICBpZiAoZXh0ZW50MlsyXSA+IGV4dGVudDFbMl0pIHtcbiAgICBleHRlbnQxWzJdID0gZXh0ZW50MlsyXTtcbiAgfVxuXG4gIGlmIChleHRlbnQyWzFdIDwgZXh0ZW50MVsxXSkge1xuICAgIGV4dGVudDFbMV0gPSBleHRlbnQyWzFdO1xuICB9XG5cbiAgaWYgKGV4dGVudDJbM10gPiBleHRlbnQxWzNdKSB7XG4gICAgZXh0ZW50MVszXSA9IGV4dGVudDJbM107XG4gIH1cblxuICByZXR1cm4gZXh0ZW50MTtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZENvb3JkaW5hdGUoZXh0ZW50LCBjb29yZGluYXRlKSB7XG4gIGlmIChjb29yZGluYXRlWzBdIDwgZXh0ZW50WzBdKSB7XG4gICAgZXh0ZW50WzBdID0gY29vcmRpbmF0ZVswXTtcbiAgfVxuXG4gIGlmIChjb29yZGluYXRlWzBdID4gZXh0ZW50WzJdKSB7XG4gICAgZXh0ZW50WzJdID0gY29vcmRpbmF0ZVswXTtcbiAgfVxuXG4gIGlmIChjb29yZGluYXRlWzFdIDwgZXh0ZW50WzFdKSB7XG4gICAgZXh0ZW50WzFdID0gY29vcmRpbmF0ZVsxXTtcbiAgfVxuXG4gIGlmIChjb29yZGluYXRlWzFdID4gZXh0ZW50WzNdKSB7XG4gICAgZXh0ZW50WzNdID0gY29vcmRpbmF0ZVsxXTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbmRDb29yZGluYXRlcyhleHRlbnQsIGNvb3JkaW5hdGVzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBleHRlbmRDb29yZGluYXRlKGV4dGVudCwgY29vcmRpbmF0ZXNbaV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZEZsYXRDb29yZGluYXRlcyhleHRlbnQsIGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICBmb3IgKDsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgZXh0ZW5kWFkoZXh0ZW50LCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XSwgZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdKTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQ7XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSByaW5ncyBSaW5ncy5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbmRSaW5ncyhleHRlbnQsIHJpbmdzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IHJpbmdzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBleHRlbmRDb29yZGluYXRlcyhleHRlbnQsIHJpbmdzW2ldKTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQ7XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZFhZKGV4dGVudCwgeCwgeSkge1xuICBleHRlbnRbMF0gPSBNYXRoLm1pbihleHRlbnRbMF0sIHgpO1xuICBleHRlbnRbMV0gPSBNYXRoLm1pbihleHRlbnRbMV0sIHkpO1xuICBleHRlbnRbMl0gPSBNYXRoLm1heChleHRlbnRbMl0sIHgpO1xuICBleHRlbnRbM10gPSBNYXRoLm1heChleHRlbnRbM10sIHkpO1xufVxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGNhbGxzIGBjYWxsYmFja2AgZm9yIGVhY2ggY29ybmVyIG9mIHRoZSBleHRlbnQuIElmIHRoZVxuICogY2FsbGJhY2sgcmV0dXJucyBhIHRydXRoeSB2YWx1ZSB0aGUgZnVuY3Rpb24gcmV0dXJucyB0aGF0IHZhbHVlXG4gKiBpbW1lZGlhdGVseS4gT3RoZXJ3aXNlIHRoZSBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBTfSBjYWxsYmFjayBDYWxsYmFjay5cbiAqIEByZXR1cm4ge1N8Ym9vbGVhbn0gVmFsdWUuXG4gKiBAdGVtcGxhdGUgU1xuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JFYWNoQ29ybmVyKGV4dGVudCwgY2FsbGJhY2spIHtcbiAgdmFyIHZhbDtcbiAgdmFsID0gY2FsbGJhY2soZ2V0Qm90dG9tTGVmdChleHRlbnQpKTtcblxuICBpZiAodmFsKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIHZhbCA9IGNhbGxiYWNrKGdldEJvdHRvbVJpZ2h0KGV4dGVudCkpO1xuXG4gIGlmICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgdmFsID0gY2FsbGJhY2soZ2V0VG9wUmlnaHQoZXh0ZW50KSk7XG5cbiAgaWYgKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICB2YWwgPSBjYWxsYmFjayhnZXRUb3BMZWZ0KGV4dGVudCkpO1xuXG4gIGlmICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBHZXQgdGhlIHNpemUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFyZWEoZXh0ZW50KSB7XG4gIHZhciBhcmVhID0gMDtcblxuICBpZiAoIWlzRW1wdHkoZXh0ZW50KSkge1xuICAgIGFyZWEgPSBnZXRXaWR0aChleHRlbnQpICogZ2V0SGVpZ2h0KGV4dGVudCk7XG4gIH1cblxuICByZXR1cm4gYXJlYTtcbn1cbi8qKlxuICogR2V0IHRoZSBib3R0b20gbGVmdCBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IEJvdHRvbSBsZWZ0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJvdHRvbUxlZnQoZXh0ZW50KSB7XG4gIHJldHVybiBbZXh0ZW50WzBdLCBleHRlbnRbMV1dO1xufVxuLyoqXG4gKiBHZXQgdGhlIGJvdHRvbSByaWdodCBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IEJvdHRvbSByaWdodCBjb29yZGluYXRlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3R0b21SaWdodChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMl0sIGV4dGVudFsxXV07XG59XG4vKipcbiAqIEdldCB0aGUgY2VudGVyIGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ2VudGVyLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDZW50ZXIoZXh0ZW50KSB7XG4gIHJldHVybiBbKGV4dGVudFswXSArIGV4dGVudFsyXSkgLyAyLCAoZXh0ZW50WzFdICsgZXh0ZW50WzNdKSAvIDJdO1xufVxuLyoqXG4gKiBHZXQgYSBjb3JuZXIgY29vcmRpbmF0ZSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQvQ29ybmVyLmpzXCIpLmRlZmF1bHR9IGNvcm5lciBDb3JuZXIuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29ybmVyIGNvb3JkaW5hdGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENvcm5lcihleHRlbnQsIGNvcm5lcikge1xuICB2YXIgY29vcmRpbmF0ZTtcblxuICBpZiAoY29ybmVyID09PSBDb3JuZXIuQk9UVE9NX0xFRlQpIHtcbiAgICBjb29yZGluYXRlID0gZ2V0Qm90dG9tTGVmdChleHRlbnQpO1xuICB9IGVsc2UgaWYgKGNvcm5lciA9PT0gQ29ybmVyLkJPVFRPTV9SSUdIVCkge1xuICAgIGNvb3JkaW5hdGUgPSBnZXRCb3R0b21SaWdodChleHRlbnQpO1xuICB9IGVsc2UgaWYgKGNvcm5lciA9PT0gQ29ybmVyLlRPUF9MRUZUKSB7XG4gICAgY29vcmRpbmF0ZSA9IGdldFRvcExlZnQoZXh0ZW50KTtcbiAgfSBlbHNlIGlmIChjb3JuZXIgPT09IENvcm5lci5UT1BfUklHSFQpIHtcbiAgICBjb29yZGluYXRlID0gZ2V0VG9wUmlnaHQoZXh0ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBhc3NlcnQoZmFsc2UsIDEzKTsgLy8gSW52YWxpZCBjb3JuZXJcbiAgfVxuXG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudCAyLlxuICogQHJldHVybiB7bnVtYmVyfSBFbmxhcmdlZCBhcmVhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbmxhcmdlZEFyZWEoZXh0ZW50MSwgZXh0ZW50Mikge1xuICB2YXIgbWluWCA9IE1hdGgubWluKGV4dGVudDFbMF0sIGV4dGVudDJbMF0pO1xuICB2YXIgbWluWSA9IE1hdGgubWluKGV4dGVudDFbMV0sIGV4dGVudDJbMV0pO1xuICB2YXIgbWF4WCA9IE1hdGgubWF4KGV4dGVudDFbMl0sIGV4dGVudDJbMl0pO1xuICB2YXIgbWF4WSA9IE1hdGgubWF4KGV4dGVudDFbM10sIGV4dGVudDJbM10pO1xuICByZXR1cm4gKG1heFggLSBtaW5YKSAqIChtYXhZIC0gbWluWSk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNlbnRlciBDZW50ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBTaXplLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IERlc3RpbmF0aW9uIGV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JWaWV3QW5kU2l6ZShjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBzaXplLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBkeCA9IHJlc29sdXRpb24gKiBzaXplWzBdIC8gMjtcbiAgdmFyIGR5ID0gcmVzb2x1dGlvbiAqIHNpemVbMV0gLyAyO1xuICB2YXIgY29zUm90YXRpb24gPSBNYXRoLmNvcyhyb3RhdGlvbik7XG4gIHZhciBzaW5Sb3RhdGlvbiA9IE1hdGguc2luKHJvdGF0aW9uKTtcbiAgdmFyIHhDb3MgPSBkeCAqIGNvc1JvdGF0aW9uO1xuICB2YXIgeFNpbiA9IGR4ICogc2luUm90YXRpb247XG4gIHZhciB5Q29zID0gZHkgKiBjb3NSb3RhdGlvbjtcbiAgdmFyIHlTaW4gPSBkeSAqIHNpblJvdGF0aW9uO1xuICB2YXIgeCA9IGNlbnRlclswXTtcbiAgdmFyIHkgPSBjZW50ZXJbMV07XG4gIHZhciB4MCA9IHggLSB4Q29zICsgeVNpbjtcbiAgdmFyIHgxID0geCAtIHhDb3MgLSB5U2luO1xuICB2YXIgeDIgPSB4ICsgeENvcyAtIHlTaW47XG4gIHZhciB4MyA9IHggKyB4Q29zICsgeVNpbjtcbiAgdmFyIHkwID0geSAtIHhTaW4gLSB5Q29zO1xuICB2YXIgeTEgPSB5IC0geFNpbiArIHlDb3M7XG4gIHZhciB5MiA9IHkgKyB4U2luICsgeUNvcztcbiAgdmFyIHkzID0geSArIHhTaW4gLSB5Q29zO1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUoTWF0aC5taW4oeDAsIHgxLCB4MiwgeDMpLCBNYXRoLm1pbih5MCwgeTEsIHkyLCB5MyksIE1hdGgubWF4KHgwLCB4MSwgeDIsIHgzKSwgTWF0aC5tYXgoeTAsIHkxLCB5MiwgeTMpLCBvcHRfZXh0ZW50KTtcbn1cbi8qKlxuICogR2V0IHRoZSBoZWlnaHQgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEhlaWdodC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SGVpZ2h0KGV4dGVudCkge1xuICByZXR1cm4gZXh0ZW50WzNdIC0gZXh0ZW50WzFdO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudCAyLlxuICogQHJldHVybiB7bnVtYmVyfSBJbnRlcnNlY3Rpb24gYXJlYS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9uQXJlYShleHRlbnQxLCBleHRlbnQyKSB7XG4gIHZhciBpbnRlcnNlY3Rpb24gPSBnZXRJbnRlcnNlY3Rpb24oZXh0ZW50MSwgZXh0ZW50Mik7XG4gIHJldHVybiBnZXRBcmVhKGludGVyc2VjdGlvbik7XG59XG4vKipcbiAqIEdldCB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3byBleHRlbnRzLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQgMi5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBPcHRpb25hbCBleHRlbnQgdG8gcG9wdWxhdGUgd2l0aCBpbnRlcnNlY3Rpb24uXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEludGVyc2VjdGluZyBleHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEludGVyc2VjdGlvbihleHRlbnQxLCBleHRlbnQyLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBpbnRlcnNlY3Rpb24gPSBvcHRfZXh0ZW50ID8gb3B0X2V4dGVudCA6IGNyZWF0ZUVtcHR5KCk7XG5cbiAgaWYgKGludGVyc2VjdHMoZXh0ZW50MSwgZXh0ZW50MikpIHtcbiAgICBpZiAoZXh0ZW50MVswXSA+IGV4dGVudDJbMF0pIHtcbiAgICAgIGludGVyc2VjdGlvblswXSA9IGV4dGVudDFbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGludGVyc2VjdGlvblswXSA9IGV4dGVudDJbMF07XG4gICAgfVxuXG4gICAgaWYgKGV4dGVudDFbMV0gPiBleHRlbnQyWzFdKSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMV0gPSBleHRlbnQxWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMV0gPSBleHRlbnQyWzFdO1xuICAgIH1cblxuICAgIGlmIChleHRlbnQxWzJdIDwgZXh0ZW50MlsyXSkge1xuICAgICAgaW50ZXJzZWN0aW9uWzJdID0gZXh0ZW50MVsyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJzZWN0aW9uWzJdID0gZXh0ZW50MlsyXTtcbiAgICB9XG5cbiAgICBpZiAoZXh0ZW50MVszXSA8IGV4dGVudDJbM10pIHtcbiAgICAgIGludGVyc2VjdGlvblszXSA9IGV4dGVudDFbM107XG4gICAgfSBlbHNlIHtcbiAgICAgIGludGVyc2VjdGlvblszXSA9IGV4dGVudDJbM107XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNyZWF0ZU9yVXBkYXRlRW1wdHkoaW50ZXJzZWN0aW9uKTtcbiAgfVxuXG4gIHJldHVybiBpbnRlcnNlY3Rpb247XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7bnVtYmVyfSBNYXJnaW4uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmdpbihleHRlbnQpIHtcbiAgcmV0dXJuIGdldFdpZHRoKGV4dGVudCkgKyBnZXRIZWlnaHQoZXh0ZW50KTtcbn1cbi8qKlxuICogR2V0IHRoZSBzaXplICh3aWR0aCwgaGVpZ2h0KSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gVGhlIGV4dGVudCBzaXplLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTaXplKGV4dGVudCkge1xuICByZXR1cm4gW2V4dGVudFsyXSAtIGV4dGVudFswXSwgZXh0ZW50WzNdIC0gZXh0ZW50WzFdXTtcbn1cbi8qKlxuICogR2V0IHRoZSB0b3AgbGVmdCBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFRvcCBsZWZ0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRvcExlZnQoZXh0ZW50KSB7XG4gIHJldHVybiBbZXh0ZW50WzBdLCBleHRlbnRbM11dO1xufVxuLyoqXG4gKiBHZXQgdGhlIHRvcCByaWdodCBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFRvcCByaWdodCBjb29yZGluYXRlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb3BSaWdodChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMl0sIGV4dGVudFszXV07XG59XG4vKipcbiAqIEdldCB0aGUgd2lkdGggb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFdpZHRoLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXaWR0aChleHRlbnQpIHtcbiAgcmV0dXJuIGV4dGVudFsyXSAtIGV4dGVudFswXTtcbn1cbi8qKlxuICogRGV0ZXJtaW5lIGlmIG9uZSBleHRlbnQgaW50ZXJzZWN0cyBhbm90aGVyLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdHdvIGV4dGVudHMgaW50ZXJzZWN0LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzKGV4dGVudDEsIGV4dGVudDIpIHtcbiAgcmV0dXJuIGV4dGVudDFbMF0gPD0gZXh0ZW50MlsyXSAmJiBleHRlbnQxWzJdID49IGV4dGVudDJbMF0gJiYgZXh0ZW50MVsxXSA8PSBleHRlbnQyWzNdICYmIGV4dGVudDFbM10gPj0gZXh0ZW50MlsxXTtcbn1cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIGV4dGVudCBpcyBlbXB0eS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gSXMgZW1wdHkuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZXh0ZW50KSB7XG4gIHJldHVybiBleHRlbnRbMl0gPCBleHRlbnRbMF0gfHwgZXh0ZW50WzNdIDwgZXh0ZW50WzFdO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmV0dXJuT3JVcGRhdGUoZXh0ZW50LCBvcHRfZXh0ZW50KSB7XG4gIGlmIChvcHRfZXh0ZW50KSB7XG4gICAgb3B0X2V4dGVudFswXSA9IGV4dGVudFswXTtcbiAgICBvcHRfZXh0ZW50WzFdID0gZXh0ZW50WzFdO1xuICAgIG9wdF9leHRlbnRbMl0gPSBleHRlbnRbMl07XG4gICAgb3B0X2V4dGVudFszXSA9IGV4dGVudFszXTtcbiAgICByZXR1cm4gb3B0X2V4dGVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXh0ZW50O1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZUZyb21DZW50ZXIoZXh0ZW50LCB2YWx1ZSkge1xuICB2YXIgZGVsdGFYID0gKGV4dGVudFsyXSAtIGV4dGVudFswXSkgLyAyICogKHZhbHVlIC0gMSk7XG4gIHZhciBkZWx0YVkgPSAoZXh0ZW50WzNdIC0gZXh0ZW50WzFdKSAvIDIgKiAodmFsdWUgLSAxKTtcbiAgZXh0ZW50WzBdIC09IGRlbHRhWDtcbiAgZXh0ZW50WzJdICs9IGRlbHRhWDtcbiAgZXh0ZW50WzFdIC09IGRlbHRhWTtcbiAgZXh0ZW50WzNdICs9IGRlbHRhWTtcbn1cbi8qKlxuICogRGV0ZXJtaW5lIGlmIHRoZSBzZWdtZW50IGJldHdlZW4gdHdvIGNvb3JkaW5hdGVzIGludGVyc2VjdHMgKGNyb3NzZXMsXG4gKiB0b3VjaGVzLCBvciBpcyBjb250YWluZWQgYnkpIHRoZSBwcm92aWRlZCBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBzdGFydCBTZWdtZW50IHN0YXJ0IGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBlbmQgU2VnbWVudCBlbmQgY29vcmRpbmF0ZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBzZWdtZW50IGludGVyc2VjdHMgdGhlIGV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0c1NlZ21lbnQoZXh0ZW50LCBzdGFydCwgZW5kKSB7XG4gIHZhciBpbnRlcnNlY3RzID0gZmFsc2U7XG4gIHZhciBzdGFydFJlbCA9IGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBzdGFydCk7XG4gIHZhciBlbmRSZWwgPSBjb29yZGluYXRlUmVsYXRpb25zaGlwKGV4dGVudCwgZW5kKTtcblxuICBpZiAoc3RhcnRSZWwgPT09IFJlbGF0aW9uc2hpcC5JTlRFUlNFQ1RJTkcgfHwgZW5kUmVsID09PSBSZWxhdGlvbnNoaXAuSU5URVJTRUNUSU5HKSB7XG4gICAgaW50ZXJzZWN0cyA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdmFyIG1pblggPSBleHRlbnRbMF07XG4gICAgdmFyIG1pblkgPSBleHRlbnRbMV07XG4gICAgdmFyIG1heFggPSBleHRlbnRbMl07XG4gICAgdmFyIG1heFkgPSBleHRlbnRbM107XG4gICAgdmFyIHN0YXJ0WCA9IHN0YXJ0WzBdO1xuICAgIHZhciBzdGFydFkgPSBzdGFydFsxXTtcbiAgICB2YXIgZW5kWCA9IGVuZFswXTtcbiAgICB2YXIgZW5kWSA9IGVuZFsxXTtcbiAgICB2YXIgc2xvcGUgPSAoZW5kWSAtIHN0YXJ0WSkgLyAoZW5kWCAtIHN0YXJ0WCk7XG4gICAgdmFyIHggPSB2b2lkIDAsXG4gICAgICAgIHkgPSB2b2lkIDA7XG5cbiAgICBpZiAoISEoZW5kUmVsICYgUmVsYXRpb25zaGlwLkFCT1ZFKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLkFCT1ZFKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyB0b3BcbiAgICAgIHggPSBlbmRYIC0gKGVuZFkgLSBtYXhZKSAvIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHggPj0gbWluWCAmJiB4IDw9IG1heFg7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzICYmICEhKGVuZFJlbCAmIFJlbGF0aW9uc2hpcC5SSUdIVCkgJiYgIShzdGFydFJlbCAmIFJlbGF0aW9uc2hpcC5SSUdIVCkpIHtcbiAgICAgIC8vIHBvdGVudGlhbGx5IGludGVyc2VjdHMgcmlnaHRcbiAgICAgIHkgPSBlbmRZIC0gKGVuZFggLSBtYXhYKSAqIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHkgPj0gbWluWSAmJiB5IDw9IG1heFk7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzICYmICEhKGVuZFJlbCAmIFJlbGF0aW9uc2hpcC5CRUxPVykgJiYgIShzdGFydFJlbCAmIFJlbGF0aW9uc2hpcC5CRUxPVykpIHtcbiAgICAgIC8vIHBvdGVudGlhbGx5IGludGVyc2VjdHMgYm90dG9tXG4gICAgICB4ID0gZW5kWCAtIChlbmRZIC0gbWluWSkgLyBzbG9wZTtcbiAgICAgIGludGVyc2VjdHMgPSB4ID49IG1pblggJiYgeCA8PSBtYXhYO1xuICAgIH1cblxuICAgIGlmICghaW50ZXJzZWN0cyAmJiAhIShlbmRSZWwgJiBSZWxhdGlvbnNoaXAuTEVGVCkgJiYgIShzdGFydFJlbCAmIFJlbGF0aW9uc2hpcC5MRUZUKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyBsZWZ0XG4gICAgICB5ID0gZW5kWSAtIChlbmRYIC0gbWluWCkgKiBzbG9wZTtcbiAgICAgIGludGVyc2VjdHMgPSB5ID49IG1pblkgJiYgeSA8PSBtYXhZO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpbnRlcnNlY3RzO1xufVxuLyoqXG4gKiBBcHBseSBhIHRyYW5zZm9ybSBmdW5jdGlvbiB0byB0aGUgZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICogQ2FsbGVkIHdpdGggYFttaW5YLCBtaW5ZLCBtYXhYLCBtYXhZXWAgZXh0ZW50IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IERlc3RpbmF0aW9uIGV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3N0b3BzIE51bWJlciBvZiBzdG9wcyBwZXIgc2lkZSB1c2VkIGZvciB0aGUgdHJhbnNmb3JtLlxuICogQnkgZGVmYXVsdCBvbmx5IHRoZSBjb3JuZXJzIGFyZSB1c2VkLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5VHJhbnNmb3JtKGV4dGVudCwgdHJhbnNmb3JtRm4sIG9wdF9leHRlbnQsIG9wdF9zdG9wcykge1xuICB2YXIgY29vcmRpbmF0ZXMgPSBbXTtcblxuICBpZiAob3B0X3N0b3BzID4gMSkge1xuICAgIHZhciB3aWR0aCA9IGV4dGVudFsyXSAtIGV4dGVudFswXTtcbiAgICB2YXIgaGVpZ2h0ID0gZXh0ZW50WzNdIC0gZXh0ZW50WzFdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHRfc3RvcHM7ICsraSkge1xuICAgICAgY29vcmRpbmF0ZXMucHVzaChleHRlbnRbMF0gKyB3aWR0aCAqIGkgLyBvcHRfc3RvcHMsIGV4dGVudFsxXSwgZXh0ZW50WzJdLCBleHRlbnRbMV0gKyBoZWlnaHQgKiBpIC8gb3B0X3N0b3BzLCBleHRlbnRbMl0gLSB3aWR0aCAqIGkgLyBvcHRfc3RvcHMsIGV4dGVudFszXSwgZXh0ZW50WzBdLCBleHRlbnRbM10gLSBoZWlnaHQgKiBpIC8gb3B0X3N0b3BzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29vcmRpbmF0ZXMgPSBbZXh0ZW50WzBdLCBleHRlbnRbMV0sIGV4dGVudFsyXSwgZXh0ZW50WzFdLCBleHRlbnRbMl0sIGV4dGVudFszXSwgZXh0ZW50WzBdLCBleHRlbnRbM11dO1xuICB9XG5cbiAgdHJhbnNmb3JtRm4oY29vcmRpbmF0ZXMsIGNvb3JkaW5hdGVzLCAyKTtcbiAgdmFyIHhzID0gW107XG4gIHZhciB5cyA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgbDsgaSArPSAyKSB7XG4gICAgeHMucHVzaChjb29yZGluYXRlc1tpXSk7XG4gICAgeXMucHVzaChjb29yZGluYXRlc1tpICsgMV0pO1xuICB9XG5cbiAgcmV0dXJuIF9ib3VuZGluZ0V4dGVudFhZcyh4cywgeXMsIG9wdF9leHRlbnQpO1xufVxuLyoqXG4gKiBNb2RpZmllcyB0aGUgcHJvdmlkZWQgZXh0ZW50IGluLXBsYWNlIHRvIGJlIHdpdGhpbiB0aGUgcmVhbCB3b3JsZFxuICogZXh0ZW50LlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb25cbiAqIEByZXR1cm4ge0V4dGVudH0gVGhlIGV4dGVudCB3aXRoaW4gdGhlIHJlYWwgd29ybGQgZXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwWChleHRlbnQsIHByb2plY3Rpb24pIHtcbiAgdmFyIHByb2plY3Rpb25FeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICB2YXIgY2VudGVyID0gZ2V0Q2VudGVyKGV4dGVudCk7XG5cbiAgaWYgKHByb2plY3Rpb24uY2FuV3JhcFgoKSAmJiAoY2VudGVyWzBdIDwgcHJvamVjdGlvbkV4dGVudFswXSB8fCBjZW50ZXJbMF0gPj0gcHJvamVjdGlvbkV4dGVudFsyXSkpIHtcbiAgICB2YXIgd29ybGRXaWR0aCA9IGdldFdpZHRoKHByb2plY3Rpb25FeHRlbnQpO1xuICAgIHZhciB3b3JsZHNBd2F5ID0gTWF0aC5mbG9vcigoY2VudGVyWzBdIC0gcHJvamVjdGlvbkV4dGVudFswXSkgLyB3b3JsZFdpZHRoKTtcbiAgICB2YXIgb2Zmc2V0ID0gd29ybGRzQXdheSAqIHdvcmxkV2lkdGg7XG4gICAgZXh0ZW50WzBdIC09IG9mZnNldDtcbiAgICBleHRlbnRbMl0gLT0gb2Zmc2V0O1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvbWF0aFxuICovXG5cbi8qKlxuICogVGFrZXMgYSBudW1iZXIgYW5kIGNsYW1wcyBpdCB0byB3aXRoaW4gdGhlIHByb3ZpZGVkIGJvdW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgaW5wdXQgbnVtYmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pbiBUaGUgbWluaW11bSB2YWx1ZSB0byByZXR1cm4uXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4IFRoZSBtYXhpbXVtIHZhbHVlIHRvIHJldHVybi5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGlucHV0IG51bWJlciBpZiBpdCBpcyB3aXRoaW4gYm91bmRzLCBvciB0aGUgbmVhcmVzdFxuICogICAgIG51bWJlciB3aXRoaW4gdGhlIGJvdW5kcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYW1wKHZhbHVlLCBtaW4sIG1heCkge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsIG1pbiksIG1heCk7XG59XG4vKipcbiAqIFJldHVybiB0aGUgaHlwZXJib2xpYyBjb3NpbmUgb2YgYSBnaXZlbiBudW1iZXIuIFRoZSBtZXRob2Qgd2lsbCB1c2UgdGhlXG4gKiBuYXRpdmUgYE1hdGguY29zaGAgZnVuY3Rpb24gaWYgaXQgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgdGhlIGh5cGVyYm9saWNcbiAqIGNvc2luZSB3aWxsIGJlIGNhbGN1bGF0ZWQgdmlhIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gb2YgdGhlIE1vemlsbGFcbiAqIGRldmVsb3BlciBuZXR3b3JrLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEh5cGVyYm9saWMgY29zaW5lIG9mIHguXG4gKi9cblxuZXhwb3J0IHZhciBjb3NoID0gZnVuY3Rpb24gKCkge1xuICAvLyBXcmFwcGVkIGluIGEgaWlmZSwgdG8gc2F2ZSB0aGUgb3ZlcmhlYWQgb2YgY2hlY2tpbmcgZm9yIHRoZSBuYXRpdmVcbiAgLy8gaW1wbGVtZW50YXRpb24gb24gZXZlcnkgaW52b2NhdGlvbi5cbiAgdmFyIGNvc2g7XG5cbiAgaWYgKCdjb3NoJyBpbiBNYXRoKSB7XG4gICAgLy8gVGhlIGVudmlyb25tZW50IHN1cHBvcnRzIHRoZSBuYXRpdmUgTWF0aC5jb3NoIGZ1bmN0aW9uLCB1c2UgaXTigKZcbiAgICBjb3NoID0gTWF0aC5jb3NoO1xuICB9IGVsc2Uge1xuICAgIC8vIOKApiBlbHNlLCB1c2UgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiBNRE46XG4gICAgY29zaCA9IGZ1bmN0aW9uIGNvc2goeCkge1xuICAgICAgdmFyIHkgPVxuICAgICAgLyoqIEB0eXBlIHtNYXRofSAqL1xuICAgICAgTWF0aC5leHAoeCk7XG4gICAgICByZXR1cm4gKHkgKyAxIC8geSkgLyAyO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gY29zaDtcbn0oKTtcbi8qKlxuICogUmV0dXJuIHRoZSBiYXNlIDIgbG9nYXJpdGhtIG9mIGEgZ2l2ZW4gbnVtYmVyLiBUaGUgbWV0aG9kIHdpbGwgdXNlIHRoZVxuICogbmF0aXZlIGBNYXRoLmxvZzJgIGZ1bmN0aW9uIGlmIGl0IGlzIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIHRoZSBiYXNlIDJcbiAqIGxvZ2FyaXRobSB3aWxsIGJlIGNhbGN1bGF0ZWQgdmlhIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gKiBNb3ppbGxhIGRldmVsb3BlciBuZXR3b3JrLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEJhc2UgMiBsb2dhcml0aG0gb2YgeC5cbiAqL1xuXG5leHBvcnQgdmFyIGxvZzIgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFdyYXBwZWQgaW4gYSBpaWZlLCB0byBzYXZlIHRoZSBvdmVyaGVhZCBvZiBjaGVja2luZyBmb3IgdGhlIG5hdGl2ZVxuICAvLyBpbXBsZW1lbnRhdGlvbiBvbiBldmVyeSBpbnZvY2F0aW9uLlxuICB2YXIgbG9nMjtcblxuICBpZiAoJ2xvZzInIGluIE1hdGgpIHtcbiAgICAvLyBUaGUgZW52aXJvbm1lbnQgc3VwcG9ydHMgdGhlIG5hdGl2ZSBNYXRoLmxvZzIgZnVuY3Rpb24sIHVzZSBpdOKAplxuICAgIGxvZzIgPSBNYXRoLmxvZzI7XG4gIH0gZWxzZSB7XG4gICAgLy8g4oCmIGVsc2UsIHVzZSB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIG9mIE1ETjpcbiAgICBsb2cyID0gZnVuY3Rpb24gbG9nMih4KSB7XG4gICAgICByZXR1cm4gTWF0aC5sb2coeCkgKiBNYXRoLkxPRzJFO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gbG9nMjtcbn0oKTtcbi8qKlxuICogUmV0dXJucyB0aGUgc3F1YXJlIG9mIHRoZSBjbG9zZXN0IGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50ICh4LCB5KSBhbmQgdGhlXG4gKiBsaW5lIHNlZ21lbnQgKHgxLCB5MSkgdG8gKHgyLCB5MikuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MSBYMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSBZMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiBYMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MiBZMi5cbiAqIEByZXR1cm4ge251bWJlcn0gU3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZFNlZ21lbnREaXN0YW5jZSh4LCB5LCB4MSwgeTEsIHgyLCB5Mikge1xuICB2YXIgZHggPSB4MiAtIHgxO1xuICB2YXIgZHkgPSB5MiAtIHkxO1xuXG4gIGlmIChkeCAhPT0gMCB8fCBkeSAhPT0gMCkge1xuICAgIHZhciB0ID0gKCh4IC0geDEpICogZHggKyAoeSAtIHkxKSAqIGR5KSAvIChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cbiAgICBpZiAodCA+IDEpIHtcbiAgICAgIHgxID0geDI7XG4gICAgICB5MSA9IHkyO1xuICAgIH0gZWxzZSBpZiAodCA+IDApIHtcbiAgICAgIHgxICs9IGR4ICogdDtcbiAgICAgIHkxICs9IGR5ICogdDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3F1YXJlZERpc3RhbmNlKHgsIHksIHgxLCB5MSk7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnRzICh4MSwgeTEpIGFuZCAoeDIsIHkyKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MSBYMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSBZMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiBYMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MiBZMi5cbiAqIEByZXR1cm4ge251bWJlcn0gU3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKHgxLCB5MSwgeDIsIHkyKSB7XG4gIHZhciBkeCA9IHgyIC0geDE7XG4gIHZhciBkeSA9IHkyIC0geTE7XG4gIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cbi8qKlxuICogU29sdmVzIHN5c3RlbSBvZiBsaW5lYXIgZXF1YXRpb25zIHVzaW5nIEdhdXNzaWFuIGVsaW1pbmF0aW9uIG1ldGhvZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBtYXQgQXVnbWVudGVkIG1hdHJpeCAobiB4IG4gKyAxIGNvbHVtbilcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHJvdy1tYWpvciBvcmRlci5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRoZSByZXN1bHRpbmcgdmVjdG9yLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzb2x2ZUxpbmVhclN5c3RlbShtYXQpIHtcbiAgdmFyIG4gPSBtYXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgLy8gRmluZCBtYXggaW4gdGhlIGktdGggY29sdW1uIChpZ25vcmluZyBpIC0gMSBmaXJzdCByb3dzKVxuICAgIHZhciBtYXhSb3cgPSBpO1xuICAgIHZhciBtYXhFbCA9IE1hdGguYWJzKG1hdFtpXVtpXSk7XG5cbiAgICBmb3IgKHZhciByID0gaSArIDE7IHIgPCBuOyByKyspIHtcbiAgICAgIHZhciBhYnNWYWx1ZSA9IE1hdGguYWJzKG1hdFtyXVtpXSk7XG5cbiAgICAgIGlmIChhYnNWYWx1ZSA+IG1heEVsKSB7XG4gICAgICAgIG1heEVsID0gYWJzVmFsdWU7XG4gICAgICAgIG1heFJvdyA9IHI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1heEVsID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDsgLy8gbWF0cml4IGlzIHNpbmd1bGFyXG4gICAgfSAvLyBTd2FwIG1heCByb3cgd2l0aCBpLXRoIChjdXJyZW50KSByb3dcblxuXG4gICAgdmFyIHRtcCA9IG1hdFttYXhSb3ddO1xuICAgIG1hdFttYXhSb3ddID0gbWF0W2ldO1xuICAgIG1hdFtpXSA9IHRtcDsgLy8gU3VidHJhY3QgdGhlIGktdGggcm93IHRvIG1ha2UgYWxsIHRoZSByZW1haW5pbmcgcm93cyAwIGluIHRoZSBpLXRoIGNvbHVtblxuXG4gICAgZm9yICh2YXIgaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7XG4gICAgICB2YXIgY29lZiA9IC1tYXRbal1baV0gLyBtYXRbaV1baV07XG5cbiAgICAgIGZvciAodmFyIGsgPSBpOyBrIDwgbiArIDE7IGsrKykge1xuICAgICAgICBpZiAoaSA9PSBrKSB7XG4gICAgICAgICAgbWF0W2pdW2tdID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXRbal1ba10gKz0gY29lZiAqIG1hdFtpXVtrXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSAvLyBTb2x2ZSBBeD1iIGZvciB1cHBlciB0cmlhbmd1bGFyIG1hdHJpeCBBIChtYXQpXG5cblxuICB2YXIgeCA9IG5ldyBBcnJheShuKTtcblxuICBmb3IgKHZhciBsID0gbiAtIDE7IGwgPj0gMDsgbC0tKSB7XG4gICAgeFtsXSA9IG1hdFtsXVtuXSAvIG1hdFtsXVtsXTtcblxuICAgIGZvciAodmFyIG0gPSBsIC0gMTsgbSA+PSAwOyBtLS0pIHtcbiAgICAgIG1hdFttXVtuXSAtPSBtYXRbbV1bbF0gKiB4W2xdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB4O1xufVxuLyoqXG4gKiBDb252ZXJ0cyByYWRpYW5zIHRvIHRvIGRlZ3JlZXMuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlSW5SYWRpYW5zIEFuZ2xlIGluIHJhZGlhbnMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIGluIGRlZ3JlZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRGVncmVlcyhhbmdsZUluUmFkaWFucykge1xuICByZXR1cm4gYW5nbGVJblJhZGlhbnMgKiAxODAgLyBNYXRoLlBJO1xufVxuLyoqXG4gKiBDb252ZXJ0cyBkZWdyZWVzIHRvIHJhZGlhbnMuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlSW5EZWdyZWVzIEFuZ2xlIGluIGRlZ3JlZXMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIGluIHJhZGlhbnMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvUmFkaWFucyhhbmdsZUluRGVncmVlcykge1xuICByZXR1cm4gYW5nbGVJbkRlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtb2R1bG8gb2YgYSAvIGIsIGRlcGVuZGluZyBvbiB0aGUgc2lnbiBvZiBiLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIERpdmlkZW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IGIgRGl2aXNvci5cbiAqIEByZXR1cm4ge251bWJlcn0gTW9kdWxvLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtb2R1bG8oYSwgYikge1xuICB2YXIgciA9IGEgJSBiO1xuICByZXR1cm4gciAqIGIgPCAwID8gciArIGIgOiByO1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsaW5lYXJseSBpbnRlcnBvbGF0ZWQgdmFsdWUgb2YgeCBiZXR3ZWVuIGEgYW5kIGIuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGEgTnVtYmVyXG4gKiBAcGFyYW0ge251bWJlcn0gYiBOdW1iZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFZhbHVlIHRvIGJlIGludGVycG9sYXRlZC5cbiAqIEByZXR1cm4ge251bWJlcn0gSW50ZXJwb2xhdGVkIHZhbHVlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsZXJwKGEsIGIsIHgpIHtcbiAgcmV0dXJuIGEgKyB4ICogKGIgLSBhKTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvY29sb3JcbiAqL1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi9tYXRoLmpzJztcbi8qKlxuICogQSBjb2xvciByZXByZXNlbnRlZCBhcyBhIHNob3J0IGFycmF5IFtyZWQsIGdyZWVuLCBibHVlLCBhbHBoYV0uXG4gKiByZWQsIGdyZWVuLCBhbmQgYmx1ZSBzaG91bGQgYmUgaW50ZWdlcnMgaW4gdGhlIHJhbmdlIDAuLjI1NSBpbmNsdXNpdmUuXG4gKiBhbHBoYSBzaG91bGQgYmUgYSBmbG9hdCBpbiB0aGUgcmFuZ2UgMC4uMSBpbmNsdXNpdmUuIElmIG5vIGFscGhhIHZhbHVlIGlzXG4gKiBnaXZlbiB0aGVuIGAxYCB3aWxsIGJlIHVzZWQuXG4gKiBAdHlwZWRlZiB7QXJyYXk8bnVtYmVyPn0gQ29sb3JcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIFRoaXMgUmVnRXhwIG1hdGNoZXMgIyBmb2xsb3dlZCBieSAzLCA0LCA2LCBvciA4IGhleCBkaWdpdHMuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtSZWdFeHB9XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBIRVhfQ09MT1JfUkVfID0gL14jKFthLWYwLTldezN9fFthLWYwLTldezR9KD86W2EtZjAtOV17Mn0pezAsMn0pJC9pO1xuLyoqXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gZm9yIG1hdGNoaW5nIHBvdGVudGlhbCBuYW1lZCBjb2xvciBzdHlsZSBzdHJpbmdzLlxuICogQGNvbnN0XG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQHByaXZhdGVcbiAqL1xuXG52YXIgTkFNRURfQ09MT1JfUkVfID0gL14oW2Etel0qKSR8XmhzbGE/XFwoLipcXCkkL2k7XG4vKipcbiAqIFJldHVybiB0aGUgY29sb3IgYXMgYW4gcmdiYSBzdHJpbmcuXG4gKiBAcGFyYW0ge0NvbG9yfHN0cmluZ30gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFJnYmEgc3RyaW5nLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhc1N0cmluZyhjb2xvcikge1xuICBpZiAodHlwZW9mIGNvbG9yID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBjb2xvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdG9TdHJpbmcoY29sb3IpO1xuICB9XG59XG4vKipcbiAqIFJldHVybiBuYW1lZCBjb2xvciBhcyBhbiByZ2JhIHN0cmluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2xvciBOYW1lZCBjb2xvci5cbiAqIEByZXR1cm4ge3N0cmluZ30gUmdiIHN0cmluZy5cbiAqL1xuXG5mdW5jdGlvbiBmcm9tTmFtZWQoY29sb3IpIHtcbiAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGVsLnN0eWxlLmNvbG9yID0gY29sb3I7XG5cbiAgaWYgKGVsLnN0eWxlLmNvbG9yICE9PSAnJykge1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWwpO1xuICAgIHZhciByZ2IgPSBnZXRDb21wdXRlZFN0eWxlKGVsKS5jb2xvcjtcbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGVsKTtcbiAgICByZXR1cm4gcmdiO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnJztcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcyBTdHJpbmcuXG4gKiBAcmV0dXJuIHtDb2xvcn0gQ29sb3IuXG4gKi9cblxuXG5leHBvcnQgdmFyIGZyb21TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFdlIG1haW50YWluIGEgc21hbGwgY2FjaGUgb2YgcGFyc2VkIHN0cmluZ3MuICBUbyBwcm92aWRlIGNoZWFwIExSVS1saWtlXG4gIC8vIHNlbWFudGljcywgd2hlbmV2ZXIgdGhlIGNhY2hlIGdyb3dzIHRvbyBsYXJnZSB3ZSBzaW1wbHkgZGVsZXRlIGFuXG4gIC8vIGFyYml0cmFyeSAyNSUgb2YgdGhlIGVudHJpZXMuXG5cbiAgLyoqXG4gICAqIEBjb25zdFxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKi9cbiAgdmFyIE1BWF9DQUNIRV9TSVpFID0gMTAyNDtcbiAgLyoqXG4gICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBDb2xvcj59XG4gICAqL1xuXG4gIHZhciBjYWNoZSA9IHt9O1xuICAvKipcbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG5cbiAgdmFyIGNhY2hlU2l6ZSA9IDA7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHMgU3RyaW5nLlxuICAgICAqIEByZXR1cm4ge0NvbG9yfSBDb2xvci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAocykge1xuICAgICAgdmFyIGNvbG9yO1xuXG4gICAgICBpZiAoY2FjaGUuaGFzT3duUHJvcGVydHkocykpIHtcbiAgICAgICAgY29sb3IgPSBjYWNoZVtzXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjYWNoZVNpemUgPj0gTUFYX0NBQ0hFX1NJWkUpIHtcbiAgICAgICAgICB2YXIgaSA9IDA7XG5cbiAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gY2FjaGUpIHtcbiAgICAgICAgICAgIGlmICgoaSsrICYgMykgPT09IDApIHtcbiAgICAgICAgICAgICAgZGVsZXRlIGNhY2hlW2tleV07XG4gICAgICAgICAgICAgIC0tY2FjaGVTaXplO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbG9yID0gZnJvbVN0cmluZ0ludGVybmFsXyhzKTtcbiAgICAgICAgY2FjaGVbc10gPSBjb2xvcjtcbiAgICAgICAgKytjYWNoZVNpemU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb2xvcjtcbiAgICB9XG4gICk7XG59KCk7XG4vKipcbiAqIFJldHVybiB0aGUgY29sb3IgYXMgYW4gYXJyYXkuIFRoaXMgZnVuY3Rpb24gbWFpbnRhaW5zIGEgY2FjaGUgb2YgY2FsY3VsYXRlZFxuICogYXJyYXlzIHdoaWNoIG1lYW5zIHRoZSByZXN1bHQgc2hvdWxkIG5vdCBiZSBtb2RpZmllZC5cbiAqIEBwYXJhbSB7Q29sb3J8c3RyaW5nfSBjb2xvciBDb2xvci5cbiAqIEByZXR1cm4ge0NvbG9yfSBDb2xvci5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXNBcnJheShjb2xvcikge1xuICBpZiAoQXJyYXkuaXNBcnJheShjb2xvcikpIHtcbiAgICByZXR1cm4gY29sb3I7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZyb21TdHJpbmcoY29sb3IpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzIFN0cmluZy5cbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJuIHtDb2xvcn0gQ29sb3IuXG4gKi9cblxuZnVuY3Rpb24gZnJvbVN0cmluZ0ludGVybmFsXyhzKSB7XG4gIHZhciByLCBnLCBiLCBhLCBjb2xvcjtcblxuICBpZiAoTkFNRURfQ09MT1JfUkVfLmV4ZWMocykpIHtcbiAgICBzID0gZnJvbU5hbWVkKHMpO1xuICB9XG5cbiAgaWYgKEhFWF9DT0xPUl9SRV8uZXhlYyhzKSkge1xuICAgIC8vIGhleFxuICAgIHZhciBuID0gcy5sZW5ndGggLSAxOyAvLyBudW1iZXIgb2YgaGV4IGRpZ2l0c1xuXG4gICAgdmFyIGQgPSAvLyBudW1iZXIgb2YgZGlnaXRzIHBlciBjaGFubmVsXG4gICAgdm9pZCAwOyAvLyBudW1iZXIgb2YgZGlnaXRzIHBlciBjaGFubmVsXG5cbiAgICBpZiAobiA8PSA0KSB7XG4gICAgICBkID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgZCA9IDI7XG4gICAgfVxuXG4gICAgdmFyIGhhc0FscGhhID0gbiA9PT0gNCB8fCBuID09PSA4O1xuICAgIHIgPSBwYXJzZUludChzLnN1YnN0cigxICsgMCAqIGQsIGQpLCAxNik7XG4gICAgZyA9IHBhcnNlSW50KHMuc3Vic3RyKDEgKyAxICogZCwgZCksIDE2KTtcbiAgICBiID0gcGFyc2VJbnQocy5zdWJzdHIoMSArIDIgKiBkLCBkKSwgMTYpO1xuXG4gICAgaWYgKGhhc0FscGhhKSB7XG4gICAgICBhID0gcGFyc2VJbnQocy5zdWJzdHIoMSArIDMgKiBkLCBkKSwgMTYpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhID0gMjU1O1xuICAgIH1cblxuICAgIGlmIChkID09IDEpIHtcbiAgICAgIHIgPSAociA8PCA0KSArIHI7XG4gICAgICBnID0gKGcgPDwgNCkgKyBnO1xuICAgICAgYiA9IChiIDw8IDQpICsgYjtcblxuICAgICAgaWYgKGhhc0FscGhhKSB7XG4gICAgICAgIGEgPSAoYSA8PCA0KSArIGE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29sb3IgPSBbciwgZywgYiwgYSAvIDI1NV07XG4gIH0gZWxzZSBpZiAocy5pbmRleE9mKCdyZ2JhKCcpID09IDApIHtcbiAgICAvLyByZ2JhKClcbiAgICBjb2xvciA9IHMuc2xpY2UoNSwgLTEpLnNwbGl0KCcsJykubWFwKE51bWJlcik7XG4gICAgbm9ybWFsaXplKGNvbG9yKTtcbiAgfSBlbHNlIGlmIChzLmluZGV4T2YoJ3JnYignKSA9PSAwKSB7XG4gICAgLy8gcmdiKClcbiAgICBjb2xvciA9IHMuc2xpY2UoNCwgLTEpLnNwbGl0KCcsJykubWFwKE51bWJlcik7XG4gICAgY29sb3IucHVzaCgxKTtcbiAgICBub3JtYWxpemUoY29sb3IpO1xuICB9IGVsc2Uge1xuICAgIGFzc2VydChmYWxzZSwgMTQpOyAvLyBJbnZhbGlkIGNvbG9yXG4gIH1cblxuICByZXR1cm4gY29sb3I7XG59XG4vKipcbiAqIFRPRE8gdGhpcyBmdW5jdGlvbiBpcyBvbmx5IHVzZWQgaW4gdGhlIHRlc3QsIHdlIHByb2JhYmx5IHNob3VsZG4ndCBleHBvcnQgaXRcbiAqIEBwYXJhbSB7Q29sb3J9IGNvbG9yIENvbG9yLlxuICogQHJldHVybiB7Q29sb3J9IENsYW1wZWQgY29sb3IuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKGNvbG9yKSB7XG4gIGNvbG9yWzBdID0gY2xhbXAoY29sb3JbMF0gKyAwLjUgfCAwLCAwLCAyNTUpO1xuICBjb2xvclsxXSA9IGNsYW1wKGNvbG9yWzFdICsgMC41IHwgMCwgMCwgMjU1KTtcbiAgY29sb3JbMl0gPSBjbGFtcChjb2xvclsyXSArIDAuNSB8IDAsIDAsIDI1NSk7XG4gIGNvbG9yWzNdID0gY2xhbXAoY29sb3JbM10sIDAsIDEpO1xuICByZXR1cm4gY29sb3I7XG59XG4vKipcbiAqIEBwYXJhbSB7Q29sb3J9IGNvbG9yIENvbG9yLlxuICogQHJldHVybiB7c3RyaW5nfSBTdHJpbmcuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbG9yKSB7XG4gIHZhciByID0gY29sb3JbMF07XG5cbiAgaWYgKHIgIT0gKHIgfCAwKSkge1xuICAgIHIgPSByICsgMC41IHwgMDtcbiAgfVxuXG4gIHZhciBnID0gY29sb3JbMV07XG5cbiAgaWYgKGcgIT0gKGcgfCAwKSkge1xuICAgIGcgPSBnICsgMC41IHwgMDtcbiAgfVxuXG4gIHZhciBiID0gY29sb3JbMl07XG5cbiAgaWYgKGIgIT0gKGIgfCAwKSkge1xuICAgIGIgPSBiICsgMC41IHwgMDtcbiAgfVxuXG4gIHZhciBhID0gY29sb3JbM10gPT09IHVuZGVmaW5lZCA/IDEgOiBjb2xvclszXTtcbiAgcmV0dXJuICdyZ2JhKCcgKyByICsgJywnICsgZyArICcsJyArIGIgKyAnLCcgKyBhICsgJyknO1xufVxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gcyBTdHJpbmcuXG4gKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBzdHJpbmcgaXMgYWN0dWFsbHkgYSB2YWxpZCBjb2xvclxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZ0NvbG9yKHMpIHtcbiAgaWYgKE5BTUVEX0NPTE9SX1JFXy50ZXN0KHMpKSB7XG4gICAgcyA9IGZyb21OYW1lZChzKTtcbiAgfVxuXG4gIHJldHVybiBIRVhfQ09MT1JfUkVfLnRlc3QocykgfHwgcy5pbmRleE9mKCdyZ2JhKCcpID09PSAwIHx8IHMuaW5kZXhPZigncmdiKCcpID09PSAwO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9JY29uSW1hZ2VDYWNoZVxuICovXG5pbXBvcnQgeyBhc1N0cmluZyB9IGZyb20gJy4uL2NvbG9yLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogU2luZ2xldG9uIGNsYXNzLiBBdmFpbGFibGUgdGhyb3VnaCB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL0ljb25JbWFnZUNhY2hlfnNoYXJlZH0uXG4gKi9cblxudmFyIEljb25JbWFnZUNhY2hlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gSWNvbkltYWdlQ2FjaGUoKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuL0ljb25JbWFnZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuY2FjaGVfID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy5jYWNoZVNpemVfID0gMDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLm1heENhY2hlU2l6ZV8gPSAzMjtcbiAgfVxuICAvKipcbiAgICogRklYTUUgZW1wdHkgZGVzY3JpcHRpb24gZm9yIGpzZG9jXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2FjaGVfID0ge307XG4gICAgdGhpcy5jYWNoZVNpemVfID0gMDtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENhbiBleHBpcmUgY2FjaGUuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlQ2FjaGUucHJvdG90eXBlLmNhbkV4cGlyZUNhY2hlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlU2l6ZV8gPiB0aGlzLm1heENhY2hlU2l6ZV87XG4gIH07XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBJY29uSW1hZ2VDYWNoZS5wcm90b3R5cGUuZXhwaXJlID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmNhbkV4cGlyZUNhY2hlKCkpIHtcbiAgICAgIHZhciBpID0gMDtcblxuICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMuY2FjaGVfKSB7XG4gICAgICAgIHZhciBpY29uSW1hZ2UgPSB0aGlzLmNhY2hlX1trZXldO1xuXG4gICAgICAgIGlmICgoaSsrICYgMykgPT09IDAgJiYgIWljb25JbWFnZS5oYXNMaXN0ZW5lcigpKSB7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuY2FjaGVfW2tleV07XG4gICAgICAgICAgLS10aGlzLmNhY2hlU2l6ZV87XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3JjIFNyYy5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9IGNvbG9yIENvbG9yLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0ljb25JbWFnZS5qc1wiKS5kZWZhdWx0fSBJY29uIGltYWdlLlxuICAgKi9cblxuXG4gIEljb25JbWFnZUNhY2hlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoc3JjLCBjcm9zc09yaWdpbiwgY29sb3IpIHtcbiAgICB2YXIga2V5ID0gZ2V0S2V5KHNyYywgY3Jvc3NPcmlnaW4sIGNvbG9yKTtcbiAgICByZXR1cm4ga2V5IGluIHRoaXMuY2FjaGVfID8gdGhpcy5jYWNoZV9ba2V5XSA6IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3JjIFNyYy5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9IGNvbG9yIENvbG9yLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vSWNvbkltYWdlLmpzXCIpLmRlZmF1bHR9IGljb25JbWFnZSBJY29uIGltYWdlLlxuICAgKi9cblxuXG4gIEljb25JbWFnZUNhY2hlLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoc3JjLCBjcm9zc09yaWdpbiwgY29sb3IsIGljb25JbWFnZSkge1xuICAgIHZhciBrZXkgPSBnZXRLZXkoc3JjLCBjcm9zc09yaWdpbiwgY29sb3IpO1xuICAgIHRoaXMuY2FjaGVfW2tleV0gPSBpY29uSW1hZ2U7XG4gICAgKyt0aGlzLmNhY2hlU2l6ZV87XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNhY2hlIHNpemUgb2YgdGhlIGljb24gY2FjaGUuIERlZmF1bHQgaXMgYDMyYC4gQ2hhbmdlIHRoaXMgdmFsdWUgd2hlblxuICAgKiB5b3VyIG1hcCB1c2VzIG1vcmUgdGhhbiAzMiBkaWZmZXJlbnQgaWNvbiBpbWFnZXMgYW5kIHlvdSBhcmUgbm90IGNhY2hpbmcgaWNvblxuICAgKiBzdHlsZXMgb24gdGhlIGFwcGxpY2F0aW9uIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FjaGVTaXplIENhY2hlIG1heCBzaXplLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlQ2FjaGUucHJvdG90eXBlLnNldFNpemUgPSBmdW5jdGlvbiAobWF4Q2FjaGVTaXplKSB7XG4gICAgdGhpcy5tYXhDYWNoZVNpemVfID0gbWF4Q2FjaGVTaXplO1xuICAgIHRoaXMuZXhwaXJlKCk7XG4gIH07XG5cbiAgcmV0dXJuIEljb25JbWFnZUNhY2hlO1xufSgpO1xuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3JjIFNyYy5cbiAqIEBwYXJhbSB7P3N0cmluZ30gY3Jvc3NPcmlnaW4gQ3Jvc3Mgb3JpZ2luLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcn0gY29sb3IgQ29sb3IuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IENhY2hlIGtleS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEtleShzcmMsIGNyb3NzT3JpZ2luLCBjb2xvcikge1xuICB2YXIgY29sb3JTdHJpbmcgPSBjb2xvciA/IGFzU3RyaW5nKGNvbG9yKSA6ICdudWxsJztcbiAgcmV0dXJuIGNyb3NzT3JpZ2luICsgJzonICsgc3JjICsgJzonICsgY29sb3JTdHJpbmc7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEljb25JbWFnZUNhY2hlO1xuLyoqXG4gKiBUaGUge0BsaW5rIG1vZHVsZTpvbC9zdHlsZS9JY29uSW1hZ2VDYWNoZX5JY29uSW1hZ2VDYWNoZX0gZm9yXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlL0ljb25+SWNvbn0gaW1hZ2VzLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgc2hhcmVkID0gbmV3IEljb25JbWFnZUNhY2hlKCk7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V2ZW50cy9FdmVudFxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogU3RyaXBwZWQgZG93biBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgVzNDIERPTSBMZXZlbCAyIEV2ZW50IGludGVyZmFjZS5cbiAqIFNlZSBodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTItRXZlbnRzL2V2ZW50cy5odG1sI0V2ZW50cy1pbnRlcmZhY2UuXG4gKlxuICogVGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHByb3ZpZGVzIGB0eXBlYCBhbmQgYHRhcmdldGAgcHJvcGVydGllcywgYW5kXG4gKiBgc3RvcFByb3BhZ2F0aW9uYCBhbmQgYHByZXZlbnREZWZhdWx0YCBtZXRob2RzLiBJdCBpcyBtZWFudCBhcyBiYXNlIGNsYXNzXG4gKiBmb3IgaGlnaGVyIGxldmVsIGV2ZW50cyBkZWZpbmVkIGluIHRoZSBsaWJyYXJ5LCBhbmQgd29ya3Mgd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvVGFyZ2V0flRhcmdldH0uXG4gKi9cbnZhciBCYXNlRXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICovXG4gIGZ1bmN0aW9uIEJhc2VFdmVudCh0eXBlKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5wcm9wYWdhdGlvblN0b3BwZWQ7XG4gICAgLyoqXG4gICAgICogVGhlIGV2ZW50IHR5cGUuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCB0YXJnZXQuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICB0aGlzLnRhcmdldCA9IG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIFN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlRXZlbnQucHJvdG90eXBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucHJvcGFnYXRpb25TdG9wcGVkID0gdHJ1ZTtcbiAgfTtcbiAgLyoqXG4gICAqIFN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlRXZlbnQucHJvdG90eXBlLnN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG4gIH07XG5cbiAgcmV0dXJuIEJhc2VFdmVudDtcbn0oKTtcbi8qKlxuICogQHBhcmFtIHtFdmVudHxpbXBvcnQoXCIuL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2dCBFdmVudFxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHN0b3BQcm9wYWdhdGlvbihldnQpIHtcbiAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V2ZW50fGltcG9ydChcIi4vRXZlbnQuanNcIikuZGVmYXVsdH0gZXZ0IEV2ZW50XG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHByZXZlbnREZWZhdWx0KGV2dCkge1xuICBldnQucHJldmVudERlZmF1bHQoKTtcbn1cbmV4cG9ydCBkZWZhdWx0IEJhc2VFdmVudDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvT2JqZWN0RXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIHByb3BlcnR5IGlzIGNoYW5nZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvT2JqZWN0Lk9iamVjdEV2ZW50I3Byb3BlcnR5Y2hhbmdlXG4gICAqIEBhcGlcbiAgICovXG4gIFBST1BFUlRZQ0hBTkdFOiAncHJvcGVydHljaGFuZ2UnXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9vYmpcbiAqL1xuXG4vKipcbiAqIFBvbHlmaWxsIGZvciBPYmplY3QuYXNzaWduKCkuICBBc3NpZ25zIGVudW1lcmFibGUgYW5kIG93biBwcm9wZXJ0aWVzIGZyb21cbiAqIG9uZSBvciBtb3JlIHNvdXJjZSBvYmplY3RzIHRvIGEgdGFyZ2V0IG9iamVjdC5cbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvYXNzaWduLlxuICpcbiAqIEBwYXJhbSB7IU9iamVjdH0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0LlxuICogQHBhcmFtIHsuLi5PYmplY3R9IHZhcl9zb3VyY2VzIFRoZSBzb3VyY2Ugb2JqZWN0KHMpLlxuICogQHJldHVybiB7IU9iamVjdH0gVGhlIG1vZGlmaWVkIHRhcmdldCBvYmplY3QuXG4gKi9cbmV4cG9ydCB2YXIgYXNzaWduID0gdHlwZW9mIE9iamVjdC5hc3NpZ24gPT09ICdmdW5jdGlvbicgPyBPYmplY3QuYXNzaWduIDogZnVuY3Rpb24gKHRhcmdldCwgdmFyX3NvdXJjZXMpIHtcbiAgaWYgKHRhcmdldCA9PT0gdW5kZWZpbmVkIHx8IHRhcmdldCA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHVuZGVmaW5lZCBvciBudWxsIHRvIG9iamVjdCcpO1xuICB9XG5cbiAgdmFyIG91dHB1dCA9IE9iamVjdCh0YXJnZXQpO1xuXG4gIGZvciAodmFyIGkgPSAxLCBpaSA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGlmIChzb3VyY2UgIT09IHVuZGVmaW5lZCAmJiBzb3VyY2UgIT09IG51bGwpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgb3V0cHV0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuLyoqXG4gKiBSZW1vdmVzIGFsbCBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNsZWFyLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhcihvYmplY3QpIHtcbiAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgZGVsZXRlIG9iamVjdFtwcm9wZXJ0eV07XG4gIH1cbn1cbi8qKlxuICogUG9seWZpbGwgZm9yIE9iamVjdC52YWx1ZXMoKS4gIEdldCBhbiBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMgZnJvbSBhbiBvYmplY3QuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L3ZhbHVlc1xuICpcbiAqIEBwYXJhbSB7IU9iamVjdDxLLFY+fSBvYmplY3QgVGhlIG9iamVjdCBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFsdWVzLlxuICogQHJldHVybiB7IUFycmF5PFY+fSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICogQHRlbXBsYXRlIEssVlxuICovXG5cbmV4cG9ydCB2YXIgZ2V0VmFsdWVzID0gdHlwZW9mIE9iamVjdC52YWx1ZXMgPT09ICdmdW5jdGlvbicgPyBPYmplY3QudmFsdWVzIDogZnVuY3Rpb24gKG9iamVjdCkge1xuICB2YXIgdmFsdWVzID0gW107XG5cbiAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgdmFsdWVzLnB1c2gob2JqZWN0W3Byb3BlcnR5XSk7XG4gIH1cblxuICByZXR1cm4gdmFsdWVzO1xufTtcbi8qKlxuICogRGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBoYXMgYW55IHByb3BlcnRpZXMuXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgb2JqZWN0IGlzIGVtcHR5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0VtcHR5KG9iamVjdCkge1xuICB2YXIgcHJvcGVydHk7XG5cbiAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gIXByb3BlcnR5O1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZXZlbnRzL1RhcmdldFxuICovXG5cblxuaW1wb3J0IERpc3Bvc2FibGUgZnJvbSAnLi4vRGlzcG9zYWJsZS5qcyc7XG5pbXBvcnQgRXZlbnQgZnJvbSAnLi9FdmVudC5qcyc7XG5pbXBvcnQgeyBWT0lEIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGNsZWFyIH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHR5cGVkZWYge0V2ZW50VGFyZ2V0fFRhcmdldH0gRXZlbnRUYXJnZXRMaWtlXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIHNpbXBsaWZpZWQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFczQyBET00gTGV2ZWwgMiBFdmVudFRhcmdldCBpbnRlcmZhY2UuXG4gKiBTZWUgaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDAvUkVDLURPTS1MZXZlbC0yLUV2ZW50cy0yMDAwMTExMy9ldmVudHMuaHRtbCNFdmVudHMtRXZlbnRUYXJnZXQuXG4gKlxuICogVGhlcmUgYXJlIHR3byBpbXBvcnRhbnQgc2ltcGxpZmljYXRpb25zIGNvbXBhcmVkIHRvIHRoZSBzcGVjaWZpY2F0aW9uOlxuICpcbiAqIDEuIFRoZSBoYW5kbGluZyBvZiBgdXNlQ2FwdHVyZWAgaW4gYGFkZEV2ZW50TGlzdGVuZXJgIGFuZFxuICogICAgYHJlbW92ZUV2ZW50TGlzdGVuZXJgLiBUaGVyZSBpcyBubyByZWFsIGNhcHR1cmUgbW9kZWwuXG4gKiAyLiBUaGUgaGFuZGxpbmcgb2YgYHN0b3BQcm9wYWdhdGlvbmAgYW5kIGBwcmV2ZW50RGVmYXVsdGAgb24gYGRpc3BhdGNoRXZlbnRgLlxuICogICAgVGhlcmUgaXMgbm8gZXZlbnQgdGFyZ2V0IGhpZXJhcmNoeS4gV2hlbiBhIGxpc3RlbmVyIGNhbGxzXG4gKiAgICBgc3RvcFByb3BhZ2F0aW9uYCBvciBgcHJldmVudERlZmF1bHRgIG9uIGFuIGV2ZW50IG9iamVjdCwgaXQgbWVhbnMgdGhhdCBub1xuICogICAgbW9yZSBsaXN0ZW5lcnMgYWZ0ZXIgdGhpcyBvbmUgd2lsbCBiZSBjYWxsZWQuIFNhbWUgYXMgd2hlbiB0aGUgbGlzdGVuZXJcbiAqICAgIHJldHVybnMgZmFsc2UuXG4gKi9cblxudmFyIFRhcmdldCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUYXJnZXQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0geyo9fSBvcHRfdGFyZ2V0IERlZmF1bHQgZXZlbnQgdGFyZ2V0IGZvciBkaXNwYXRjaGVkIGV2ZW50cy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUYXJnZXQob3B0X3RhcmdldCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Kn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZXZlbnRUYXJnZXRfID0gb3B0X3RhcmdldDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMucGVuZGluZ1JlbW92YWxzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgbnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRpc3BhdGNoaW5nXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkxpc3RlbmVyPj59XG4gICAgICovXG5cbiAgICBfdGhpcy5saXN0ZW5lcnNfID0gbnVsbDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkxpc3RlbmVyfSBsaXN0ZW5lciBMaXN0ZW5lci5cbiAgICovXG5cblxuICBUYXJnZXQucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIpIHtcbiAgICBpZiAoIXR5cGUgfHwgIWxpc3RlbmVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGxpc3RlbmVycyA9IHRoaXMubGlzdGVuZXJzXyB8fCAodGhpcy5saXN0ZW5lcnNfID0ge30pO1xuICAgIHZhciBsaXN0ZW5lcnNGb3JUeXBlID0gbGlzdGVuZXJzW3R5cGVdIHx8IChsaXN0ZW5lcnNbdHlwZV0gPSBbXSk7XG5cbiAgICBpZiAobGlzdGVuZXJzRm9yVHlwZS5pbmRleE9mKGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgIGxpc3RlbmVyc0ZvclR5cGUucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhbiBldmVudCBhbmQgY2FsbHMgYWxsIGxpc3RlbmVycyBsaXN0ZW5pbmcgZm9yIGV2ZW50c1xuICAgKiBvZiB0aGlzIHR5cGUuIFRoZSBldmVudCBwYXJhbWV0ZXIgY2FuIGVpdGhlciBiZSBhIHN0cmluZyBvciBhblxuICAgKiBPYmplY3Qgd2l0aCBhIGB0eXBlYCBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0V2ZW50LmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBldmVudCBFdmVudCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW58dW5kZWZpbmVkfSBgZmFsc2VgIGlmIGFueW9uZSBjYWxsZWQgcHJldmVudERlZmF1bHQgb24gdGhlXG4gICAqICAgICBldmVudCBvYmplY3Qgb3IgaWYgYW55IG9mIHRoZSBsaXN0ZW5lcnMgcmV0dXJuZWQgZmFsc2UuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUYXJnZXQucHJvdG90eXBlLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vRXZlbnQuanNcIikuZGVmYXVsdHxFdmVudH0gKi9cbiAgICB2YXIgZXZ0ID0gdHlwZW9mIGV2ZW50ID09PSAnc3RyaW5nJyA/IG5ldyBFdmVudChldmVudCkgOiBldmVudDtcbiAgICB2YXIgdHlwZSA9IGV2dC50eXBlO1xuXG4gICAgaWYgKCFldnQudGFyZ2V0KSB7XG4gICAgICBldnQudGFyZ2V0ID0gdGhpcy5ldmVudFRhcmdldF8gfHwgdGhpcztcbiAgICB9XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5saXN0ZW5lcnNfICYmIHRoaXMubGlzdGVuZXJzX1t0eXBlXTtcbiAgICB2YXIgcHJvcGFnYXRlO1xuXG4gICAgaWYgKGxpc3RlbmVycykge1xuICAgICAgdmFyIGRpc3BhdGNoaW5nID0gdGhpcy5kaXNwYXRjaGluZ18gfHwgKHRoaXMuZGlzcGF0Y2hpbmdfID0ge30pO1xuICAgICAgdmFyIHBlbmRpbmdSZW1vdmFscyA9IHRoaXMucGVuZGluZ1JlbW92YWxzXyB8fCAodGhpcy5wZW5kaW5nUmVtb3ZhbHNfID0ge30pO1xuXG4gICAgICBpZiAoISh0eXBlIGluIGRpc3BhdGNoaW5nKSkge1xuICAgICAgICBkaXNwYXRjaGluZ1t0eXBlXSA9IDA7XG4gICAgICAgIHBlbmRpbmdSZW1vdmFsc1t0eXBlXSA9IDA7XG4gICAgICB9XG5cbiAgICAgICsrZGlzcGF0Y2hpbmdbdHlwZV07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGlmICgnaGFuZGxlRXZlbnQnIGluIGxpc3RlbmVyc1tpXSkge1xuICAgICAgICAgIHByb3BhZ2F0ZSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuTGlzdGVuZXJPYmplY3R9ICovXG4gICAgICAgICAgbGlzdGVuZXJzW2ldLmhhbmRsZUV2ZW50KGV2dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvcGFnYXRlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5MaXN0ZW5lckZ1bmN0aW9ufSAqL1xuICAgICAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHRoaXMsIGV2dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcGFnYXRlID09PSBmYWxzZSB8fCBldnQucHJvcGFnYXRpb25TdG9wcGVkKSB7XG4gICAgICAgICAgcHJvcGFnYXRlID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLS1kaXNwYXRjaGluZ1t0eXBlXTtcblxuICAgICAgaWYgKGRpc3BhdGNoaW5nW3R5cGVdID09PSAwKSB7XG4gICAgICAgIHZhciBwciA9IHBlbmRpbmdSZW1vdmFsc1t0eXBlXTtcbiAgICAgICAgZGVsZXRlIHBlbmRpbmdSZW1vdmFsc1t0eXBlXTtcblxuICAgICAgICB3aGlsZSAocHItLSkge1xuICAgICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBWT0lEKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSBkaXNwYXRjaGluZ1t0eXBlXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHByb3BhZ2F0ZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBDbGVhbiB1cC5cbiAgICovXG5cblxuICBUYXJnZXQucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmxpc3RlbmVyc18gJiYgY2xlYXIodGhpcy5saXN0ZW5lcnNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbGlzdGVuZXJzIGZvciBhIHNwZWNpZmllZCBldmVudCB0eXBlLiBMaXN0ZW5lcnMgYXJlIHJldHVybmVkIGluIHRoZVxuICAgKiBvcmRlciB0aGF0IHRoZXkgd2lsbCBiZSBjYWxsZWQgaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5MaXN0ZW5lcj58dW5kZWZpbmVkfSBMaXN0ZW5lcnMuXG4gICAqL1xuXG5cbiAgVGFyZ2V0LnByb3RvdHlwZS5nZXRMaXN0ZW5lcnMgPSBmdW5jdGlvbiAodHlwZSkge1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyc18gJiYgdGhpcy5saXN0ZW5lcnNfW3R5cGVdIHx8IHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X3R5cGUgVHlwZS4gSWYgbm90IHByb3ZpZGVkLFxuICAgKiAgICAgYHRydWVgIHdpbGwgYmUgcmV0dXJuZWQgaWYgdGhpcyBldmVudCB0YXJnZXQgaGFzIGFueSBsaXN0ZW5lcnMuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEhhcyBsaXN0ZW5lcnMuXG4gICAqL1xuXG5cbiAgVGFyZ2V0LnByb3RvdHlwZS5oYXNMaXN0ZW5lciA9IGZ1bmN0aW9uIChvcHRfdHlwZSkge1xuICAgIGlmICghdGhpcy5saXN0ZW5lcnNfKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdF90eXBlID8gb3B0X3R5cGUgaW4gdGhpcy5saXN0ZW5lcnNfIDogT2JqZWN0LmtleXModGhpcy5saXN0ZW5lcnNfKS5sZW5ndGggPiAwO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9ldmVudHMuanNcIikuTGlzdGVuZXJ9IGxpc3RlbmVyIExpc3RlbmVyLlxuICAgKi9cblxuXG4gIFRhcmdldC5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikge1xuICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmxpc3RlbmVyc18gJiYgdGhpcy5saXN0ZW5lcnNfW3R5cGVdO1xuXG4gICAgaWYgKGxpc3RlbmVycykge1xuICAgICAgdmFyIGluZGV4ID0gbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuXG4gICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgIGlmICh0aGlzLnBlbmRpbmdSZW1vdmFsc18gJiYgdHlwZSBpbiB0aGlzLnBlbmRpbmdSZW1vdmFsc18pIHtcbiAgICAgICAgICAvLyBtYWtlIGxpc3RlbmVyIGEgbm8tb3AsIGFuZCByZW1vdmUgbGF0ZXIgaW4gI2Rpc3BhdGNoRXZlbnQoKVxuICAgICAgICAgIGxpc3RlbmVyc1tpbmRleF0gPSBWT0lEO1xuICAgICAgICAgICsrdGhpcy5wZW5kaW5nUmVtb3ZhbHNfW3R5cGVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpc3RlbmVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgICAgICAgaWYgKGxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmxpc3RlbmVyc19bdHlwZV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBUYXJnZXQ7XG59KERpc3Bvc2FibGUpO1xuXG5leHBvcnQgZGVmYXVsdCBUYXJnZXQ7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V2ZW50cy9FdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAY29uc3RcbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogR2VuZXJpYyBjaGFuZ2UgZXZlbnQuIFRyaWdnZXJlZCB3aGVuIHRoZSByZXZpc2lvbiBjb3VudGVyIGlzIGluY3JlYXNlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9ldmVudHMvRXZlbnR+QmFzZUV2ZW50I2NoYW5nZVxuICAgKiBAYXBpXG4gICAqL1xuICBDSEFOR0U6ICdjaGFuZ2UnLFxuXG4gIC8qKlxuICAgKiBHZW5lcmljIGVycm9yIGV2ZW50LiBUcmlnZ2VyZWQgd2hlbiBhbiBlcnJvciBvY2N1cnMuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvZXZlbnRzL0V2ZW50fkJhc2VFdmVudCNlcnJvclxuICAgKiBAYXBpXG4gICAqL1xuICBFUlJPUjogJ2Vycm9yJyxcbiAgQkxVUjogJ2JsdXInLFxuICBDTEVBUjogJ2NsZWFyJyxcbiAgQ09OVEVYVE1FTlU6ICdjb250ZXh0bWVudScsXG4gIENMSUNLOiAnY2xpY2snLFxuICBEQkxDTElDSzogJ2RibGNsaWNrJyxcbiAgRFJBR0VOVEVSOiAnZHJhZ2VudGVyJyxcbiAgRFJBR09WRVI6ICdkcmFnb3ZlcicsXG4gIERST1A6ICdkcm9wJyxcbiAgRk9DVVM6ICdmb2N1cycsXG4gIEtFWURPV046ICdrZXlkb3duJyxcbiAgS0VZUFJFU1M6ICdrZXlwcmVzcycsXG4gIExPQUQ6ICdsb2FkJyxcbiAgUkVTSVpFOiAncmVzaXplJyxcbiAgVE9VQ0hNT1ZFOiAndG91Y2htb3ZlJyxcbiAgV0hFRUw6ICd3aGVlbCdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2V2ZW50c1xuICovXG5pbXBvcnQgeyBjbGVhciB9IGZyb20gJy4vb2JqLmpzJztcbi8qKlxuICogS2V5IHRvIHVzZSB3aXRoIHtAbGluayBtb2R1bGU6b2wvT2JzZXJ2YWJsZX5PYnNlcnZhYmxlI3VuQnlLZXl9LlxuICogQHR5cGVkZWYge09iamVjdH0gRXZlbnRzS2V5XG4gKiBAcHJvcGVydHkge0xpc3RlbmVyRnVuY3Rpb259IGxpc3RlbmVyXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vZXZlbnRzL1RhcmdldC5qc1wiKS5FdmVudFRhcmdldExpa2V9IHRhcmdldFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHR5cGVcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIExpc3RlbmVyIGZ1bmN0aW9uLiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFuIGV2ZW50IG9iamVjdCBhcyBhcmd1bWVudC5cbiAqIFdoZW4gdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYCwgZXZlbnQgcHJvcGFnYXRpb24gd2lsbCBzdG9wLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbigoRXZlbnR8aW1wb3J0KFwiLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdCkpOiAodm9pZHxib29sZWFuKX0gTGlzdGVuZXJGdW5jdGlvblxuICogQGFwaVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTGlzdGVuZXJPYmplY3RcbiAqIEBwcm9wZXJ0eSB7TGlzdGVuZXJGdW5jdGlvbn0gaGFuZGxlRXZlbnRcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtMaXN0ZW5lckZ1bmN0aW9ufExpc3RlbmVyT2JqZWN0fSBMaXN0ZW5lclxuICovXG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyIG9uIGFuIGV2ZW50IHRhcmdldC4gSW5zcGlyZWQgYnlcbiAqIGh0dHBzOi8vZ29vZ2xlLmdpdGh1Yi5pby9jbG9zdXJlLWxpYnJhcnkvYXBpL3NvdXJjZS9jbG9zdXJlL2dvb2cvZXZlbnRzL2V2ZW50cy5qcy5zcmMuaHRtbFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gZWZmaWNpZW50bHkgYmluZHMgYSBgbGlzdGVuZXJgIHRvIGEgYHRoaXNgIG9iamVjdCwgYW5kIHJldHVybnNcbiAqIGEga2V5IGZvciB1c2Ugd2l0aCB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50c351bmxpc3RlbkJ5S2V5fS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXZlbnRzL1RhcmdldC5qc1wiKS5FdmVudFRhcmdldExpa2V9IHRhcmdldCBFdmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBFdmVudCB0eXBlLlxuICogQHBhcmFtIHtMaXN0ZW5lckZ1bmN0aW9ufSBsaXN0ZW5lciBMaXN0ZW5lci5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0X3RoaXMgT2JqZWN0IHJlZmVyZW5jZWQgYnkgdGhlIGB0aGlzYCBrZXl3b3JkIGluIHRoZVxuICogICAgIGxpc3RlbmVyLiBEZWZhdWx0IGlzIHRoZSBgdGFyZ2V0YC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9vbmNlIElmIHRydWUsIGFkZCB0aGUgbGlzdGVuZXIgYXMgb25lLW9mZiBsaXN0ZW5lci5cbiAqIEByZXR1cm4ge0V2ZW50c0tleX0gVW5pcXVlIGtleSBmb3IgdGhlIGxpc3RlbmVyLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW4odGFyZ2V0LCB0eXBlLCBfbGlzdGVuZXIsIG9wdF90aGlzLCBvcHRfb25jZSkge1xuICBpZiAob3B0X3RoaXMgJiYgb3B0X3RoaXMgIT09IHRhcmdldCkge1xuICAgIF9saXN0ZW5lciA9IF9saXN0ZW5lci5iaW5kKG9wdF90aGlzKTtcbiAgfVxuXG4gIGlmIChvcHRfb25jZSkge1xuICAgIHZhciBvcmlnaW5hbExpc3RlbmVyXzEgPSBfbGlzdGVuZXI7XG5cbiAgICBfbGlzdGVuZXIgPSBmdW5jdGlvbiBsaXN0ZW5lcigpIHtcbiAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIF9saXN0ZW5lcik7XG4gICAgICBvcmlnaW5hbExpc3RlbmVyXzEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9O1xuICB9XG5cbiAgdmFyIGV2ZW50c0tleSA9IHtcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICB0eXBlOiB0eXBlLFxuICAgIGxpc3RlbmVyOiBfbGlzdGVuZXJcbiAgfTtcbiAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgX2xpc3RlbmVyKTtcbiAgcmV0dXJuIGV2ZW50c0tleTtcbn1cbi8qKlxuICogUmVnaXN0ZXJzIGEgb25lLW9mZiBldmVudCBsaXN0ZW5lciBvbiBhbiBldmVudCB0YXJnZXQuIEluc3BpcmVkIGJ5XG4gKiBodHRwczovL2dvb2dsZS5naXRodWIuaW8vY2xvc3VyZS1saWJyYXJ5L2FwaS9zb3VyY2UvY2xvc3VyZS9nb29nL2V2ZW50cy9ldmVudHMuanMuc3JjLmh0bWxcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGVmZmljaWVudGx5IGJpbmRzIGEgYGxpc3RlbmVyYCBhcyBzZWxmLXVucmVnaXN0ZXJpbmcgbGlzdGVuZXJcbiAqIHRvIGEgYHRoaXNgIG9iamVjdCwgYW5kIHJldHVybnMgYSBrZXkgZm9yIHVzZSB3aXRoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50c351bmxpc3RlbkJ5S2V5fSBpbiBjYXNlIHRoZSBsaXN0ZW5lciBuZWVkcyB0byBiZVxuICogdW5yZWdpc3RlcmVkIGJlZm9yZSBpdCBpcyBjYWxsZWQuXG4gKlxuICogV2hlbiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50c35saXN0ZW59IGlzIGNhbGxlZCB3aXRoIHRoZSBzYW1lIGFyZ3VtZW50cyBhZnRlciB0aGlzXG4gKiBmdW5jdGlvbiwgdGhlIHNlbGYtdW5yZWdpc3RlcmluZyBsaXN0ZW5lciB3aWxsIGJlIHR1cm5lZCBpbnRvIGEgcGVybWFuZW50XG4gKiBsaXN0ZW5lci5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXZlbnRzL1RhcmdldC5qc1wiKS5FdmVudFRhcmdldExpa2V9IHRhcmdldCBFdmVudCB0YXJnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBFdmVudCB0eXBlLlxuICogQHBhcmFtIHtMaXN0ZW5lckZ1bmN0aW9ufSBsaXN0ZW5lciBMaXN0ZW5lci5cbiAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0X3RoaXMgT2JqZWN0IHJlZmVyZW5jZWQgYnkgdGhlIGB0aGlzYCBrZXl3b3JkIGluIHRoZVxuICogICAgIGxpc3RlbmVyLiBEZWZhdWx0IGlzIHRoZSBgdGFyZ2V0YC5cbiAqIEByZXR1cm4ge0V2ZW50c0tleX0gS2V5IGZvciB1bmxpc3RlbkJ5S2V5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW5PbmNlKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIsIG9wdF90aGlzKSB7XG4gIHJldHVybiBsaXN0ZW4odGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgb3B0X3RoaXMsIHRydWUpO1xufVxuLyoqXG4gKiBVbnJlZ2lzdGVycyBldmVudCBsaXN0ZW5lcnMgb24gYW4gZXZlbnQgdGFyZ2V0LiBJbnNwaXJlZCBieVxuICogaHR0cHM6Ly9nb29nbGUuZ2l0aHViLmlvL2Nsb3N1cmUtbGlicmFyeS9hcGkvc291cmNlL2Nsb3N1cmUvZ29vZy9ldmVudHMvZXZlbnRzLmpzLnNyYy5odG1sXG4gKlxuICogVGhlIGFyZ3VtZW50IHBhc3NlZCB0byB0aGlzIGZ1bmN0aW9uIGlzIHRoZSBrZXkgcmV0dXJuZWQgZnJvbVxuICoge0BsaW5rIG1vZHVsZTpvbC9ldmVudHN+bGlzdGVufSBvciB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50c35saXN0ZW5PbmNlfS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50c0tleX0ga2V5IFRoZSBrZXkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVubGlzdGVuQnlLZXkoa2V5KSB7XG4gIGlmIChrZXkgJiYga2V5LnRhcmdldCkge1xuICAgIGtleS50YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihrZXkudHlwZSwga2V5Lmxpc3RlbmVyKTtcbiAgICBjbGVhcihrZXkpO1xuICB9XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9PYnNlcnZhYmxlXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudHMvVGFyZ2V0LmpzJztcbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IGxpc3RlbiwgbGlzdGVuT25jZSwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4vZXZlbnRzLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogQW4gZXZlbnQgdGFyZ2V0IHByb3ZpZGluZyBjb252ZW5pZW50IG1ldGhvZHMgZm9yIGxpc3RlbmVyIHJlZ2lzdHJhdGlvblxuICogYW5kIHVucmVnaXN0cmF0aW9uLiBBIGdlbmVyaWMgYGNoYW5nZWAgZXZlbnQgaXMgYWx3YXlzIGF2YWlsYWJsZSB0aHJvdWdoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL09ic2VydmFibGV+T2JzZXJ2YWJsZSNjaGFuZ2VkfS5cbiAqXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdFxuICogQGFwaVxuICovXG5cbnZhciBPYnNlcnZhYmxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE9ic2VydmFibGUsIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gT2JzZXJ2YWJsZSgpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMucmV2aXNpb25fID0gMDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEluY3JlYXNlcyB0aGUgcmV2aXNpb24gY291bnRlciBhbmQgZGlzcGF0Y2hlcyBhICdjaGFuZ2UnIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT2JzZXJ2YWJsZS5wcm90b3R5cGUuY2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICArK3RoaXMucmV2aXNpb25fO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChFdmVudFR5cGUuQ0hBTkdFKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmVyc2lvbiBudW1iZXIgZm9yIHRoaXMgb2JqZWN0LiAgRWFjaCB0aW1lIHRoZSBvYmplY3QgaXMgbW9kaWZpZWQsXG4gICAqIGl0cyB2ZXJzaW9uIG51bWJlciB3aWxsIGJlIGluY3JlbWVudGVkLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFJldmlzaW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT2JzZXJ2YWJsZS5wcm90b3R5cGUuZ2V0UmV2aXNpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmV2aXNpb25fO1xuICB9O1xuICAvKipcbiAgICogTGlzdGVuIGZvciBhIGNlcnRhaW4gdHlwZSBvZiBldmVudC5cbiAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gdHlwZSBUaGUgZXZlbnQgdHlwZSBvciBhcnJheSBvZiBldmVudCB0eXBlcy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbig/KTogP30gbGlzdGVuZXIgVGhlIGxpc3RlbmVyIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl8QXJyYXk8aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn0gVW5pcXVlIGtleSBmb3IgdGhlIGxpc3RlbmVyLiBJZlxuICAgKiAgICAgY2FsbGVkIHdpdGggYW4gYXJyYXkgb2YgZXZlbnQgdHlwZXMgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCB0aGUgcmV0dXJuXG4gICAqICAgICB3aWxsIGJlIGFuIGFycmF5IG9mIGtleXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPYnNlcnZhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGUpKSB7XG4gICAgICB2YXIgbGVuID0gdHlwZS5sZW5ndGg7XG4gICAgICB2YXIga2V5cyA9IG5ldyBBcnJheShsZW4pO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGtleXNbaV0gPSBsaXN0ZW4odGhpcywgdHlwZVtpXSwgbGlzdGVuZXIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ga2V5cztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGxpc3Rlbih0aGlzLFxuICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICB0eXBlLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogTGlzdGVuIG9uY2UgZm9yIGEgY2VydGFpbiB0eXBlIG9mIGV2ZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheTxzdHJpbmc+fSB0eXBlIFRoZSBldmVudCB0eXBlIG9yIGFycmF5IG9mIGV2ZW50IHR5cGVzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKD8pOiA/fSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleXxBcnJheTxpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fSBVbmlxdWUga2V5IGZvciB0aGUgbGlzdGVuZXIuIElmXG4gICAqICAgICBjYWxsZWQgd2l0aCBhbiBhcnJheSBvZiBldmVudCB0eXBlcyBhcyB0aGUgZmlyc3QgYXJndW1lbnQsIHRoZSByZXR1cm5cbiAgICogICAgIHdpbGwgYmUgYW4gYXJyYXkgb2Yga2V5cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE9ic2VydmFibGUucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiAodHlwZSwgbGlzdGVuZXIpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICAgIHZhciBsZW4gPSB0eXBlLmxlbmd0aDtcbiAgICAgIGtleSA9IG5ldyBBcnJheShsZW4pO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGtleVtpXSA9IGxpc3Rlbk9uY2UodGhpcywgdHlwZVtpXSwgbGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBrZXkgPSBsaXN0ZW5PbmNlKHRoaXMsXG4gICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgIHR5cGUsIGxpc3RlbmVyKTtcbiAgICB9XG4gICAgLyoqIEB0eXBlIHtPYmplY3R9ICovXG5cblxuICAgIGxpc3RlbmVyLm9sX2tleSA9IGtleTtcbiAgICByZXR1cm4ga2V5O1xuICB9O1xuICAvKipcbiAgICogVW5saXN0ZW4gZm9yIGEgY2VydGFpbiB0eXBlIG9mIGV2ZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheTxzdHJpbmc+fSB0eXBlIFRoZSBldmVudCB0eXBlIG9yIGFycmF5IG9mIGV2ZW50IHR5cGVzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKD8pOiA/fSBsaXN0ZW5lciBUaGUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPYnNlcnZhYmxlLnByb3RvdHlwZS51biA9IGZ1bmN0aW9uICh0eXBlLCBsaXN0ZW5lcikge1xuICAgIHZhciBrZXkgPVxuICAgIC8qKiBAdHlwZSB7T2JqZWN0fSAqL1xuICAgIGxpc3RlbmVyLm9sX2tleTtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgIHVuQnlLZXkoa2V5KTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHR5cGUubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZVtpXSwgbGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gT2JzZXJ2YWJsZTtcbn0oRXZlbnRUYXJnZXQpO1xuLyoqXG4gKiBSZW1vdmVzIGFuIGV2ZW50IGxpc3RlbmVyIHVzaW5nIHRoZSBrZXkgcmV0dXJuZWQgYnkgYG9uKClgIG9yIGBvbmNlKClgLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl8QXJyYXk8aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5Pn0ga2V5IFRoZSBrZXkgcmV0dXJuZWQgYnkgYG9uKClgXG4gKiAgICAgb3IgYG9uY2UoKWAgKG9yIGFuIGFycmF5IG9mIGtleXMpLlxuICogQGFwaVxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHVuQnlLZXkoa2V5KSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGtleSkpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBrZXkubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdW5saXN0ZW5CeUtleShrZXlbaV0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB1bmxpc3RlbkJ5S2V5KFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fSAqL1xuICAgIGtleSk7XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IE9ic2VydmFibGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9PYmplY3RcbiAqL1xuXG5cbmltcG9ydCBFdmVudCBmcm9tICcuL2V2ZW50cy9FdmVudC5qcyc7XG5pbXBvcnQgT2JqZWN0RXZlbnRUeXBlIGZyb20gJy4vT2JqZWN0RXZlbnRUeXBlLmpzJztcbmltcG9ydCBPYnNlcnZhYmxlIGZyb20gJy4vT2JzZXJ2YWJsZS5qcyc7XG5pbXBvcnQgeyBhc3NpZ24sIGlzRW1wdHkgfSBmcm9tICcuL29iai5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuL3V0aWwuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH5CYXNlT2JqZWN0fSBpbnN0YW5jZXMgYXJlIGluc3RhbmNlcyBvZiB0aGlzIHR5cGUuXG4gKi9cblxudmFyIE9iamVjdEV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE9iamVjdEV2ZW50LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgVGhlIGV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHByb3BlcnR5IG5hbWUuXG4gICAqIEBwYXJhbSB7Kn0gb2xkVmFsdWUgVGhlIG9sZCB2YWx1ZSBmb3IgYGtleWAuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gT2JqZWN0RXZlbnQodHlwZSwga2V5LCBvbGRWYWx1ZSkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHR5cGUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IHdob3NlIHZhbHVlIGlzIGNoYW5naW5nLlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5rZXkgPSBrZXk7XG4gICAgLyoqXG4gICAgICogVGhlIG9sZCB2YWx1ZS4gVG8gZ2V0IHRoZSBuZXcgdmFsdWUgdXNlIGBlLnRhcmdldC5nZXQoZS5rZXkpYCB3aGVyZVxuICAgICAqIGBlYCBpcyB0aGUgZXZlbnQgb2JqZWN0LlxuICAgICAqIEB0eXBlIHsqfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdEV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCB7IE9iamVjdEV2ZW50IH07XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIE1vc3Qgbm9uLXRyaXZpYWwgY2xhc3NlcyBpbmhlcml0IGZyb20gdGhpcy5cbiAqXG4gKiBUaGlzIGV4dGVuZHMge0BsaW5rIG1vZHVsZTpvbC9PYnNlcnZhYmxlfSB3aXRoIG9ic2VydmFibGVcbiAqIHByb3BlcnRpZXMsIHdoZXJlIGVhY2ggcHJvcGVydHkgaXMgb2JzZXJ2YWJsZSBhcyB3ZWxsIGFzIHRoZSBvYmplY3QgYXMgYVxuICogd2hvbGUuXG4gKlxuICogQ2xhc3NlcyB0aGF0IGluaGVyaXQgZnJvbSB0aGlzIGhhdmUgcHJlLWRlZmluZWQgcHJvcGVydGllcywgdG8gd2hpY2ggeW91IGNhblxuICogYWRkIHlvdXIgb3ducy4gVGhlIHByZS1kZWZpbmVkIHByb3BlcnRpZXMgYXJlIGxpc3RlZCBpbiB0aGlzIGRvY3VtZW50YXRpb24gYXNcbiAqICdPYnNlcnZhYmxlIFByb3BlcnRpZXMnLCBhbmQgaGF2ZSB0aGVpciBvd24gYWNjZXNzb3JzOyBmb3IgZXhhbXBsZSxcbiAqIHtAbGluayBtb2R1bGU6b2wvTWFwfk1hcH0gaGFzIGEgYHRhcmdldGAgcHJvcGVydHksIGFjY2Vzc2VkIHdpdGhcbiAqIGBnZXRUYXJnZXQoKWAgYW5kIGNoYW5nZWQgd2l0aCBgc2V0VGFyZ2V0KClgLiBOb3QgYWxsIHByb3BlcnRpZXMgYXJlIGhvd2V2ZXJcbiAqIHNldHRhYmxlLiBUaGVyZSBhcmUgYWxzbyBnZW5lcmFsLXB1cnBvc2UgYWNjZXNzb3JzIGBnZXQoKWAgYW5kIGBzZXQoKWAuIEZvclxuICogZXhhbXBsZSwgYGdldCgndGFyZ2V0JylgIGlzIGVxdWl2YWxlbnQgdG8gYGdldFRhcmdldCgpYC5cbiAqXG4gKiBUaGUgYHNldGAgYWNjZXNzb3JzIHRyaWdnZXIgYSBjaGFuZ2UgZXZlbnQsIGFuZCB5b3UgY2FuIG1vbml0b3IgdGhpcyBieVxuICogcmVnaXN0ZXJpbmcgYSBsaXN0ZW5lci4gRm9yIGV4YW1wbGUsIHtAbGluayBtb2R1bGU6b2wvVmlld35WaWV3fSBoYXMgYVxuICogYGNlbnRlcmAgcHJvcGVydHksIHNvIGB2aWV3Lm9uKCdjaGFuZ2U6Y2VudGVyJywgZnVuY3Rpb24oZXZ0KSB7Li4ufSk7YCB3b3VsZFxuICogY2FsbCB0aGUgZnVuY3Rpb24gd2hlbmV2ZXIgdGhlIHZhbHVlIG9mIHRoZSBjZW50ZXIgcHJvcGVydHkgY2hhbmdlcy4gV2l0aGluXG4gKiB0aGUgZnVuY3Rpb24sIGBldnQudGFyZ2V0YCB3b3VsZCBiZSB0aGUgdmlldywgc28gYGV2dC50YXJnZXQuZ2V0Q2VudGVyKClgXG4gKiB3b3VsZCByZXR1cm4gdGhlIG5ldyBjZW50ZXIuXG4gKlxuICogWW91IGNhbiBhZGQgeW91ciBvd24gb2JzZXJ2YWJsZSBwcm9wZXJ0aWVzIHdpdGhcbiAqIGBvYmplY3Quc2V0KCdwcm9wJywgJ3ZhbHVlJylgLCBhbmQgcmV0cmlldmUgdGhhdCB3aXRoIGBvYmplY3QuZ2V0KCdwcm9wJylgLlxuICogWW91IGNhbiBsaXN0ZW4gZm9yIGNoYW5nZXMgb24gdGhhdCBwcm9wZXJ0eSB2YWx1ZSB3aXRoXG4gKiBgb2JqZWN0Lm9uKCdjaGFuZ2U6cHJvcCcsIGxpc3RlbmVyKWAuIFlvdSBjYW4gZ2V0IGEgbGlzdCBvZiBhbGxcbiAqIHByb3BlcnRpZXMgd2l0aCB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH5CYXNlT2JqZWN0I2dldFByb3BlcnRpZXN9LlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgb2JzZXJ2YWJsZSBwcm9wZXJ0aWVzIGFyZSBzZXBhcmF0ZSBmcm9tIHN0YW5kYXJkIEpTIHByb3BlcnRpZXMuXG4gKiBZb3UgY2FuLCBmb3IgZXhhbXBsZSwgZ2l2ZSB5b3VyIG1hcCBvYmplY3QgYSB0aXRsZSB3aXRoXG4gKiBgbWFwLnRpdGxlPSdOZXcgdGl0bGUnYCBhbmQgd2l0aCBgbWFwLnNldCgndGl0bGUnLCAnQW5vdGhlciB0aXRsZScpYC4gVGhlXG4gKiBmaXJzdCB3aWxsIGJlIGEgYGhhc093blByb3BlcnR5YDsgdGhlIHNlY29uZCB3aWxsIGFwcGVhciBpblxuICogYGdldFByb3BlcnRpZXMoKWAuIE9ubHkgdGhlIHNlY29uZCBpcyBvYnNlcnZhYmxlLlxuICpcbiAqIFByb3BlcnRpZXMgY2FuIGJlIGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHVuc2V0IG1ldGhvZC4gRS5nLlxuICogb2JqZWN0LnVuc2V0KCdmb28nKS5cbiAqXG4gKiBAZmlyZXMgT2JqZWN0RXZlbnRcbiAqIEBhcGlcbiAqL1xuXG52YXIgQmFzZU9iamVjdCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhCYXNlT2JqZWN0LCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCAqPj19IG9wdF92YWx1ZXMgQW4gb2JqZWN0IHdpdGgga2V5LXZhbHVlIHBhaXJzLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEJhc2VPYmplY3Qob3B0X3ZhbHVlcykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7IC8vIENhbGwge0BsaW5rIG1vZHVsZTpvbC91dGlsfmdldFVpZH0gdG8gZW5zdXJlIHRoYXQgdGhlIG9yZGVyIG9mIG9iamVjdHMnIGlkcyBpc1xuICAgIC8vIHRoZSBzYW1lIGFzIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdlcmUgY3JlYXRlZC4gIFRoaXMgYWxzbyBoZWxwcyB0b1xuICAgIC8vIGVuc3VyZSB0aGF0IG9iamVjdCBwcm9wZXJ0aWVzIGFyZSBhbHdheXMgYWRkZWQgaW4gdGhlIHNhbWUgb3JkZXIsIHdoaWNoXG4gICAgLy8gaGVscHMgbWFueSBKYXZhU2NyaXB0IGVuZ2luZXMgZ2VuZXJhdGUgZmFzdGVyIGNvZGUuXG5cblxuICAgIGdldFVpZChfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgKj59XG4gICAgICovXG5cbiAgICBfdGhpcy52YWx1ZXNfID0gbnVsbDtcblxuICAgIGlmIChvcHRfdmFsdWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIF90aGlzLnNldFByb3BlcnRpZXMob3B0X3ZhbHVlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBHZXRzIGEgdmFsdWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEByZXR1cm4geyp9IFZhbHVlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZU9iamVjdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciB2YWx1ZTtcblxuICAgIGlmICh0aGlzLnZhbHVlc18gJiYgdGhpcy52YWx1ZXNfLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIHZhbHVlID0gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBvYmplY3QgcHJvcGVydHkgbmFtZXMuXG4gICAqIEByZXR1cm4ge0FycmF5PHN0cmluZz59IExpc3Qgb2YgcHJvcGVydHkgbmFtZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5nZXRLZXlzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc18gJiYgT2JqZWN0LmtleXModGhpcy52YWx1ZXNfKSB8fCBbXTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbiBvYmplY3Qgb2YgYWxsIHByb3BlcnR5IG5hbWVzIGFuZCB2YWx1ZXMuXG4gICAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsICo+fSBPYmplY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5nZXRQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlc18gJiYgYXNzaWduKHt9LCB0aGlzLnZhbHVlc18pIHx8IHt9O1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIG9iamVjdCBoYXMgcHJvcGVydGllcy5cbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5oYXNQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIXRoaXMudmFsdWVzXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gICAqIEBwYXJhbSB7Kn0gb2xkVmFsdWUgT2xkIHZhbHVlLlxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLm5vdGlmeSA9IGZ1bmN0aW9uIChrZXksIG9sZFZhbHVlKSB7XG4gICAgdmFyIGV2ZW50VHlwZTtcbiAgICBldmVudFR5cGUgPSBnZXRDaGFuZ2VFdmVudFR5cGUoa2V5KTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IE9iamVjdEV2ZW50KGV2ZW50VHlwZSwga2V5LCBvbGRWYWx1ZSkpO1xuICAgIGV2ZW50VHlwZSA9IE9iamVjdEV2ZW50VHlwZS5QUk9QRVJUWUNIQU5HRTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IE9iamVjdEV2ZW50KGV2ZW50VHlwZSwga2V5LCBvbGRWYWx1ZSkpO1xuICB9O1xuICAvKipcbiAgICogU2V0cyBhIHZhbHVlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2lsZW50IFVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgYW4gZXZlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlT2JqZWN0LnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSwgb3B0X3NpbGVudCkge1xuICAgIHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlc18gfHwgKHRoaXMudmFsdWVzXyA9IHt9KTtcblxuICAgIGlmIChvcHRfc2lsZW50KSB7XG4gICAgICB2YWx1ZXNba2V5XSA9IHZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgb2xkVmFsdWUgPSB2YWx1ZXNba2V5XTtcbiAgICAgIHZhbHVlc1trZXldID0gdmFsdWU7XG5cbiAgICAgIGlmIChvbGRWYWx1ZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgdGhpcy5ub3RpZnkoa2V5LCBvbGRWYWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0cyBhIGNvbGxlY3Rpb24gb2Yga2V5LXZhbHVlIHBhaXJzLiAgTm90ZSB0aGF0IHRoaXMgY2hhbmdlcyBhbnkgZXhpc3RpbmdcbiAgICogcHJvcGVydGllcyBhbmQgYWRkcyBuZXcgb25lcyAoaXQgZG9lcyBub3QgcmVtb3ZlIGFueSBleGlzdGluZyBwcm9wZXJ0aWVzKS5cbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCAqPn0gdmFsdWVzIFZhbHVlcy5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3NpbGVudCBVcGRhdGUgd2l0aG91dCB0cmlnZ2VyaW5nIGFuIGV2ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZU9iamVjdC5wcm90b3R5cGUuc2V0UHJvcGVydGllcyA9IGZ1bmN0aW9uICh2YWx1ZXMsIG9wdF9zaWxlbnQpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gdmFsdWVzKSB7XG4gICAgICB0aGlzLnNldChrZXksIHZhbHVlc1trZXldLCBvcHRfc2lsZW50KTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBBcHBseSBhbnkgcHJvcGVydGllcyBmcm9tIGFub3RoZXIgb2JqZWN0IHdpdGhvdXQgdHJpZ2dlcmluZyBldmVudHMuXG4gICAqIEBwYXJhbSB7QmFzZU9iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQmFzZU9iamVjdC5wcm90b3R5cGUuYXBwbHlQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgIGlmICghc291cmNlLnZhbHVlc18pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhc3NpZ24odGhpcy52YWx1ZXNfIHx8ICh0aGlzLnZhbHVlc18gPSB7fSksIHNvdXJjZS52YWx1ZXNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIFVuc2V0cyBhIHByb3BlcnR5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleSBuYW1lLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2lsZW50IFVuc2V0IHdpdGhvdXQgdHJpZ2dlcmluZyBhbiBldmVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VPYmplY3QucHJvdG90eXBlLnVuc2V0ID0gZnVuY3Rpb24gKGtleSwgb3B0X3NpbGVudCkge1xuICAgIGlmICh0aGlzLnZhbHVlc18gJiYga2V5IGluIHRoaXMudmFsdWVzXykge1xuICAgICAgdmFyIG9sZFZhbHVlID0gdGhpcy52YWx1ZXNfW2tleV07XG4gICAgICBkZWxldGUgdGhpcy52YWx1ZXNfW2tleV07XG5cbiAgICAgIGlmIChpc0VtcHR5KHRoaXMudmFsdWVzXykpIHtcbiAgICAgICAgdGhpcy52YWx1ZXNfID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFvcHRfc2lsZW50KSB7XG4gICAgICAgIHRoaXMubm90aWZ5KGtleSwgb2xkVmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gQmFzZU9iamVjdDtcbn0oT2JzZXJ2YWJsZSk7XG4vKipcbiAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBzdHJpbmc+fVxuICovXG5cblxudmFyIGNoYW5nZUV2ZW50VHlwZUNhY2hlID0ge307XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5IG5hbWUuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IENoYW5nZSBuYW1lLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFuZ2VFdmVudFR5cGUoa2V5KSB7XG4gIHJldHVybiBjaGFuZ2VFdmVudFR5cGVDYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpID8gY2hhbmdlRXZlbnRUeXBlQ2FjaGVba2V5XSA6IGNoYW5nZUV2ZW50VHlwZUNhY2hlW2tleV0gPSAnY2hhbmdlOicgKyBrZXk7XG59XG5leHBvcnQgZGVmYXVsdCBCYXNlT2JqZWN0OyIsIi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9Qcm9wZXJ0eVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBPUEFDSVRZOiAnb3BhY2l0eScsXG4gIFZJU0lCTEU6ICd2aXNpYmxlJyxcbiAgRVhURU5UOiAnZXh0ZW50JyxcbiAgWl9JTkRFWDogJ3pJbmRleCcsXG4gIE1BWF9SRVNPTFVUSU9OOiAnbWF4UmVzb2x1dGlvbicsXG4gIE1JTl9SRVNPTFVUSU9OOiAnbWluUmVzb2x1dGlvbicsXG4gIE1BWF9aT09NOiAnbWF4Wm9vbScsXG4gIE1JTl9aT09NOiAnbWluWm9vbScsXG4gIFNPVVJDRTogJ3NvdXJjZSdcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9CYXNlXG4gKi9cblxuXG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuLi9PYmplY3QuanMnO1xuaW1wb3J0IExheWVyUHJvcGVydHkgZnJvbSAnLi9Qcm9wZXJ0eS5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWxheWVyJ10gQSBDU1MgY2xhc3MgbmFtZSB0byBzZXQgdG8gdGhlIGxheWVyIGVsZW1lbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSAoMCwgMSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt2aXNpYmxlPXRydWVdIFZpc2liaWxpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBib3VuZGluZyBleHRlbnQgZm9yIGxheWVyIHJlbmRlcmluZy4gIFRoZSBsYXllciB3aWxsIG5vdCBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGlzIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBUaGUgei1pbmRleCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgQXQgcmVuZGVyaW5nIHRpbWUsIHRoZSBsYXllcnNcbiAqIHdpbGwgYmUgb3JkZXJlZCwgZmlyc3QgYnkgWi1pbmRleCBhbmQgdGhlbiBieSBwb3NpdGlvbi4gV2hlbiBgdW5kZWZpbmVkYCwgYSBgekluZGV4YCBvZiAwIGlzIGFzc3VtZWRcbiAqIGZvciBsYXllcnMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIG1hcCdzIGBsYXllcnNgIGNvbGxlY3Rpb24sIG9yIGBJbmZpbml0eWAgd2hlbiB0aGUgbGF5ZXIncyBgc2V0TWFwKClgXG4gKiBtZXRob2Qgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIChleGNsdXNpdmUpIGJlbG93IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIE5vdGUgdGhhdCB3aXRoIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvQmFzZX0gYW5kIGFsbCBpdHMgc3ViY2xhc3NlcywgYW55IHByb3BlcnR5IHNldCBpblxuICogdGhlIG9wdGlvbnMgaXMgc2V0IGFzIGEge0BsaW5rIG1vZHVsZTpvbC9PYmplY3R9IHByb3BlcnR5IG9uIHRoZSBsYXllciBvYmplY3QsIHNvXG4gKiBpcyBvYnNlcnZhYmxlLCBhbmQgaGFzIGdldC9zZXQgYWNjZXNzb3JzLlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgQmFzZUxheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEJhc2VMYXllciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBMYXllciBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEJhc2VMYXllcihvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgKj59XG4gICAgICovXG5cblxuICAgIHZhciBwcm9wZXJ0aWVzID0gYXNzaWduKHt9LCBvcHRpb25zKTtcbiAgICBwcm9wZXJ0aWVzW0xheWVyUHJvcGVydHkuT1BBQ0lUWV0gPSBvcHRpb25zLm9wYWNpdHkgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMub3BhY2l0eSA6IDE7XG4gICAgYXNzZXJ0KHR5cGVvZiBwcm9wZXJ0aWVzW0xheWVyUHJvcGVydHkuT1BBQ0lUWV0gPT09ICdudW1iZXInLCA2NCk7IC8vIExheWVyIG9wYWNpdHkgbXVzdCBiZSBhIG51bWJlclxuXG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5LlZJU0lCTEVdID0gb3B0aW9ucy52aXNpYmxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnZpc2libGUgOiB0cnVlO1xuICAgIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5aX0lOREVYXSA9IG9wdGlvbnMuekluZGV4O1xuICAgIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5NQVhfUkVTT0xVVElPTl0gPSBvcHRpb25zLm1heFJlc29sdXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWF4UmVzb2x1dGlvbiA6IEluZmluaXR5O1xuICAgIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5NSU5fUkVTT0xVVElPTl0gPSBvcHRpb25zLm1pblJlc29sdXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWluUmVzb2x1dGlvbiA6IDA7XG4gICAgcHJvcGVydGllc1tMYXllclByb3BlcnR5Lk1JTl9aT09NXSA9IG9wdGlvbnMubWluWm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5taW5ab29tIDogLUluZmluaXR5O1xuICAgIHByb3BlcnRpZXNbTGF5ZXJQcm9wZXJ0eS5NQVhfWk9PTV0gPSBvcHRpb25zLm1heFpvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubWF4Wm9vbSA6IEluZmluaXR5O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmNsYXNzTmFtZV8gPSBwcm9wZXJ0aWVzLmNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbGFzc05hbWUgOiAnb2wtbGF5ZXInO1xuICAgIGRlbGV0ZSBwcm9wZXJ0aWVzLmNsYXNzTmFtZTtcblxuICAgIF90aGlzLnNldFByb3BlcnRpZXMocHJvcGVydGllcyk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGV9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuc3RhdGVfID0gbnVsbDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQ1NTIGNsYXNzIG5hbWUuXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRDbGFzc05hbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xhc3NOYW1lXztcbiAgfTtcbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGlzIG5vdCBtZWFudCB0byBiZSBjYWxsZWQgYnkgbGF5ZXJzIG9yIGxheWVyIHJlbmRlcmVycyBiZWNhdXNlIHRoZSBzdGF0ZVxuICAgKiBpcyBpbmNvcnJlY3QgaWYgdGhlIGxheWVyIGlzIGluY2x1ZGVkIGluIGEgbGF5ZXIgZ3JvdXAuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9tYW5hZ2VkIExheWVyIGlzIG1hbmFnZWQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGV9IExheWVyIHN0YXRlLlxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJTdGF0ZSA9IGZ1bmN0aW9uIChvcHRfbWFuYWdlZCkge1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZX0gKi9cbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlXyB8fFxuICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICB7XG4gICAgICBsYXllcjogdGhpcyxcbiAgICAgIG1hbmFnZWQ6IG9wdF9tYW5hZ2VkID09PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0X21hbmFnZWRcbiAgICB9O1xuICAgIHZhciB6SW5kZXggPSB0aGlzLmdldFpJbmRleCgpO1xuICAgIHN0YXRlLm9wYWNpdHkgPSBjbGFtcChNYXRoLnJvdW5kKHRoaXMuZ2V0T3BhY2l0eSgpICogMTAwKSAvIDEwMCwgMCwgMSk7XG4gICAgc3RhdGUuc291cmNlU3RhdGUgPSB0aGlzLmdldFNvdXJjZVN0YXRlKCk7XG4gICAgc3RhdGUudmlzaWJsZSA9IHRoaXMuZ2V0VmlzaWJsZSgpO1xuICAgIHN0YXRlLmV4dGVudCA9IHRoaXMuZ2V0RXh0ZW50KCk7XG4gICAgc3RhdGUuekluZGV4ID0gekluZGV4ICE9PSB1bmRlZmluZWQgPyB6SW5kZXggOiBzdGF0ZS5tYW5hZ2VkID09PSBmYWxzZSA/IEluZmluaXR5IDogMDtcbiAgICBzdGF0ZS5tYXhSZXNvbHV0aW9uID0gdGhpcy5nZXRNYXhSZXNvbHV0aW9uKCk7XG4gICAgc3RhdGUubWluUmVzb2x1dGlvbiA9IE1hdGgubWF4KHRoaXMuZ2V0TWluUmVzb2x1dGlvbigpLCAwKTtcbiAgICBzdGF0ZS5taW5ab29tID0gdGhpcy5nZXRNaW5ab29tKCk7XG4gICAgc3RhdGUubWF4Wm9vbSA9IHRoaXMuZ2V0TWF4Wm9vbSgpO1xuICAgIHRoaXMuc3RhdGVfID0gc3RhdGU7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5kZWZhdWx0Pj19IG9wdF9hcnJheSBBcnJheSBvZiBsYXllcnMgKHRvIGJlXG4gICAqICAgICBtb2RpZmllZCBpbiBwbGFjZSkuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdD59IEFycmF5IG9mIGxheWVycy5cbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldExheWVyc0FycmF5ID0gZnVuY3Rpb24gKG9wdF9hcnJheSkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZT49fSBvcHRfc3RhdGVzIE9wdGlvbmFsIGxpc3Qgb2YgbGF5ZXJcbiAgICogICAgIHN0YXRlcyAodG8gYmUgbW9kaWZpZWQgaW4gcGxhY2UpLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlPn0gTGlzdCBvZiBsYXllciBzdGF0ZXMuXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRMYXllclN0YXRlc0FycmF5ID0gZnVuY3Rpb24gKG9wdF9zdGF0ZXMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUge0BsaW5rIG1vZHVsZTpvbC9leHRlbnR+RXh0ZW50IGV4dGVudH0gb2YgdGhlIGxheWVyIG9yIGB1bmRlZmluZWRgIGlmIGl0XG4gICAqIHdpbGwgYmUgdmlzaWJsZSByZWdhcmRsZXNzIG9mIGV4dGVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudHx1bmRlZmluZWR9IFRoZSBsYXllciBleHRlbnQuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuRVhURU5UKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIG1heGltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1heGltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldE1heFJlc29sdXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5NQVhfUkVTT0xVVElPTilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBtaW5pbXVtIHJlc29sdXRpb24gb2YgdGhlIGxheWVyLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtaW5pbXVtIHJlc29sdXRpb24gb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5nZXRNaW5SZXNvbHV0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuTUlOX1JFU09MVVRJT04pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbWluaW11bSB6b29tIGxldmVsIG9mIHRoZSBsYXllci5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbWluaW11bSB6b29tIGxldmVsIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0TWluWm9vbSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChMYXllclByb3BlcnR5Lk1JTl9aT09NKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIG1heGltdW0gem9vbSBsZXZlbCBvZiB0aGUgbGF5ZXIuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG1heGltdW0gem9vbSBsZXZlbCBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldE1heFpvb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5NQVhfWk9PTSlcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBvcGFjaXR5IG9mIHRoZSBsYXllciAoYmV0d2VlbiAwIGFuZCAxKS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgb3BhY2l0eSBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldE9wYWNpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoTGF5ZXJQcm9wZXJ0eS5PUEFDSVRZKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc291cmNlL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFNvdXJjZSBzdGF0ZS5cbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldFNvdXJjZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBsYXllciAoYHRydWVgIG9yIGBmYWxzZWApLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdmlzaWJpbGl0eSBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmdldFZpc2libGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuVklTSUJMRSlcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBaLWluZGV4IG9mIHRoZSBsYXllciwgd2hpY2ggaXMgdXNlZCB0byBvcmRlciBsYXllcnMgYmVmb3JlXG4gICAqIHJlbmRlcmluZy4gVGhlIGRlZmF1bHQgWi1pbmRleCBpcyAwLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBaLWluZGV4IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuZ2V0WkluZGV4ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0KExheWVyUHJvcGVydHkuWl9JTkRFWClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBleHRlbnQgYXQgd2hpY2ggdGhlIGxheWVyIGlzIHZpc2libGUuICBJZiBgdW5kZWZpbmVkYCwgdGhlIGxheWVyXG4gICAqIHdpbGwgYmUgdmlzaWJsZSBhdCBhbGwgZXh0ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fHVuZGVmaW5lZH0gZXh0ZW50IFRoZSBleHRlbnQgb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5zZXRFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5FWFRFTlQsIGV4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG1heGltdW0gcmVzb2x1dGlvbiBhdCB3aGljaCB0aGUgbGF5ZXIgaXMgdmlzaWJsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1heFJlc29sdXRpb24gVGhlIG1heGltdW0gcmVzb2x1dGlvbiBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldE1heFJlc29sdXRpb24gPSBmdW5jdGlvbiAobWF4UmVzb2x1dGlvbikge1xuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuTUFYX1JFU09MVVRJT04sIG1heFJlc29sdXRpb24pO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBtaW5pbXVtIHJlc29sdXRpb24gYXQgd2hpY2ggdGhlIGxheWVyIGlzIHZpc2libGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5SZXNvbHV0aW9uIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gb2YgdGhlIGxheWVyLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQmFzZUxheWVyLnByb3RvdHlwZS5zZXRNaW5SZXNvbHV0aW9uID0gZnVuY3Rpb24gKG1pblJlc29sdXRpb24pIHtcbiAgICB0aGlzLnNldChMYXllclByb3BlcnR5Lk1JTl9SRVNPTFVUSU9OLCBtaW5SZXNvbHV0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbWF4aW11bSB6b29tIChleGNsdXNpdmUpIGF0IHdoaWNoIHRoZSBsYXllciBpcyB2aXNpYmxlLlxuICAgKiBOb3RlIHRoYXQgdGhlIHpvb20gbGV2ZWxzIGZvciBsYXllciB2aXNpYmlsaXR5IGFyZSBiYXNlZCBvbiB0aGVcbiAgICogdmlldyB6b29tIGxldmVsLCB3aGljaCBtYXkgYmUgZGlmZmVyZW50IGZyb20gYSB0aWxlIHNvdXJjZSB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Wm9vbSBUaGUgbWF4aW11bSB6b29tIG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0TWF4Wm9vbSA9IGZ1bmN0aW9uIChtYXhab29tKSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5NQVhfWk9PTSwgbWF4Wm9vbSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG1pbmltdW0gem9vbSAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGUgbGF5ZXIgaXMgdmlzaWJsZS5cbiAgICogTm90ZSB0aGF0IHRoZSB6b29tIGxldmVscyBmb3IgbGF5ZXIgdmlzaWJpbGl0eSBhcmUgYmFzZWQgb24gdGhlXG4gICAqIHZpZXcgem9vbSBsZXZlbCwgd2hpY2ggbWF5IGJlIGRpZmZlcmVudCBmcm9tIGEgdGlsZSBzb3VyY2Ugem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblpvb20gVGhlIG1pbmltdW0gem9vbSBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldE1pblpvb20gPSBmdW5jdGlvbiAobWluWm9vbSkge1xuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuTUlOX1pPT00sIG1pblpvb20pO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBvcGFjaXR5IG9mIHRoZSBsYXllciwgYWxsb3dlZCB2YWx1ZXMgcmFuZ2UgZnJvbSAwIHRvIDEuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IFRoZSBvcGFjaXR5IG9mIHRoZSBsYXllci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VMYXllci5wcm90b3R5cGUuc2V0T3BhY2l0eSA9IGZ1bmN0aW9uIChvcGFjaXR5KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBvcGFjaXR5ID09PSAnbnVtYmVyJywgNjQpOyAvLyBMYXllciBvcGFjaXR5IG11c3QgYmUgYSBudW1iZXJcblxuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuT1BBQ0lUWSwgb3BhY2l0eSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGxheWVyIChgdHJ1ZWAgb3IgYGZhbHNlYCkuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdmlzaWJsZSBUaGUgdmlzaWJpbGl0eSBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldFZpc2libGUgPSBmdW5jdGlvbiAodmlzaWJsZSkge1xuICAgIHRoaXMuc2V0KExheWVyUHJvcGVydHkuVklTSUJMRSwgdmlzaWJsZSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgWi1pbmRleCBvZiB0aGUgbGF5ZXIsIHdoaWNoIGlzIHVzZWQgdG8gb3JkZXIgbGF5ZXJzIGJlZm9yZSByZW5kZXJpbmcuXG4gICAqIFRoZSBkZWZhdWx0IFotaW5kZXggaXMgMC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHppbmRleCBUaGUgei1pbmRleCBvZiB0aGUgbGF5ZXIuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLnNldFpJbmRleCA9IGZ1bmN0aW9uICh6aW5kZXgpIHtcbiAgICB0aGlzLnNldChMYXllclByb3BlcnR5LlpfSU5ERVgsIHppbmRleCk7XG4gIH07XG4gIC8qKlxuICAgKiBDbGVhbiB1cC5cbiAgICovXG5cblxuICBCYXNlTGF5ZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZV8pIHtcbiAgICAgIHRoaXMuc3RhdGVfLmxheWVyID0gbnVsbDtcbiAgICAgIHRoaXMuc3RhdGVfID0gbnVsbDtcbiAgICB9XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICB9O1xuXG4gIHJldHVybiBCYXNlTGF5ZXI7XG59KEJhc2VPYmplY3QpO1xuXG5leHBvcnQgZGVmYXVsdCBCYXNlTGF5ZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9FdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFRyaWdnZXJlZCBiZWZvcmUgYSBsYXllciBpcyByZW5kZXJlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9yZW5kZXIvRXZlbnR+UmVuZGVyRXZlbnQjcHJlcmVuZGVyXG4gICAqIEBhcGlcbiAgICovXG4gIFBSRVJFTkRFUjogJ3ByZXJlbmRlcicsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCBhZnRlciBhIGxheWVyIGlzIHJlbmRlcmVkLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudCNwb3N0cmVuZGVyXG4gICAqIEBhcGlcbiAgICovXG4gIFBPU1RSRU5ERVI6ICdwb3N0cmVuZGVyJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIGJlZm9yZSBsYXllcnMgYXJlIHJlbmRlcmVkLlxuICAgKiBUaGUgZXZlbnQgb2JqZWN0IHdpbGwgbm90IGhhdmUgYSBgY29udGV4dGAgc2V0LlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudCNwcmVjb21wb3NlXG4gICAqIEBhcGlcbiAgICovXG4gIFBSRUNPTVBPU0U6ICdwcmVjb21wb3NlJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIGFmdGVyIGFsbCBsYXllcnMgYXJlIHJlbmRlcmVkLlxuICAgKiBUaGUgZXZlbnQgb2JqZWN0IHdpbGwgbm90IGhhdmUgYSBgY29udGV4dGAgc2V0LlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudCNwb3N0Y29tcG9zZVxuICAgKiBAYXBpXG4gICAqL1xuICBQT1NUQ09NUE9TRTogJ3Bvc3Rjb21wb3NlJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gcmVuZGVyaW5nIGlzIGNvbXBsZXRlLCBpLmUuIGFsbCBzb3VyY2VzIGFuZCB0aWxlcyBoYXZlXG4gICAqIGZpbmlzaGVkIGxvYWRpbmcgZm9yIHRoZSBjdXJyZW50IHZpZXdwb3J0LCBhbmQgYWxsIHRpbGVzIGFyZSBmYWRlZCBpbi5cbiAgICogVGhlIGV2ZW50IG9iamVjdCB3aWxsIG5vdCBoYXZlIGEgYGNvbnRleHRgIHNldC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9yZW5kZXIvRXZlbnR+UmVuZGVyRXZlbnQjcmVuZGVyY29tcGxldGVcbiAgICogQGFwaVxuICAgKi9cbiAgUkVOREVSQ09NUExFVEU6ICdyZW5kZXJjb21wbGV0ZSdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9TdGF0ZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqIFN0YXRlIG9mIHRoZSBzb3VyY2UsIG9uZSBvZiAndW5kZWZpbmVkJywgJ2xvYWRpbmcnLCAncmVhZHknIG9yICdlcnJvcicuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgVU5ERUZJTkVEOiAndW5kZWZpbmVkJyxcbiAgTE9BRElORzogJ2xvYWRpbmcnLFxuICBSRUFEWTogJ3JlYWR5JyxcbiAgRVJST1I6ICdlcnJvcidcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9MYXllclxuICovXG5cblxuaW1wb3J0IEJhc2VMYXllciBmcm9tICcuL0Jhc2UuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBMYXllclByb3BlcnR5IGZyb20gJy4vUHJvcGVydHkuanMnO1xuaW1wb3J0IFJlbmRlckV2ZW50VHlwZSBmcm9tICcuLi9yZW5kZXIvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBTb3VyY2VTdGF0ZSBmcm9tICcuLi9zb3VyY2UvU3RhdGUuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgZ2V0Q2hhbmdlRXZlbnRUeXBlIH0gZnJvbSAnLi4vT2JqZWN0LmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4uL2V2ZW50cy5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZSk6SFRNTEVsZW1lbnR9IFJlbmRlckZ1bmN0aW9uXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtbGF5ZXInXSBBIENTUyBjbGFzcyBuYW1lIHRvIHNldCB0byB0aGUgbGF5ZXIgZWxlbWVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb3BhY2l0eT0xXSBPcGFjaXR5ICgwLCAxKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Zpc2libGU9dHJ1ZV0gVmlzaWJpbGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGhlIGJvdW5kaW5nIGV4dGVudCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgVGhlIGxheWVyIHdpbGwgbm90IGJlXG4gKiByZW5kZXJlZCBvdXRzaWRlIG9mIHRoaXMgZXh0ZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6SW5kZXhdIFRoZSB6LWluZGV4IGZvciBsYXllciByZW5kZXJpbmcuICBBdCByZW5kZXJpbmcgdGltZSwgdGhlIGxheWVyc1xuICogd2lsbCBiZSBvcmRlcmVkLCBmaXJzdCBieSBaLWluZGV4IGFuZCB0aGVuIGJ5IHBvc2l0aW9uLiBXaGVuIGB1bmRlZmluZWRgLCBhIGB6SW5kZXhgIG9mIDAgaXMgYXNzdW1lZFxuICogZm9yIGxheWVycyB0aGF0IGFyZSBhZGRlZCB0byB0aGUgbWFwJ3MgYGxheWVyc2AgY29sbGVjdGlvbiwgb3IgYEluZmluaXR5YCB3aGVuIHRoZSBsYXllcidzIGBzZXRNYXAoKWBcbiAqIG1ldGhvZCB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluUmVzb2x1dGlvbl0gVGhlIG1pbmltdW0gcmVzb2x1dGlvbiAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFJlc29sdXRpb25dIFRoZSBtYXhpbXVtIHJlc29sdXRpb24gKGV4Y2x1c2l2ZSkgYmVsb3cgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tXSBUaGUgbWluaW11bSB2aWV3IHpvb20gbGV2ZWwgKGV4Y2x1c2l2ZSkgYWJvdmUgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBUaGUgbWF4aW11bSB2aWV3IHpvb20gbGV2ZWwgKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsXG4gKiBiZSB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zb3VyY2UvU291cmNlLmpzXCIpLmRlZmF1bHR9IFtzb3VyY2VdIFNvdXJjZSBmb3IgdGhpcyBsYXllci4gIElmIG5vdCBwcm92aWRlZCB0byB0aGUgY29uc3RydWN0b3IsXG4gKiB0aGUgc291cmNlIGNhbiBiZSBzZXQgYnkgY2FsbGluZyB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyI3NldFNvdXJjZSBsYXllci5zZXRTb3VyY2Uoc291cmNlKX0gYWZ0ZXJcbiAqIGNvbnN0cnVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IFttYXBdIE1hcC5cbiAqIEBwcm9wZXJ0eSB7UmVuZGVyRnVuY3Rpb259IFtyZW5kZXJdIFJlbmRlciBmdW5jdGlvbi4gVGFrZXMgdGhlIGZyYW1lIHN0YXRlIGFzIGlucHV0IGFuZCBpcyBleHBlY3RlZCB0byByZXR1cm4gYW5cbiAqIEhUTUwgZWxlbWVudC4gV2lsbCBvdmVyd3JpdGUgdGhlIGRlZmF1bHQgcmVuZGVyaW5nIGZvciB0aGUgbGF5ZXIuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdGF0ZVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0xheWVyLmpzXCIpLmRlZmF1bHR9IGxheWVyXG4gKiBAcHJvcGVydHkge251bWJlcn0gb3BhY2l0eSBPcGFjaXR5LCB0aGUgdmFsdWUgaXMgcm91bmRlZCB0byB0d28gZGlnaXRzIHRvIGFwcGVhciBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc291cmNlL1N0YXRlLmpzXCIpLmRlZmF1bHR9IHNvdXJjZVN0YXRlXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHZpc2libGVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gbWFuYWdlZFxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XVxuICogQHByb3BlcnR5IHtudW1iZXJ9IHpJbmRleFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heFJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5SZXNvbHV0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWluWm9vbVxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heFpvb21cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEJhc2UgY2xhc3MgZnJvbSB3aGljaCBhbGwgbGF5ZXIgdHlwZXMgYXJlIGRlcml2ZWQuIFRoaXMgc2hvdWxkIG9ubHkgYmUgaW5zdGFudGlhdGVkXG4gKiBpbiB0aGUgY2FzZSB3aGVyZSBhIGN1c3RvbSBsYXllciBpcyBiZSBhZGRlZCB0byB0aGUgbWFwIHdpdGggYSBjdXN0b20gYHJlbmRlcmAgZnVuY3Rpb24uXG4gKiBTdWNoIGEgZnVuY3Rpb24gY2FuIGJlIHNwZWNpZmllZCBpbiB0aGUgYG9wdGlvbnNgIG9iamVjdCwgYW5kIGlzIGV4cGVjdGVkIHRvIHJldHVybiBhbiBIVE1MIGVsZW1lbnQuXG4gKlxuICogQSB2aXN1YWwgcmVwcmVzZW50YXRpb24gb2YgcmFzdGVyIG9yIHZlY3RvciBtYXAgZGF0YS5cbiAqIExheWVycyBncm91cCB0b2dldGhlciB0aG9zZSBwcm9wZXJ0aWVzIHRoYXQgcGVydGFpbiB0byBob3cgdGhlIGRhdGEgaXMgdG8gYmVcbiAqIGRpc3BsYXllZCwgaXJyZXNwZWN0aXZlIG9mIHRoZSBzb3VyY2Ugb2YgdGhhdCBkYXRhLlxuICpcbiAqIExheWVycyBhcmUgdXN1YWxseSBhZGRlZCB0byBhIG1hcCB3aXRoIHtAbGluayBtb2R1bGU6b2wvTWFwI2FkZExheWVyfS4gQ29tcG9uZW50c1xuICogbGlrZSB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL1NlbGVjdH5TZWxlY3R9IHVzZSB1bm1hbmFnZWQgbGF5ZXJzXG4gKiBpbnRlcm5hbGx5LiBUaGVzZSB1bm1hbmFnZWQgbGF5ZXJzIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIG1hcCB1c2luZ1xuICoge0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllcn5MYXllciNzZXRNYXB9IGluc3RlYWQuXG4gKlxuICogQSBnZW5lcmljIGBjaGFuZ2VgIGV2ZW50IGlzIGZpcmVkIHdoZW4gdGhlIHN0YXRlIG9mIHRoZSBzb3VyY2UgY2hhbmdlcy5cbiAqXG4gKiBQbGVhc2Ugbm90ZSB0aGF0IGZvciBwZXJmb3JtYW5jZSByZWFzb25zIHNldmVyYWwgbGF5ZXJzIG1pZ2h0IGdldCByZW5kZXJlZCB0b1xuICogdGhlIHNhbWUgSFRNTCBlbGVtZW50LCB3aGljaCB3aWxsIGNhdXNlIHtAbGluayBtb2R1bGU6b2wvTWFwfk1hcCNmb3JFYWNoTGF5ZXJBdFBpeGVsfSB0b1xuICogZ2l2ZSBmYWxzZSBwb3NpdGl2ZXMuIFRvIGF2b2lkIHRoaXMsIGFwcGx5IGRpZmZlcmVudCBgY2xhc3NOYW1lYCBwcm9wZXJ0aWVzIHRvIHRoZVxuICogbGF5ZXJzIGF0IGNyZWF0aW9uIHRpbWUuXG4gKlxuICogQGZpcmVzIGltcG9ydChcIi4uL3JlbmRlci9FdmVudC5qc1wiKS5SZW5kZXJFdmVudCNwcmVyZW5kZXJcbiAqIEBmaXJlcyBpbXBvcnQoXCIuLi9yZW5kZXIvRXZlbnQuanNcIikuUmVuZGVyRXZlbnQjcG9zdHJlbmRlclxuICpcbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vc291cmNlL1NvdXJjZS5qc1wiKS5kZWZhdWx0fSBTb3VyY2VUeXBlXG4gKiBAYXBpXG4gKi9cblxudmFyIExheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKExheWVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIExheWVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTGF5ZXIob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgYmFzZU9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy5zb3VyY2U7XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBiYXNlT3B0aW9ucykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKi9cblxuICAgIF90aGlzLm1hcFByZWNvbXBvc2VLZXlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKi9cblxuICAgIF90aGlzLm1hcFJlbmRlcktleV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc291cmNlQ2hhbmdlS2V5XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyZXIvTGF5ZXIuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVyXyA9IG51bGw7IC8vIE92ZXJ3cml0ZSBkZWZhdWx0IHJlbmRlciBtZXRob2Qgd2l0aCBhIGN1c3RvbSBvbmVcblxuICAgIGlmIChvcHRpb25zLnJlbmRlcikge1xuICAgICAgX3RoaXMucmVuZGVyID0gb3B0aW9ucy5yZW5kZXI7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubWFwKSB7XG4gICAgICBfdGhpcy5zZXRNYXAob3B0aW9ucy5tYXApO1xuICAgIH1cblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKExheWVyUHJvcGVydHkuU09VUkNFKSwgX3RoaXMuaGFuZGxlU291cmNlUHJvcGVydHlDaGFuZ2VfKTtcblxuICAgIHZhciBzb3VyY2UgPSBvcHRpb25zLnNvdXJjZSA/XG4gICAgLyoqIEB0eXBlIHtTb3VyY2VUeXBlfSAqL1xuICAgIG9wdGlvbnMuc291cmNlIDogbnVsbDtcblxuICAgIF90aGlzLnNldFNvdXJjZShzb3VyY2UpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdD49fSBvcHRfYXJyYXkgQXJyYXkgb2YgbGF5ZXJzICh0byBiZSBtb2RpZmllZCBpbiBwbGFjZSkuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuZGVmYXVsdD59IEFycmF5IG9mIGxheWVycy5cbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuZ2V0TGF5ZXJzQXJyYXkgPSBmdW5jdGlvbiAob3B0X2FycmF5KSB7XG4gICAgdmFyIGFycmF5ID0gb3B0X2FycmF5ID8gb3B0X2FycmF5IDogW107XG4gICAgYXJyYXkucHVzaCh0aGlzKTtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vTGF5ZXIuanNcIikuU3RhdGU+PX0gb3B0X3N0YXRlcyBPcHRpb25hbCBsaXN0IG9mIGxheWVyIHN0YXRlcyAodG8gYmUgbW9kaWZpZWQgaW4gcGxhY2UpLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlPn0gTGlzdCBvZiBsYXllciBzdGF0ZXMuXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmdldExheWVyU3RhdGVzQXJyYXkgPSBmdW5jdGlvbiAob3B0X3N0YXRlcykge1xuICAgIHZhciBzdGF0ZXMgPSBvcHRfc3RhdGVzID8gb3B0X3N0YXRlcyA6IFtdO1xuICAgIHN0YXRlcy5wdXNoKHRoaXMuZ2V0TGF5ZXJTdGF0ZSgpKTtcbiAgICByZXR1cm4gc3RhdGVzO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsYXllciBzb3VyY2UuXG4gICAqIEByZXR1cm4ge1NvdXJjZVR5cGV9IFRoZSBsYXllciBzb3VyY2UgKG9yIGBudWxsYCBpZiBub3QgeWV0IHNldCkuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuZ2V0U291cmNlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge1NvdXJjZVR5cGV9ICovXG4gICAgICB0aGlzLmdldChMYXllclByb3BlcnR5LlNPVVJDRSkgfHwgbnVsbFxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zb3VyY2UvU3RhdGUuanNcIikuZGVmYXVsdH0gU291cmNlIHN0YXRlLlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5nZXRTb3VyY2VTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc291cmNlID0gdGhpcy5nZXRTb3VyY2UoKTtcbiAgICByZXR1cm4gIXNvdXJjZSA/IFNvdXJjZVN0YXRlLlVOREVGSU5FRCA6IHNvdXJjZS5nZXRTdGF0ZSgpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuaGFuZGxlU291cmNlQ2hhbmdlXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmhhbmRsZVNvdXJjZVByb3BlcnR5Q2hhbmdlXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zb3VyY2VDaGFuZ2VLZXlfKSB7XG4gICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMuc291cmNlQ2hhbmdlS2V5Xyk7XG4gICAgICB0aGlzLnNvdXJjZUNoYW5nZUtleV8gPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2UgPSB0aGlzLmdldFNvdXJjZSgpO1xuXG4gICAgaWYgKHNvdXJjZSkge1xuICAgICAgdGhpcy5zb3VyY2VDaGFuZ2VLZXlfID0gbGlzdGVuKHNvdXJjZSwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVTb3VyY2VDaGFuZ2VfLCB0aGlzKTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWxcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PGltcG9ydChcIi4uL0ZlYXR1cmVcIikuZGVmYXVsdD4+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aFxuICAgKiBhbiBhcnJheSBvZiBmZWF0dXJlcy5cbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlcl8uZ2V0RmVhdHVyZXMocGl4ZWwpO1xuICB9O1xuICAvKipcbiAgICogSW4gY2hhcmdlIHRvIG1hbmFnZSB0aGUgcmVuZGVyaW5nIG9mIHRoZSBsYXllci4gT25lIGxheWVyIHR5cGUgaXNcbiAgICogYm91bmRlZCB3aXRoIG9uZSBsYXllciByZW5kZXJlci5cbiAgICogQHBhcmFtIHs/aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBUYXJnZXQgd2hpY2ggdGhlIHJlbmRlcmVyIG1heSAoYnV0IG5lZWQgbm90KSB1c2VcbiAgICogZm9yIHJlbmRlcmluZyBpdHMgY29udGVudC5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSByZW5kZXJlZCBlbGVtZW50LlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSwgdGFyZ2V0KSB7XG4gICAgdmFyIGxheWVyUmVuZGVyZXIgPSB0aGlzLmdldFJlbmRlcmVyKCk7XG5cbiAgICBpZiAobGF5ZXJSZW5kZXJlci5wcmVwYXJlRnJhbWUoZnJhbWVTdGF0ZSkpIHtcbiAgICAgIHJldHVybiBsYXllclJlbmRlcmVyLnJlbmRlckZyYW1lKGZyYW1lU3RhdGUsIHRhcmdldCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0cyB0aGUgbGF5ZXIgdG8gYmUgcmVuZGVyZWQgb24gdG9wIG9mIG90aGVyIGxheWVycyBvbiBhIG1hcC4gVGhlIG1hcCB3aWxsXG4gICAqIG5vdCBtYW5hZ2UgdGhpcyBsYXllciBpbiBpdHMgbGF5ZXJzIGNvbGxlY3Rpb24sIGFuZCB0aGUgY2FsbGJhY2sgaW5cbiAgICoge0BsaW5rIG1vZHVsZTpvbC9NYXAjZm9yRWFjaExheWVyQXRQaXhlbH0gd2lsbCByZWNlaXZlIGBudWxsYCBhcyBsYXllci4gVGhpc1xuICAgKiBpcyB1c2VmdWwgZm9yIHRlbXBvcmFyeSBsYXllcnMuIFRvIHJlbW92ZSBhbiB1bm1hbmFnZWQgbGF5ZXIgZnJvbSB0aGUgbWFwLFxuICAgKiB1c2UgYCNzZXRNYXAobnVsbClgLlxuICAgKlxuICAgKiBUbyBhZGQgdGhlIGxheWVyIHRvIGEgbWFwIGFuZCBoYXZlIGl0IG1hbmFnZWQgYnkgdGhlIG1hcCwgdXNlXG4gICAqIHtAbGluayBtb2R1bGU6b2wvTWFwI2FkZExheWVyfSBpbnN0ZWFkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBtYXAgTWFwLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLnNldE1hcCA9IGZ1bmN0aW9uIChtYXApIHtcbiAgICBpZiAodGhpcy5tYXBQcmVjb21wb3NlS2V5Xykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLm1hcFByZWNvbXBvc2VLZXlfKTtcbiAgICAgIHRoaXMubWFwUHJlY29tcG9zZUtleV8gPSBudWxsO1xuICAgIH1cblxuICAgIGlmICghbWFwKSB7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXBSZW5kZXJLZXlfKSB7XG4gICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMubWFwUmVuZGVyS2V5Xyk7XG4gICAgICB0aGlzLm1hcFJlbmRlcktleV8gPSBudWxsO1xuICAgIH1cblxuICAgIGlmIChtYXApIHtcbiAgICAgIHRoaXMubWFwUHJlY29tcG9zZUtleV8gPSBsaXN0ZW4obWFwLCBSZW5kZXJFdmVudFR5cGUuUFJFQ09NUE9TRSwgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICB2YXIgcmVuZGVyRXZlbnQgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3JlbmRlci9FdmVudC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBldnQ7XG4gICAgICAgIHZhciBsYXllclN0YXRlc0FycmF5ID0gcmVuZGVyRXZlbnQuZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5O1xuICAgICAgICB2YXIgbGF5ZXJTdGF0ZSA9IHRoaXMuZ2V0TGF5ZXJTdGF0ZShmYWxzZSk7IC8vIEEgbGF5ZXIgY2FuIG9ubHkgYmUgYWRkZWQgdG8gdGhlIG1hcCBvbmNlLiBVc2UgZWl0aGVyIGBsYXllci5zZXRNYXAoKWAgb3IgYG1hcC5hZGRMYXllcigpYCwgbm90IGJvdGguXG5cbiAgICAgICAgYXNzZXJ0KCFsYXllclN0YXRlc0FycmF5LnNvbWUoZnVuY3Rpb24gKGFycmF5TGF5ZXJTdGF0ZSkge1xuICAgICAgICAgIHJldHVybiBhcnJheUxheWVyU3RhdGUubGF5ZXIgPT09IGxheWVyU3RhdGUubGF5ZXI7XG4gICAgICAgIH0pLCA2Nyk7XG4gICAgICAgIGxheWVyU3RhdGVzQXJyYXkucHVzaChsYXllclN0YXRlKTtcbiAgICAgIH0sIHRoaXMpO1xuICAgICAgdGhpcy5tYXBSZW5kZXJLZXlfID0gbGlzdGVuKHRoaXMsIEV2ZW50VHlwZS5DSEFOR0UsIG1hcC5yZW5kZXIsIG1hcCk7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGxheWVyIHNvdXJjZS5cbiAgICogQHBhcmFtIHtTb3VyY2VUeXBlfSBzb3VyY2UgVGhlIGxheWVyIHNvdXJjZS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5zZXRTb3VyY2UgPSBmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgdGhpcy5zZXQoTGF5ZXJQcm9wZXJ0eS5TT1VSQ0UsIHNvdXJjZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlbmRlcmVyIGZvciB0aGlzIGxheWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9yZW5kZXJlci9MYXllci5qc1wiKS5kZWZhdWx0fSBUaGUgbGF5ZXIgcmVuZGVyZXIuXG4gICAqL1xuXG5cbiAgTGF5ZXIucHJvdG90eXBlLmdldFJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5yZW5kZXJlcl8pIHtcbiAgICAgIHRoaXMucmVuZGVyZXJfID0gdGhpcy5jcmVhdGVSZW5kZXJlcigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBsYXllciBoYXMgYSByZW5kZXJlci5cbiAgICovXG5cblxuICBMYXllci5wcm90b3R5cGUuaGFzUmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5yZW5kZXJlcl87XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGUgYSByZW5kZXJlciBmb3IgdGhpcyBsYXllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcmVuZGVyZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gQSBsYXllciByZW5kZXJlci5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIExheWVyLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRTb3VyY2UobnVsbCk7XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICB9O1xuXG4gIHJldHVybiBMYXllcjtcbn0oQmFzZUxheWVyKTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgbGF5ZXIgaXMgdmlzaWJsZSBhbmQgaWYgdGhlIHByb3ZpZGVkIHZpZXcgc3RhdGVcbiAqIGhhcyByZXNvbHV0aW9uIGFuZCB6b29tIGxldmVscyB0aGF0IGFyZSBpbiByYW5nZSBvZiB0aGUgbGF5ZXIncyBtaW4vbWF4LlxuICogQHBhcmFtIHtTdGF0ZX0gbGF5ZXJTdGF0ZSBMYXllciBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVmlldy5qc1wiKS5TdGF0ZX0gdmlld1N0YXRlIFZpZXcgc3RhdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgbGF5ZXIgaXMgdmlzaWJsZSBhdCB0aGUgZ2l2ZW4gdmlldyBzdGF0ZS5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBpblZpZXcobGF5ZXJTdGF0ZSwgdmlld1N0YXRlKSB7XG4gIGlmICghbGF5ZXJTdGF0ZS52aXNpYmxlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHJlc29sdXRpb24gPSB2aWV3U3RhdGUucmVzb2x1dGlvbjtcblxuICBpZiAocmVzb2x1dGlvbiA8IGxheWVyU3RhdGUubWluUmVzb2x1dGlvbiB8fCByZXNvbHV0aW9uID49IGxheWVyU3RhdGUubWF4UmVzb2x1dGlvbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB6b29tID0gdmlld1N0YXRlLnpvb207XG4gIHJldHVybiB6b29tID4gbGF5ZXJTdGF0ZS5taW5ab29tICYmIHpvb20gPD0gbGF5ZXJTdGF0ZS5tYXhab29tO1xufVxuZXhwb3J0IGRlZmF1bHQgTGF5ZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Nvb3JkaW5hdGVcbiAqL1xuaW1wb3J0IHsgZ2V0V2lkdGggfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBtb2R1bG8gfSBmcm9tICcuL21hdGguanMnO1xuaW1wb3J0IHsgcGFkTnVtYmVyIH0gZnJvbSAnLi9zdHJpbmcuanMnO1xuLyoqXG4gKiBBbiBhcnJheSBvZiBudW1iZXJzIHJlcHJlc2VudGluZyBhbiB4eSBjb29yZGluYXRlLiBFeGFtcGxlOiBgWzE2LCA0OF1gLlxuICogQHR5cGVkZWYge0FycmF5PG51bWJlcj59IENvb3JkaW5hdGVcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlfSBhbmRcbiAqIHRyYW5zZm9ybXMgaXQgaW50byBhIGB7c3RyaW5nfWAuXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKChDb29yZGluYXRlfHVuZGVmaW5lZCkpOiBzdHJpbmd9IENvb3JkaW5hdGVGb3JtYXRcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEFkZCBgZGVsdGFgIHRvIGBjb29yZGluYXRlYC4gYGNvb3JkaW5hdGVgIGlzIG1vZGlmaWVkIGluIHBsYWNlIGFuZCByZXR1cm5lZFxuICogYnkgdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCB7YWRkfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgYWRkKGNvb3JkLCBbLTIsIDRdKTtcbiAqICAgICAvLyBjb29yZCBpcyBub3cgWzUuODUsIDUxLjk4MzMzM11cbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gZGVsdGEgRGVsdGEuXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlfSBUaGUgaW5wdXQgY29vcmRpbmF0ZSBhZGp1c3RlZCBieVxuICogdGhlIGdpdmVuIGRlbHRhLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQoY29vcmRpbmF0ZSwgZGVsdGEpIHtcbiAgY29vcmRpbmF0ZVswXSArPSArZGVsdGFbMF07XG4gIGNvb3JkaW5hdGVbMV0gKz0gK2RlbHRhWzFdO1xuICByZXR1cm4gY29vcmRpbmF0ZTtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcG9pbnQgY2xvc2VzdCB0byB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgb24gdGhlIHBhc3NlZCBjaXJjbGUuXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIFRoZSBjb29yZGluYXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGNpcmNsZSBUaGUgY2lyY2xlLlxuICogQHJldHVybiB7Q29vcmRpbmF0ZX0gQ2xvc2VzdCBwb2ludCBvbiB0aGUgY2lyY3VtZmVyZW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xvc2VzdE9uQ2lyY2xlKGNvb3JkaW5hdGUsIGNpcmNsZSkge1xuICB2YXIgciA9IGNpcmNsZS5nZXRSYWRpdXMoKTtcbiAgdmFyIGNlbnRlciA9IGNpcmNsZS5nZXRDZW50ZXIoKTtcbiAgdmFyIHgwID0gY2VudGVyWzBdO1xuICB2YXIgeTAgPSBjZW50ZXJbMV07XG4gIHZhciB4MSA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5MSA9IGNvb3JkaW5hdGVbMV07XG4gIHZhciBkeCA9IHgxIC0geDA7XG4gIHZhciBkeSA9IHkxIC0geTA7XG5cbiAgaWYgKGR4ID09PSAwICYmIGR5ID09PSAwKSB7XG4gICAgZHggPSAxO1xuICB9XG5cbiAgdmFyIGQgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpO1xuICB2YXIgeCA9IHgwICsgciAqIGR4IC8gZDtcbiAgdmFyIHkgPSB5MCArIHIgKiBkeSAvIGQ7XG4gIHJldHVybiBbeCwgeV07XG59XG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHBvaW50IGNsb3Nlc3QgdG8gdGhlIHBhc3NlZCBjb29yZGluYXRlIG9uIHRoZSBwYXNzZWQgc2VnbWVudC5cbiAqIFRoaXMgaXMgdGhlIGZvb3Qgb2YgdGhlIHBlcnBlbmRpY3VsYXIgb2YgdGhlIGNvb3JkaW5hdGUgdG8gdGhlIHNlZ21lbnQgd2hlblxuICogdGhlIGZvb3QgaXMgb24gdGhlIHNlZ21lbnQsIG9yIHRoZSBjbG9zZXN0IHNlZ21lbnQgY29vcmRpbmF0ZSB3aGVuIHRoZSBmb290XG4gKiBpcyBvdXRzaWRlIHRoZSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBUaGUgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7QXJyYXk8Q29vcmRpbmF0ZT59IHNlZ21lbnQgVGhlIHR3byBjb29yZGluYXRlc1xuICogb2YgdGhlIHNlZ21lbnQuXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlfSBUaGUgZm9vdCBvZiB0aGUgcGVycGVuZGljdWxhciBvZlxuICogdGhlIGNvb3JkaW5hdGUgdG8gdGhlIHNlZ21lbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3Nlc3RPblNlZ21lbnQoY29vcmRpbmF0ZSwgc2VnbWVudCkge1xuICB2YXIgeDAgPSBjb29yZGluYXRlWzBdO1xuICB2YXIgeTAgPSBjb29yZGluYXRlWzFdO1xuICB2YXIgc3RhcnQgPSBzZWdtZW50WzBdO1xuICB2YXIgZW5kID0gc2VnbWVudFsxXTtcbiAgdmFyIHgxID0gc3RhcnRbMF07XG4gIHZhciB5MSA9IHN0YXJ0WzFdO1xuICB2YXIgeDIgPSBlbmRbMF07XG4gIHZhciB5MiA9IGVuZFsxXTtcbiAgdmFyIGR4ID0geDIgLSB4MTtcbiAgdmFyIGR5ID0geTIgLSB5MTtcbiAgdmFyIGFsb25nID0gZHggPT09IDAgJiYgZHkgPT09IDAgPyAwIDogKGR4ICogKHgwIC0geDEpICsgZHkgKiAoeTAgLSB5MSkpIC8gKGR4ICogZHggKyBkeSAqIGR5IHx8IDApO1xuICB2YXIgeCwgeTtcblxuICBpZiAoYWxvbmcgPD0gMCkge1xuICAgIHggPSB4MTtcbiAgICB5ID0geTE7XG4gIH0gZWxzZSBpZiAoYWxvbmcgPj0gMSkge1xuICAgIHggPSB4MjtcbiAgICB5ID0geTI7XG4gIH0gZWxzZSB7XG4gICAgeCA9IHgxICsgYWxvbmcgKiBkeDtcbiAgICB5ID0geTEgKyBhbG9uZyAqIGR5O1xuICB9XG5cbiAgcmV0dXJuIFt4LCB5XTtcbn1cbi8qKlxuICogUmV0dXJucyBhIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlRm9ybWF0fSBmdW5jdGlvbiB0aGF0IGNhbiBiZVxuICogdXNlZCB0byBmb3JtYXRcbiAqIGEge0Nvb3JkaW5hdGV9IHRvIGEgc3RyaW5nLlxuICpcbiAqIEV4YW1wbGUgd2l0aG91dCBzcGVjaWZ5aW5nIHRoZSBmcmFjdGlvbmFsIGRpZ2l0czpcbiAqXG4gKiAgICAgaW1wb3J0IHtjcmVhdGVTdHJpbmdYWX0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciBzdHJpbmdpZnlGdW5jID0gY3JlYXRlU3RyaW5nWFkoKTtcbiAqICAgICB2YXIgb3V0ID0gc3RyaW5naWZ5RnVuYyhjb29yZCk7XG4gKiAgICAgLy8gb3V0IGlzIG5vdyAnOCwgNDgnXG4gKlxuICogRXhhbXBsZSB3aXRoIGV4cGxpY2l0bHkgc3BlY2lmeWluZyAyIGZyYWN0aW9uYWwgZGlnaXRzOlxuICpcbiAqICAgICBpbXBvcnQge2NyZWF0ZVN0cmluZ1hZfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHN0cmluZ2lmeUZ1bmMgPSBjcmVhdGVTdHJpbmdYWSgyKTtcbiAqICAgICB2YXIgb3V0ID0gc3RyaW5naWZ5RnVuYyhjb29yZCk7XG4gKiAgICAgLy8gb3V0IGlzIG5vdyAnNy44NSwgNDcuOTgnXG4gKlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZnJhY3Rpb25EaWdpdHMgVGhlIG51bWJlciBvZiBkaWdpdHMgdG8gaW5jbHVkZVxuICogICAgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuIERlZmF1bHQgaXMgYDBgLlxuICogQHJldHVybiB7Q29vcmRpbmF0ZUZvcm1hdH0gQ29vcmRpbmF0ZSBmb3JtYXQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0cmluZ1hZKG9wdF9mcmFjdGlvbkRpZ2l0cykge1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgICAqIEByZXR1cm4ge3N0cmluZ30gU3RyaW5nIFhZLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgICByZXR1cm4gdG9TdHJpbmdYWShjb29yZGluYXRlLCBvcHRfZnJhY3Rpb25EaWdpdHMpO1xuICAgIH1cbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGhlbWlzcGhlcmVzIEhlbWlzcGhlcmVzLlxuICogQHBhcmFtIHtudW1iZXJ9IGRlZ3JlZXMgRGVncmVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2ZyYWN0aW9uRGlnaXRzIFRoZSBudW1iZXIgb2YgZGlnaXRzIHRvIGluY2x1ZGVcbiAqICAgIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LiBEZWZhdWx0IGlzIGAwYC5cbiAqIEByZXR1cm4ge3N0cmluZ30gU3RyaW5nLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWdyZWVzVG9TdHJpbmdIRE1TKGhlbWlzcGhlcmVzLCBkZWdyZWVzLCBvcHRfZnJhY3Rpb25EaWdpdHMpIHtcbiAgdmFyIG5vcm1hbGl6ZWREZWdyZWVzID0gbW9kdWxvKGRlZ3JlZXMgKyAxODAsIDM2MCkgLSAxODA7XG4gIHZhciB4ID0gTWF0aC5hYnMoMzYwMCAqIG5vcm1hbGl6ZWREZWdyZWVzKTtcbiAgdmFyIGRmbFByZWNpc2lvbiA9IG9wdF9mcmFjdGlvbkRpZ2l0cyB8fCAwO1xuICB2YXIgcHJlY2lzaW9uID0gTWF0aC5wb3coMTAsIGRmbFByZWNpc2lvbik7XG4gIHZhciBkZWcgPSBNYXRoLmZsb29yKHggLyAzNjAwKTtcbiAgdmFyIG1pbiA9IE1hdGguZmxvb3IoKHggLSBkZWcgKiAzNjAwKSAvIDYwKTtcbiAgdmFyIHNlYyA9IHggLSBkZWcgKiAzNjAwIC0gbWluICogNjA7XG4gIHNlYyA9IE1hdGguY2VpbChzZWMgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uO1xuXG4gIGlmIChzZWMgPj0gNjApIHtcbiAgICBzZWMgPSAwO1xuICAgIG1pbiArPSAxO1xuICB9XG5cbiAgaWYgKG1pbiA+PSA2MCkge1xuICAgIG1pbiA9IDA7XG4gICAgZGVnICs9IDE7XG4gIH1cblxuICByZXR1cm4gZGVnICsgXCJcXHhCMCBcIiArIHBhZE51bWJlcihtaW4sIDIpICsgXCJcXHUyMDMyIFwiICsgcGFkTnVtYmVyKHNlYywgMiwgZGZsUHJlY2lzaW9uKSArIFwiXFx1MjAzM1wiICsgKG5vcm1hbGl6ZWREZWdyZWVzID09IDAgPyAnJyA6ICcgJyArIGhlbWlzcGhlcmVzLmNoYXJBdChub3JtYWxpemVkRGVncmVlcyA8IDAgPyAxIDogMCkpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSBnaXZlbiB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0gdG8gYSBzdHJpbmdcbiAqIHVzaW5nIHRoZSBnaXZlbiBzdHJpbmcgdGVtcGxhdGUuIFRoZSBzdHJpbmdzIGB7eH1gIGFuZCBge3l9YCBpbiB0aGUgdGVtcGxhdGVcbiAqIHdpbGwgYmUgcmVwbGFjZWQgd2l0aCB0aGUgZmlyc3QgYW5kIHNlY29uZCBjb29yZGluYXRlIHZhbHVlcyByZXNwZWN0aXZlbHkuXG4gKlxuICogRXhhbXBsZSB3aXRob3V0IHNwZWNpZnlpbmcgdGhlIGZyYWN0aW9uYWwgZGlnaXRzOlxuICpcbiAqICAgICBpbXBvcnQge2Zvcm1hdH0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciB0ZW1wbGF0ZSA9ICdDb29yZGluYXRlIGlzICh7eH18e3l9KS4nO1xuICogICAgIHZhciBvdXQgPSBmb3JtYXQoY29vcmQsIHRlbXBsYXRlKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICdDb29yZGluYXRlIGlzICg4fDQ4KS4nXG4gKlxuICogRXhhbXBsZSBleHBsaWNpdGx5IHNwZWNpZnlpbmcgdGhlIGZyYWN0aW9uYWwgZGlnaXRzOlxuICpcbiAqICAgICBpbXBvcnQge2Zvcm1hdH0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciB0ZW1wbGF0ZSA9ICdDb29yZGluYXRlIGlzICh7eH18e3l9KS4nO1xuICogICAgIHZhciBvdXQgPSBmb3JtYXQoY29vcmQsIHRlbXBsYXRlLCAyKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICdDb29yZGluYXRlIGlzICg3Ljg1fDQ3Ljk4KS4nXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgQSB0ZW1wbGF0ZSBzdHJpbmcgd2l0aCBge3h9YCBhbmQgYHt5fWAgcGxhY2Vob2xkZXJzXG4gKiAgICAgdGhhdCB3aWxsIGJlIHJlcGxhY2VkIGJ5IGZpcnN0IGFuZCBzZWNvbmQgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9mcmFjdGlvbkRpZ2l0cyBUaGUgbnVtYmVyIG9mIGRpZ2l0cyB0byBpbmNsdWRlXG4gKiAgICBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gRGVmYXVsdCBpcyBgMGAuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IEZvcm1hdHRlZCBjb29yZGluYXRlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXQoY29vcmRpbmF0ZSwgdGVtcGxhdGUsIG9wdF9mcmFjdGlvbkRpZ2l0cykge1xuICBpZiAoY29vcmRpbmF0ZSkge1xuICAgIHJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKCd7eH0nLCBjb29yZGluYXRlWzBdLnRvRml4ZWQob3B0X2ZyYWN0aW9uRGlnaXRzKSkucmVwbGFjZSgne3l9JywgY29vcmRpbmF0ZVsxXS50b0ZpeGVkKG9wdF9mcmFjdGlvbkRpZ2l0cykpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAnJztcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUxIEZpcnN0IGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUyIFNlY29uZCBjb29yZGluYXRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHR3byBjb29yZGluYXRlcyBhcmUgZXF1YWwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhjb29yZGluYXRlMSwgY29vcmRpbmF0ZTIpIHtcbiAgdmFyIGVxdWFscyA9IHRydWU7XG5cbiAgZm9yICh2YXIgaSA9IGNvb3JkaW5hdGUxLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgaWYgKGNvb3JkaW5hdGUxW2ldICE9IGNvb3JkaW5hdGUyW2ldKSB7XG4gICAgICBlcXVhbHMgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlcXVhbHM7XG59XG4vKipcbiAqIFJvdGF0ZSBgY29vcmRpbmF0ZWAgYnkgYGFuZ2xlYC4gYGNvb3JkaW5hdGVgIGlzIG1vZGlmaWVkIGluIHBsYWNlIGFuZFxuICogcmV0dXJuZWQgYnkgdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCB7cm90YXRlfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHJvdGF0ZVJhZGlhbnMgPSBNYXRoLlBJIC8gMjsgLy8gOTAgZGVncmVlc1xuICogICAgIHJvdGF0ZShjb29yZCwgcm90YXRlUmFkaWFucyk7XG4gKiAgICAgLy8gY29vcmQgaXMgbm93IFstNDcuOTgzMzMzLCA3Ljg1XVxuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlIEFuZ2xlIGluIHJhZGlhbi5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZShjb29yZGluYXRlLCBhbmdsZSkge1xuICB2YXIgY29zQW5nbGUgPSBNYXRoLmNvcyhhbmdsZSk7XG4gIHZhciBzaW5BbmdsZSA9IE1hdGguc2luKGFuZ2xlKTtcbiAgdmFyIHggPSBjb29yZGluYXRlWzBdICogY29zQW5nbGUgLSBjb29yZGluYXRlWzFdICogc2luQW5nbGU7XG4gIHZhciB5ID0gY29vcmRpbmF0ZVsxXSAqIGNvc0FuZ2xlICsgY29vcmRpbmF0ZVswXSAqIHNpbkFuZ2xlO1xuICBjb29yZGluYXRlWzBdID0geDtcbiAgY29vcmRpbmF0ZVsxXSA9IHk7XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBTY2FsZSBgY29vcmRpbmF0ZWAgYnkgYHNjYWxlYC4gYGNvb3JkaW5hdGVgIGlzIG1vZGlmaWVkIGluIHBsYWNlIGFuZCByZXR1cm5lZFxuICogYnkgdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCB7c2NhbGUgYXMgc2NhbGVDb29yZGluYXRlfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIHNjYWxlID0gMS4yO1xuICogICAgIHNjYWxlQ29vcmRpbmF0ZShjb29yZCwgc2NhbGUpO1xuICogICAgIC8vIGNvb3JkIGlzIG5vdyBbOS40MiwgNTcuNTc5OTk5Nl1cbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzY2FsZSBTY2FsZSBmYWN0b3IuXG4gKiBAcmV0dXJuIHtDb29yZGluYXRlfSBDb29yZGluYXRlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShjb29yZGluYXRlLCBzY2FsZSkge1xuICBjb29yZGluYXRlWzBdICo9IHNjYWxlO1xuICBjb29yZGluYXRlWzFdICo9IHNjYWxlO1xuICByZXR1cm4gY29vcmRpbmF0ZTtcbn1cbi8qKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZDEgRmlyc3QgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmQyIFNlY29uZCBjb29yZGluYXRlLlxuICogQHJldHVybiB7bnVtYmVyfSBTcXVhcmVkIGRpc3RhbmNlIGJldHdlZW4gY29vcmQxIGFuZCBjb29yZDIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWREaXN0YW5jZShjb29yZDEsIGNvb3JkMikge1xuICB2YXIgZHggPSBjb29yZDFbMF0gLSBjb29yZDJbMF07XG4gIHZhciBkeSA9IGNvb3JkMVsxXSAtIGNvb3JkMlsxXTtcbiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuLyoqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkMSBGaXJzdCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZDIgU2Vjb25kIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IERpc3RhbmNlIGJldHdlZW4gY29vcmQxIGFuZCBjb29yZDIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlKGNvb3JkMSwgY29vcmQyKSB7XG4gIHJldHVybiBNYXRoLnNxcnQoc3F1YXJlZERpc3RhbmNlKGNvb3JkMSwgY29vcmQyKSk7XG59XG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgc3F1YXJlZCBkaXN0YW5jZSBmcm9tIGEgY29vcmRpbmF0ZSB0byBhIGxpbmUgc2VnbWVudC5cbiAqXG4gKiBAcGFyYW0ge0Nvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZSBvZiB0aGUgcG9pbnQuXG4gKiBAcGFyYW0ge0FycmF5PENvb3JkaW5hdGU+fSBzZWdtZW50IExpbmUgc2VnbWVudCAoMlxuICogY29vcmRpbmF0ZXMpLlxuICogQHJldHVybiB7bnVtYmVyfSBTcXVhcmVkIGRpc3RhbmNlIGZyb20gdGhlIHBvaW50IHRvIHRoZSBsaW5lIHNlZ21lbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWFyZWREaXN0YW5jZVRvU2VnbWVudChjb29yZGluYXRlLCBzZWdtZW50KSB7XG4gIHJldHVybiBzcXVhcmVkRGlzdGFuY2UoY29vcmRpbmF0ZSwgY2xvc2VzdE9uU2VnbWVudChjb29yZGluYXRlLCBzZWdtZW50KSk7XG59XG4vKipcbiAqIEZvcm1hdCBhIGdlb2dyYXBoaWMgY29vcmRpbmF0ZSB3aXRoIHRoZSBoZW1pc3BoZXJlLCBkZWdyZWVzLCBtaW51dGVzLCBhbmRcbiAqIHNlY29uZHMuXG4gKlxuICogRXhhbXBsZSB3aXRob3V0IHNwZWNpZnlpbmcgZnJhY3Rpb25hbCBkaWdpdHM6XG4gKlxuICogICAgIGltcG9ydCB7dG9TdHJpbmdIRE1TfSBmcm9tICdvbC9jb29yZGluYXRlJztcbiAqXG4gKiAgICAgdmFyIGNvb3JkID0gWzcuODUsIDQ3Ljk4MzMzM107XG4gKiAgICAgdmFyIG91dCA9IHRvU3RyaW5nSERNUyhjb29yZCk7XG4gKiAgICAgLy8gb3V0IGlzIG5vdyAnNDfCsCA1OOKAsiA2MOKAsyBOIDfCsCA1MOKAsiA2MOKAsyBFJ1xuICpcbiAqIEV4YW1wbGUgZXhwbGljaXRseSBzcGVjaWZ5aW5nIDEgZnJhY3Rpb25hbCBkaWdpdDpcbiAqXG4gKiAgICAgaW1wb3J0IHt0b1N0cmluZ0hETVN9IGZyb20gJ29sL2Nvb3JkaW5hdGUnO1xuICpcbiAqICAgICB2YXIgY29vcmQgPSBbNy44NSwgNDcuOTgzMzMzXTtcbiAqICAgICB2YXIgb3V0ID0gdG9TdHJpbmdIRE1TKGNvb3JkLCAxKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc0N8KwIDU44oCyIDYwLjDigLMgTiA3wrAgNTDigLIgNjAuMOKAsyBFJ1xuICpcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZnJhY3Rpb25EaWdpdHMgVGhlIG51bWJlciBvZiBkaWdpdHMgdG8gaW5jbHVkZVxuICogICAgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuIERlZmF1bHQgaXMgYDBgLlxuICogQHJldHVybiB7c3RyaW5nfSBIZW1pc3BoZXJlLCBkZWdyZWVzLCBtaW51dGVzIGFuZCBzZWNvbmRzLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1N0cmluZ0hETVMoY29vcmRpbmF0ZSwgb3B0X2ZyYWN0aW9uRGlnaXRzKSB7XG4gIGlmIChjb29yZGluYXRlKSB7XG4gICAgcmV0dXJuIGRlZ3JlZXNUb1N0cmluZ0hETVMoJ05TJywgY29vcmRpbmF0ZVsxXSwgb3B0X2ZyYWN0aW9uRGlnaXRzKSArICcgJyArIGRlZ3JlZXNUb1N0cmluZ0hETVMoJ0VXJywgY29vcmRpbmF0ZVswXSwgb3B0X2ZyYWN0aW9uRGlnaXRzKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbn1cbi8qKlxuICogRm9ybWF0IGEgY29vcmRpbmF0ZSBhcyBhIGNvbW1hIGRlbGltaXRlZCBzdHJpbmcuXG4gKlxuICogRXhhbXBsZSB3aXRob3V0IHNwZWNpZnlpbmcgZnJhY3Rpb25hbCBkaWdpdHM6XG4gKlxuICogICAgIGltcG9ydCB7dG9TdHJpbmdYWX0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciBvdXQgPSB0b1N0cmluZ1hZKGNvb3JkKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc4LCA0OCdcbiAqXG4gKiBFeGFtcGxlIGV4cGxpY2l0bHkgc3BlY2lmeWluZyAxIGZyYWN0aW9uYWwgZGlnaXQ6XG4gKlxuICogICAgIGltcG9ydCB7dG9TdHJpbmdYWX0gZnJvbSAnb2wvY29vcmRpbmF0ZSc7XG4gKlxuICogICAgIHZhciBjb29yZCA9IFs3Ljg1LCA0Ny45ODMzMzNdO1xuICogICAgIHZhciBvdXQgPSB0b1N0cmluZ1hZKGNvb3JkLCAxKTtcbiAqICAgICAvLyBvdXQgaXMgbm93ICc3LjgsIDQ4LjAnXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9mcmFjdGlvbkRpZ2l0cyBUaGUgbnVtYmVyIG9mIGRpZ2l0cyB0byBpbmNsdWRlXG4gKiAgICBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gRGVmYXVsdCBpcyBgMGAuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFhZLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1N0cmluZ1hZKGNvb3JkaW5hdGUsIG9wdF9mcmFjdGlvbkRpZ2l0cykge1xuICByZXR1cm4gZm9ybWF0KGNvb3JkaW5hdGUsICd7eH0sIHt5fScsIG9wdF9mcmFjdGlvbkRpZ2l0cyk7XG59XG4vKipcbiAqIE1vZGlmaWVzIHRoZSBwcm92aWRlZCBjb29yZGluYXRlIGluLXBsYWNlIHRvIGJlIHdpdGhpbiB0aGUgcmVhbCB3b3JsZFxuICogZXh0ZW50LiBUaGUgbG93ZXIgcHJvamVjdGlvbiBleHRlbnQgYm91bmRhcnkgaXMgaW5jbHVzaXZlLCB0aGUgdXBwZXIgb25lXG4gKiBleGNsdXNpdmUuXG4gKlxuICogQHBhcmFtIHtDb29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge0Nvb3JkaW5hdGV9IFRoZSBjb29yZGluYXRlIHdpdGhpbiB0aGUgcmVhbCB3b3JsZCBleHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBYKGNvb3JkaW5hdGUsIHByb2plY3Rpb24pIHtcbiAgaWYgKHByb2plY3Rpb24uY2FuV3JhcFgoKSkge1xuICAgIHZhciB3b3JsZFdpZHRoID0gZ2V0V2lkdGgocHJvamVjdGlvbi5nZXRFeHRlbnQoKSk7XG4gICAgdmFyIHdvcmxkc0F3YXkgPSBnZXRXb3JsZHNBd2F5KGNvb3JkaW5hdGUsIHByb2plY3Rpb24sIHdvcmxkV2lkdGgpO1xuXG4gICAgaWYgKHdvcmxkc0F3YXkpIHtcbiAgICAgIGNvb3JkaW5hdGVbMF0gLT0gd29ybGRzQXdheSAqIHdvcmxkV2lkdGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvb3JkaW5hdGU7XG59XG4vKipcbiAqIEBwYXJhbSB7Q29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9zb3VyY2VFeHRlbnRXaWR0aCBXaWR0aCBvZiB0aGUgc291cmNlIGV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gT2Zmc2V0IGluIHdvcmxkIHdpZHRocy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ybGRzQXdheShjb29yZGluYXRlLCBwcm9qZWN0aW9uLCBvcHRfc291cmNlRXh0ZW50V2lkdGgpIHtcbiAgdmFyIHByb2plY3Rpb25FeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICB2YXIgd29ybGRzQXdheSA9IDA7XG5cbiAgaWYgKHByb2plY3Rpb24uY2FuV3JhcFgoKSAmJiAoY29vcmRpbmF0ZVswXSA8IHByb2plY3Rpb25FeHRlbnRbMF0gfHwgY29vcmRpbmF0ZVswXSA+IHByb2plY3Rpb25FeHRlbnRbMl0pKSB7XG4gICAgdmFyIHNvdXJjZUV4dGVudFdpZHRoID0gb3B0X3NvdXJjZUV4dGVudFdpZHRoIHx8IGdldFdpZHRoKHByb2plY3Rpb25FeHRlbnQpO1xuICAgIHdvcmxkc0F3YXkgPSBNYXRoLmZsb29yKChjb29yZGluYXRlWzBdIC0gcHJvamVjdGlvbkV4dGVudFswXSkgLyBzb3VyY2VFeHRlbnRXaWR0aCk7XG4gIH1cblxuICByZXR1cm4gd29ybGRzQXdheTtcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL01hcFxuICovXG5cblxuaW1wb3J0IERpc3Bvc2FibGUgZnJvbSAnLi4vRGlzcG9zYWJsZS5qcyc7XG5pbXBvcnQgeyBUUlVFIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBjb21wb3NlIGFzIGNvbXBvc2VUcmFuc2Zvcm0sIG1ha2VJbnZlcnNlIH0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGdldFdpZHRoIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IHNoYXJlZCBhcyBpY29uSW1hZ2VDYWNoZSB9IGZyb20gJy4uL3N0eWxlL0ljb25JbWFnZUNhY2hlLmpzJztcbmltcG9ydCB7IGluVmlldyB9IGZyb20gJy4uL2xheWVyL0xheWVyLmpzJztcbmltcG9ydCB7IHdyYXBYIH0gZnJvbSAnLi4vY29vcmRpbmF0ZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIEhpdE1hdGNoXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmVcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXJcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRpc3RhbmNlU3FcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi92ZWN0b3IuanNcIikuRmVhdHVyZUNhbGxiYWNrPFQ+fSBjYWxsYmFja1xuICogQHRlbXBsYXRlIFRcbiAqL1xuXG4vKipcbiAqIEBhYnN0cmFjdFxuICovXG5cbnZhciBNYXBSZW5kZXJlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNYXBSZW5kZXJlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTWFwUmVuZGVyZXIobWFwKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWFwXyA9IG1hcDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9FdmVudFR5cGUuanNcIikuZGVmYXVsdH0gdHlwZSBFdmVudCB0eXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5kaXNwYXRjaFJlbmRlckV2ZW50ID0gZnVuY3Rpb24gKHR5cGUsIGZyYW1lU3RhdGUpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZVN0YXRlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTWFwUmVuZGVyZXIucHJvdG90eXBlLmNhbGN1bGF0ZU1hdHJpY2VzMkQgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0gPSBmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtO1xuICAgIHZhciBwaXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybSA9IGZyYW1lU3RhdGUucGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm07XG4gICAgY29tcG9zZVRyYW5zZm9ybShjb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgZnJhbWVTdGF0ZS5zaXplWzBdIC8gMiwgZnJhbWVTdGF0ZS5zaXplWzFdIC8gMiwgMSAvIHZpZXdTdGF0ZS5yZXNvbHV0aW9uLCAtMSAvIHZpZXdTdGF0ZS5yZXNvbHV0aW9uLCAtdmlld1N0YXRlLnJvdGF0aW9uLCAtdmlld1N0YXRlLmNlbnRlclswXSwgLXZpZXdTdGF0ZS5jZW50ZXJbMV0pO1xuICAgIG1ha2VJbnZlcnNlKHBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtLCBjb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY2hlY2tXcmFwcGVkIENoZWNrIGZvciB3cmFwcGVkIGdlb21ldHJpZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi92ZWN0b3IuanNcIikuRmVhdHVyZUNhbGxiYWNrPFQ+fSBjYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge1N9IHRoaXNBcmcgVmFsdWUgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyBgY2FsbGJhY2tgLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6IFUsIGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQpOiBib29sZWFufSBsYXllckZpbHRlciBMYXllciBmaWx0ZXJcbiAgICogICAgIGZ1bmN0aW9uLCBvbmx5IGxheWVycyB3aGljaCBhcmUgdmlzaWJsZSBhbmQgZm9yIHdoaWNoIHRoaXMgZnVuY3Rpb25cbiAgICogICAgIHJldHVybnMgYHRydWVgIHdpbGwgYmUgdGVzdGVkIGZvciBmZWF0dXJlcy4gIEJ5IGRlZmF1bHQsIGFsbCB2aXNpYmxlXG4gICAqICAgICBsYXllcnMgd2lsbCBiZSB0ZXN0ZWQuXG4gICAqIEBwYXJhbSB7VX0gdGhpc0FyZzIgVmFsdWUgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyBgbGF5ZXJGaWx0ZXJgLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgUyxULFVcbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlLCBjaGVja1dyYXBwZWQsIGNhbGxiYWNrLCB0aGlzQXJnLCBsYXllckZpbHRlciwgdGhpc0FyZzIpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG1hbmFnZWQgTWFuYWdlZCBsYXllci5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IGxheWVyIExheWVyLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgICAqL1xuXG4gICAgZnVuY3Rpb24gZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUobWFuYWdlZCwgZmVhdHVyZSwgbGF5ZXIsIGdlb21ldHJ5KSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCBmZWF0dXJlLCBtYW5hZ2VkID8gbGF5ZXIgOiBudWxsLCBnZW9tZXRyeSk7XG4gICAgfVxuXG4gICAgdmFyIHByb2plY3Rpb24gPSB2aWV3U3RhdGUucHJvamVjdGlvbjtcbiAgICB2YXIgdHJhbnNsYXRlZENvb3JkaW5hdGUgPSB3cmFwWChjb29yZGluYXRlLnNsaWNlKCksIHByb2plY3Rpb24pO1xuICAgIHZhciBvZmZzZXRzID0gW1swLCAwXV07XG5cbiAgICBpZiAocHJvamVjdGlvbi5jYW5XcmFwWCgpICYmIGNoZWNrV3JhcHBlZCkge1xuICAgICAgdmFyIHByb2plY3Rpb25FeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICAgICAgdmFyIHdvcmxkV2lkdGggPSBnZXRXaWR0aChwcm9qZWN0aW9uRXh0ZW50KTtcbiAgICAgIG9mZnNldHMucHVzaChbLXdvcmxkV2lkdGgsIDBdLCBbd29ybGRXaWR0aCwgMF0pO1xuICAgIH1cblxuICAgIHZhciBsYXllclN0YXRlcyA9IGZyYW1lU3RhdGUubGF5ZXJTdGF0ZXNBcnJheTtcbiAgICB2YXIgbnVtTGF5ZXJzID0gbGF5ZXJTdGF0ZXMubGVuZ3RoO1xuICAgIHZhciBtYXRjaGVzID1cbiAgICAvKiogQHR5cGUge0FycmF5PEhpdE1hdGNoPFQ+Pn0gKi9cbiAgICBbXTtcbiAgICB2YXIgdG1wQ29vcmQgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2Zmc2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgZm9yICh2YXIgaiA9IG51bUxheWVycyAtIDE7IGogPj0gMDsgLS1qKSB7XG4gICAgICAgIHZhciBsYXllclN0YXRlID0gbGF5ZXJTdGF0ZXNbal07XG4gICAgICAgIHZhciBsYXllciA9IGxheWVyU3RhdGUubGF5ZXI7XG5cbiAgICAgICAgaWYgKGxheWVyLmhhc1JlbmRlcmVyKCkgJiYgaW5WaWV3KGxheWVyU3RhdGUsIHZpZXdTdGF0ZSkgJiYgbGF5ZXJGaWx0ZXIuY2FsbCh0aGlzQXJnMiwgbGF5ZXIpKSB7XG4gICAgICAgICAgdmFyIGxheWVyUmVuZGVyZXIgPSBsYXllci5nZXRSZW5kZXJlcigpO1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcblxuICAgICAgICAgIGlmIChsYXllclJlbmRlcmVyICYmIHNvdXJjZSkge1xuICAgICAgICAgICAgdmFyIGNvb3JkaW5hdGVzID0gc291cmNlLmdldFdyYXBYKCkgPyB0cmFuc2xhdGVkQ29vcmRpbmF0ZSA6IGNvb3JkaW5hdGU7XG4gICAgICAgICAgICB2YXIgY2FsbGJhY2tfMSA9IGZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlLmJpbmQobnVsbCwgbGF5ZXJTdGF0ZS5tYW5hZ2VkKTtcbiAgICAgICAgICAgIHRtcENvb3JkWzBdID0gY29vcmRpbmF0ZXNbMF0gKyBvZmZzZXRzW2ldWzBdO1xuICAgICAgICAgICAgdG1wQ29vcmRbMV0gPSBjb29yZGluYXRlc1sxXSArIG9mZnNldHNbaV1bMV07XG4gICAgICAgICAgICByZXN1bHQgPSBsYXllclJlbmRlcmVyLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlKHRtcENvb3JkLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrXzEsIG1hdGNoZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1hdGNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHZhciBvcmRlciA9IDEgLyBtYXRjaGVzLmxlbmd0aDtcbiAgICBtYXRjaGVzLmZvckVhY2goZnVuY3Rpb24gKG0sIGkpIHtcbiAgICAgIHJldHVybiBtLmRpc3RhbmNlU3EgKz0gaSAqIG9yZGVyO1xuICAgIH0pO1xuICAgIG1hdGNoZXMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEuZGlzdGFuY2VTcSAtIGIuZGlzdGFuY2VTcTtcbiAgICB9KTtcbiAgICBtYXRjaGVzLnNvbWUoZnVuY3Rpb24gKG0pIHtcbiAgICAgIHJldHVybiByZXN1bHQgPSBtLmNhbGxiYWNrKG0uZmVhdHVyZSwgbS5sYXllciwgbS5nZW9tZXRyeSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZVN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQsIChVaW50OENsYW1wZWRBcnJheXxVaW50OEFycmF5KSk6IFR9IGNhbGxiYWNrIExheWVyXG4gICAqICAgICBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0KTogYm9vbGVhbn0gbGF5ZXJGaWx0ZXIgTGF5ZXIgZmlsdGVyXG4gICAqICAgICBmdW5jdGlvbiwgb25seSBsYXllcnMgd2hpY2ggYXJlIHZpc2libGUgYW5kIGZvciB3aGljaCB0aGlzIGZ1bmN0aW9uXG4gICAqICAgICByZXR1cm5zIGB0cnVlYCB3aWxsIGJlIHRlc3RlZCBmb3IgZmVhdHVyZXMuICBCeSBkZWZhdWx0LCBhbGwgdmlzaWJsZVxuICAgKiAgICAgbGF5ZXJzIHdpbGwgYmUgdGVzdGVkLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIE1hcFJlbmRlcmVyLnByb3RvdHlwZS5mb3JFYWNoTGF5ZXJBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBsYXllckZpbHRlcikge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZVN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGNoZWNrV3JhcHBlZCBDaGVjayBmb3Igd3JhcHBlZCBnZW9tZXRyaWVzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6IFUsIGltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHQpOiBib29sZWFufSBsYXllckZpbHRlciBMYXllciBmaWx0ZXJcbiAgICogICAgIGZ1bmN0aW9uLCBvbmx5IGxheWVycyB3aGljaCBhcmUgdmlzaWJsZSBhbmQgZm9yIHdoaWNoIHRoaXMgZnVuY3Rpb25cbiAgICogICAgIHJldHVybnMgYHRydWVgIHdpbGwgYmUgdGVzdGVkIGZvciBmZWF0dXJlcy4gIEJ5IGRlZmF1bHQsIGFsbCB2aXNpYmxlXG4gICAqICAgICBsYXllcnMgd2lsbCBiZSB0ZXN0ZWQuXG4gICAqIEBwYXJhbSB7VX0gdGhpc0FyZyBWYWx1ZSB0byB1c2UgYXMgYHRoaXNgIHdoZW4gZXhlY3V0aW5nIGBsYXllckZpbHRlcmAuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElzIHRoZXJlIGEgZmVhdHVyZSBhdCB0aGUgZ2l2ZW4gY29vcmRpbmF0ZT9cbiAgICogQHRlbXBsYXRlIFVcbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUuaGFzRmVhdHVyZUF0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNoZWNrV3JhcHBlZCwgbGF5ZXJGaWx0ZXIsIHRoaXNBcmcpIHtcbiAgICB2YXIgaGFzRmVhdHVyZSA9IHRoaXMuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUoY29vcmRpbmF0ZSwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlLCBjaGVja1dyYXBwZWQsIFRSVUUsIHRoaXMsIGxheWVyRmlsdGVyLCB0aGlzQXJnKTtcbiAgICByZXR1cm4gaGFzRmVhdHVyZSAhPT0gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IE1hcC5cbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1hcF87XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0gez9pbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBNYXBSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTWFwUmVuZGVyZXIucHJvdG90eXBlLnNjaGVkdWxlRXhwaXJlSWNvbkNhY2hlID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICBpZiAoaWNvbkltYWdlQ2FjaGUuY2FuRXhwaXJlQ2FjaGUoKSkge1xuICAgICAgZnJhbWVTdGF0ZS5wb3N0UmVuZGVyRnVuY3Rpb25zLnB1c2goZXhwaXJlSWNvbkNhY2hlKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIE1hcFJlbmRlcmVyO1xufShEaXNwb3NhYmxlKTtcbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gKi9cblxuXG5mdW5jdGlvbiBleHBpcmVJY29uQ2FjaGUobWFwLCBmcmFtZVN0YXRlKSB7XG4gIGljb25JbWFnZUNhY2hlLmV4cGlyZSgpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBNYXBSZW5kZXJlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL0V2ZW50XG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBFdmVudCBmcm9tICcuLi9ldmVudHMvRXZlbnQuanMnO1xuXG52YXIgUmVuZGVyRXZlbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUmVuZGVyRXZlbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRXZlbnRUeXBlLmpzXCIpLmRlZmF1bHR9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtPX0gb3B0X2ludmVyc2VQaXhlbFRyYW5zZm9ybSBUcmFuc2Zvcm0gZm9yXG4gICAqICAgICBDU1MgcGl4ZWxzIHRvIHJlbmRlcmVkIHBpeGVscy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZT19IG9wdF9mcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0gez9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQ9fSBvcHRfY29udGV4dCBDb250ZXh0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFJlbmRlckV2ZW50KHR5cGUsIG9wdF9pbnZlcnNlUGl4ZWxUcmFuc2Zvcm0sIG9wdF9mcmFtZVN0YXRlLCBvcHRfY29udGV4dCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHR5cGUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtIGZyb20gQ1NTIHBpeGVscyAocmVsYXRpdmUgdG8gdGhlIHRvcC1sZWZ0IGNvcm5lciBvZiB0aGUgbWFwIHZpZXdwb3J0KVxuICAgICAqIHRvIHJlbmRlcmVkIHBpeGVscyBvbiB0aGlzIGV2ZW50J3MgYGNvbnRleHRgLiBPbmx5IGF2YWlsYWJsZSB3aGVuIGEgQ2FudmFzIHJlbmRlcmVyIGlzIHVzZWQsIG51bGwgb3RoZXJ3aXNlLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cblxuICAgIF90aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSA9IG9wdF9pbnZlcnNlUGl4ZWxUcmFuc2Zvcm07XG4gICAgLyoqXG4gICAgICogQW4gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY3VycmVudCByZW5kZXIgZnJhbWUgc3RhdGUuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICBfdGhpcy5mcmFtZVN0YXRlID0gb3B0X2ZyYW1lU3RhdGU7XG4gICAgLyoqXG4gICAgICogQ2FudmFzIGNvbnRleHQuIE5vdCBhdmFpbGFibGUgd2hlbiB0aGUgZXZlbnQgaXMgZGlzcGF0Y2hlZCBieSB0aGUgbWFwLiBPbmx5IGF2YWlsYWJsZVxuICAgICAqIHdoZW4gYSBDYW52YXMgcmVuZGVyZXIgaXMgdXNlZCwgbnVsbCBvdGhlcndpc2UuXG4gICAgICogQHR5cGUge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRHxudWxsfHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0ID0gb3B0X2NvbnRleHQ7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFJlbmRlckV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlckV2ZW50OyIsIi8qKlxuICogQG1vZHVsZSBvbC9jc3NcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEZvbnRQYXJhbWV0ZXJzXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc3R5bGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB2YXJpYW50XG4gKiBAcHJvcGVydHkge3N0cmluZ30gd2VpZ2h0XG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2l6ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGxpbmVIZWlnaHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmYW1pbHlcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gZmFtaWxpZXNcbiAqL1xuXG4vKipcbiAqIFRoZSBDU1MgY2xhc3MgZm9yIGhpZGRlbiBmZWF0dXJlLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IHZhciBDTEFTU19ISURERU4gPSAnb2wtaGlkZGVuJztcbi8qKlxuICogVGhlIENTUyBjbGFzcyB0aGF0IHdlJ2xsIGdpdmUgdGhlIERPTSBlbGVtZW50cyB0byBoYXZlIHRoZW0gc2VsZWN0YWJsZS5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBDTEFTU19TRUxFQ1RBQkxFID0gJ29sLXNlbGVjdGFibGUnO1xuLyoqXG4gKiBUaGUgQ1NTIGNsYXNzIHRoYXQgd2UnbGwgZ2l2ZSB0aGUgRE9NIGVsZW1lbnRzIHRvIGhhdmUgdGhlbSB1bnNlbGVjdGFibGUuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgQ0xBU1NfVU5TRUxFQ1RBQkxFID0gJ29sLXVuc2VsZWN0YWJsZSc7XG4vKipcbiAqIFRoZSBDU1MgY2xhc3MgZm9yIHVuc3VwcG9ydGVkIGZlYXR1cmUuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgQ0xBU1NfVU5TVVBQT1JURUQgPSAnb2wtdW5zdXBwb3J0ZWQnO1xuLyoqXG4gKiBUaGUgQ1NTIGNsYXNzIGZvciBjb250cm9scy5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBDTEFTU19DT05UUk9MID0gJ29sLWNvbnRyb2wnO1xuLyoqXG4gKiBUaGUgQ1NTIGNsYXNzIHRoYXQgd2UnbGwgZ2l2ZSB0aGUgRE9NIGVsZW1lbnRzIHRoYXQgYXJlIGNvbGxhcHNlZCwgaS5lLlxuICogdG8gdGhvc2UgZWxlbWVudHMgd2hpY2ggdXN1YWxseSBjYW4gYmUgZXhwYW5kZWQuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgQ0xBU1NfQ09MTEFQU0VEID0gJ29sLWNvbGxhcHNlZCc7XG4vKipcbiAqIEZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDEzNTY5Ny9yZWdleC10by1wYXJzZS1hbnktY3NzLWZvbnRcbiAqIEB0eXBlIHtSZWdFeHB9XG4gKi9cblxudmFyIGZvbnRSZWdFeCA9IG5ldyBSZWdFeHAoWydeXFxcXHMqKD89KD86KD86Wy1hLXpdK1xcXFxzKil7MCwyfShpdGFsaWN8b2JsaXF1ZSkpPyknLCAnKD89KD86KD86Wy1hLXpdK1xcXFxzKil7MCwyfShzbWFsbC1jYXBzKSk/KScsICcoPz0oPzooPzpbLWEtel0rXFxcXHMqKXswLDJ9KGJvbGQoPzplcik/fGxpZ2h0ZXJ8WzEtOV0wMCApKT8pJywgJyg/Oig/Om5vcm1hbHxcXFxcMXxcXFxcMnxcXFxcMylcXFxccyopezAsM30oKD86eHg/LSk/JywgJyg/OnNtYWxsfGxhcmdlKXxtZWRpdW18c21hbGxlcnxsYXJnZXJ8W1xcXFwuXFxcXGRdKyg/OlxcXFwlfGlufFtjZW1dbXxleHxwW2N0eF0pKScsICcoPzpcXFxccypcXFxcL1xcXFxzKihub3JtYWx8W1xcXFwuXFxcXGRdKyg/OlxcXFwlfGlufFtjZW1dbXxleHxwW2N0eF0pPykpJywgJz9cXFxccyooWy0sXFxcXFwiXFxcXFxcJ1xcXFxzYS16XSs/KVxcXFxzKiQnXS5qb2luKCcnKSwgJ2knKTtcbnZhciBmb250UmVnRXhNYXRjaEluZGV4ID0gWydzdHlsZScsICd2YXJpYW50JywgJ3dlaWdodCcsICdzaXplJywgJ2xpbmVIZWlnaHQnLCAnZmFtaWx5J107XG4vKipcbiAqIEdldCB0aGUgbGlzdCBvZiBmb250IGZhbWlsaWVzIGZyb20gYSBmb250IHNwZWMuICBOb3RlIHRoYXQgdGhpcyBkb2Vzbid0IHdvcmtcbiAqIGZvciBmb250IGZhbWlsaWVzIHRoYXQgaGF2ZSBjb21tYXMgaW4gdGhlbS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmb250U3BlYyBUaGUgQ1NTIGZvbnQgcHJvcGVydHkuXG4gKiBAcmV0dXJuIHtGb250UGFyYW1ldGVyc30gVGhlIGZvbnQgcGFyYW1ldGVycyAob3IgbnVsbCBpZiB0aGUgaW5wdXQgc3BlYyBpcyBpbnZhbGlkKS5cbiAqL1xuXG5leHBvcnQgdmFyIGdldEZvbnRQYXJhbWV0ZXJzID0gZnVuY3Rpb24gZ2V0Rm9udFBhcmFtZXRlcnMoZm9udFNwZWMpIHtcbiAgdmFyIG1hdGNoID0gZm9udFNwZWMubWF0Y2goZm9udFJlZ0V4KTtcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgc3R5bGUgPVxuICAvKiogQHR5cGUge0ZvbnRQYXJhbWV0ZXJzfSAqL1xuICB7XG4gICAgbGluZUhlaWdodDogJ25vcm1hbCcsXG4gICAgc2l6ZTogJzEuMmVtJyxcbiAgICBzdHlsZTogJ25vcm1hbCcsXG4gICAgd2VpZ2h0OiAnbm9ybWFsJyxcbiAgICB2YXJpYW50OiAnbm9ybWFsJ1xuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGZvbnRSZWdFeE1hdGNoSW5kZXgubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciB2YWx1ZSA9IG1hdGNoW2kgKyAxXTtcblxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBzdHlsZVtmb250UmVnRXhNYXRjaEluZGV4W2ldXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHN0eWxlLmZhbWlsaWVzID0gc3R5bGUuZmFtaWx5LnNwbGl0KC8sXFxzPy8pO1xuICByZXR1cm4gc3R5bGU7XG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9oYXNcbiAqL1xudmFyIHVhID0gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvci51c2VyQWdlbnQgIT09ICd1bmRlZmluZWQnID8gbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpIDogJyc7XG4vKipcbiAqIFVzZXIgYWdlbnQgc3RyaW5nIHNheXMgd2UgYXJlIGRlYWxpbmcgd2l0aCBGaXJlZm94IGFzIGJyb3dzZXIuXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIEZJUkVGT1ggPSB1YS5pbmRleE9mKCdmaXJlZm94JykgIT09IC0xO1xuLyoqXG4gKiBVc2VyIGFnZW50IHN0cmluZyBzYXlzIHdlIGFyZSBkZWFsaW5nIHdpdGggU2FmYXJpIGFzIGJyb3dzZXIuXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIFNBRkFSSSA9IHVhLmluZGV4T2YoJ3NhZmFyaScpICE9PSAtMSAmJiB1YS5pbmRleE9mKCdjaHJvbScpID09IC0xO1xuLyoqXG4gKiBVc2VyIGFnZW50IHN0cmluZyBzYXlzIHdlIGFyZSBkZWFsaW5nIHdpdGggYSBXZWJLaXQgZW5naW5lLlxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBXRUJLSVQgPSB1YS5pbmRleE9mKCd3ZWJraXQnKSAhPT0gLTEgJiYgdWEuaW5kZXhPZignZWRnZScpID09IC0xO1xuLyoqXG4gKiBVc2VyIGFnZW50IHN0cmluZyBzYXlzIHdlIGFyZSBkZWFsaW5nIHdpdGggYSBNYWMgYXMgcGxhdGZvcm0uXG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIE1BQyA9IHVhLmluZGV4T2YoJ21hY2ludG9zaCcpICE9PSAtMTtcbi8qKlxuICogVGhlIHJhdGlvIGJldHdlZW4gcGh5c2ljYWwgcGl4ZWxzIGFuZCBkZXZpY2UtaW5kZXBlbmRlbnQgcGl4ZWxzXG4gKiAoZGlwcykgb24gdGhlIGRldmljZSAoYHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvYCkuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBERVZJQ0VfUElYRUxfUkFUSU8gPSB0eXBlb2YgZGV2aWNlUGl4ZWxSYXRpbyAhPT0gJ3VuZGVmaW5lZCcgPyBkZXZpY2VQaXhlbFJhdGlvIDogMTtcbi8qKlxuICogVGhlIGV4ZWN1dGlvbiBjb250ZXh0IGlzIGEgd29ya2VyIHdpdGggT2Zmc2NyZWVuQ2FudmFzIGF2YWlsYWJsZS5cbiAqIEBjb25zdFxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyA9IHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIE9mZnNjcmVlbkNhbnZhcyAhPT0gJ3VuZGVmaW5lZCcgJiYgc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlOyAvL2VzbGludC1kaXNhYmxlLWxpbmVcblxuLyoqXG4gKiBJbWFnZS5wcm90b3R5cGUuZGVjb2RlKCkgaXMgc3VwcG9ydGVkLlxuICogQHR5cGUge2Jvb2xlYW59XG4gKi9cblxuZXhwb3J0IHZhciBJTUFHRV9ERUNPREUgPSB0eXBlb2YgSW1hZ2UgIT09ICd1bmRlZmluZWQnICYmIEltYWdlLnByb3RvdHlwZS5kZWNvZGU7XG4vKipcbiAqIEB0eXBlIHtib29sZWFufVxuICovXG5cbmV4cG9ydCB2YXIgUEFTU0lWRV9FVkVOVF9MSVNURU5FUlMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBwYXNzaXZlID0gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgb3B0aW9ucyA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh7fSwgJ3Bhc3NpdmUnLCB7XG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgcGFzc2l2ZSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ18nLCBudWxsLCBvcHRpb25zKTtcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignXycsIG51bGwsIG9wdGlvbnMpO1xuICB9IGNhdGNoIChlcnJvcikgey8vIHBhc3NpdmUgbm90IHN1cHBvcnRlZFxuICB9XG5cbiAgcmV0dXJuIHBhc3NpdmU7XG59KCk7IiwiaW1wb3J0IHsgV09SS0VSX09GRlNDUkVFTl9DQU5WQVMgfSBmcm9tICcuL2hhcy5qcyc7XG4vKipcbiAqIEBtb2R1bGUgb2wvZG9tXG4gKi9cbi8vRklYTUUgTW92ZSB0aGlzIGZ1bmN0aW9uIHRvIHRoZSBjYW52YXMgbW9kdWxlXG5cbi8qKlxuICogQ3JlYXRlIGFuIGh0bWwgY2FudmFzIGVsZW1lbnQgYW5kIHJldHVybnMgaXRzIDJkIGNvbnRleHQuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF93aWR0aCBDYW52YXMgd2lkdGguXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9oZWlnaHQgQ2FudmFzIGhlaWdodC5cbiAqIEBwYXJhbSB7QXJyYXk8SFRNTENhbnZhc0VsZW1lbnQ+PX0gb3B0X2NhbnZhc1Bvb2wgQ2FudmFzIHBvb2wgdG8gdGFrZSBleGlzdGluZyBjYW52YXMgZnJvbS5cbiAqIEByZXR1cm4ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gVGhlIGNvbnRleHQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNhbnZhc0NvbnRleHQyRChvcHRfd2lkdGgsIG9wdF9oZWlnaHQsIG9wdF9jYW52YXNQb29sKSB7XG4gIHZhciBjYW52YXMgPSBvcHRfY2FudmFzUG9vbCAmJiBvcHRfY2FudmFzUG9vbC5sZW5ndGggPyBvcHRfY2FudmFzUG9vbC5zaGlmdCgpIDogV09SS0VSX09GRlNDUkVFTl9DQU5WQVMgPyBuZXcgT2Zmc2NyZWVuQ2FudmFzKG9wdF93aWR0aCB8fCAzMDAsIG9wdF9oZWlnaHQgfHwgMzAwKSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuXG4gIGlmIChvcHRfd2lkdGgpIHtcbiAgICBjYW52YXMud2lkdGggPSBvcHRfd2lkdGg7XG4gIH1cblxuICBpZiAob3B0X2hlaWdodCkge1xuICAgIGNhbnZhcy5oZWlnaHQgPSBvcHRfaGVpZ2h0O1xuICB9IC8vRklYTUUgQWxsb3cgT2Zmc2NyZWVuQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEIGFzIHJldHVybiB0eXBlXG5cblxuICByZXR1cm4gKFxuICAgIC8qKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSAqL1xuICAgIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpXG4gICk7XG59XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCBjb21wdXRlZCB3aWR0aCBmb3IgdGhlIGdpdmVuIGVsZW1lbnQgaW5jbHVkaW5nIG1hcmdpbixcbiAqIHBhZGRpbmcgYW5kIGJvcmRlci5cbiAqIEVxdWl2YWxlbnQgdG8galF1ZXJ5J3MgYCQoZWwpLm91dGVyV2lkdGgodHJ1ZSlgLlxuICogQHBhcmFtIHshSFRNTEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIHdpZHRoLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvdXRlcldpZHRoKGVsZW1lbnQpIHtcbiAgdmFyIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgdmFyIHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcbiAgd2lkdGggKz0gcGFyc2VJbnQoc3R5bGUubWFyZ2luTGVmdCwgMTApICsgcGFyc2VJbnQoc3R5bGUubWFyZ2luUmlnaHQsIDEwKTtcbiAgcmV0dXJuIHdpZHRoO1xufVxuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgY29tcHV0ZWQgaGVpZ2h0IGZvciB0aGUgZ2l2ZW4gZWxlbWVudCBpbmNsdWRpbmcgbWFyZ2luLFxuICogcGFkZGluZyBhbmQgYm9yZGVyLlxuICogRXF1aXZhbGVudCB0byBqUXVlcnkncyBgJChlbCkub3V0ZXJIZWlnaHQodHJ1ZSlgLlxuICogQHBhcmFtIHshSFRNTEVsZW1lbnR9IGVsZW1lbnQgRWxlbWVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGhlaWdodC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gb3V0ZXJIZWlnaHQoZWxlbWVudCkge1xuICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gIHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gIGhlaWdodCArPSBwYXJzZUludChzdHlsZS5tYXJnaW5Ub3AsIDEwKSArIHBhcnNlSW50KHN0eWxlLm1hcmdpbkJvdHRvbSwgMTApO1xuICByZXR1cm4gaGVpZ2h0O1xufVxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5ld05vZGUgTm9kZSB0byByZXBsYWNlIG9sZCBub2RlXG4gKiBAcGFyYW0ge05vZGV9IG9sZE5vZGUgVGhlIG5vZGUgdG8gYmUgcmVwbGFjZWRcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZU5vZGUobmV3Tm9kZSwgb2xkTm9kZSkge1xuICB2YXIgcGFyZW50ID0gb2xkTm9kZS5wYXJlbnROb2RlO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVwbGFjZUNoaWxkKG5ld05vZGUsIG9sZE5vZGUpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBUaGUgbm9kZSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyB7Tm9kZX0gVGhlIG5vZGUgdGhhdCB3YXMgcmVtb3ZlZCBvciBudWxsLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVOb2RlKG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUgJiYgbm9kZS5wYXJlbnROb2RlID8gbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpIDogbnVsbDtcbn1cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIFRoZSBub2RlIHRvIHJlbW92ZSB0aGUgY2hpbGRyZW4gZnJvbS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlQ2hpbGRyZW4obm9kZSkge1xuICB3aGlsZSAobm9kZS5sYXN0Q2hpbGQpIHtcbiAgICBub2RlLnJlbW92ZUNoaWxkKG5vZGUubGFzdENoaWxkKTtcbiAgfVxufVxuLyoqXG4gKiBUcmFuc2Zvcm0gdGhlIGNoaWxkcmVuIG9mIGEgcGFyZW50IG5vZGUgc28gdGhleSBtYXRjaCB0aGVcbiAqIHByb3ZpZGVkIGxpc3Qgb2YgY2hpbGRyZW4uICBUaGlzIGZ1bmN0aW9uIGFpbXMgdG8gZWZmaWNpZW50bHlcbiAqIHJlbW92ZSwgYWRkLCBhbmQgcmVvcmRlciBjaGlsZCBub2RlcyB3aGlsZSBtYWludGFpbmluZyBhIHNpbXBsZVxuICogaW1wbGVtZW50YXRpb24gKGl0IGlzIG5vdCBndWFyYW50ZWVkIHRvIG1pbmltaXplIERPTSBvcGVyYXRpb25zKS5cbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSBUaGUgcGFyZW50IG5vZGUgd2hvc2UgY2hpbGRyZW4gbmVlZCByZXdvcmtpbmcuXG4gKiBAcGFyYW0ge0FycmF5PE5vZGU+fSBjaGlsZHJlbiBUaGUgZGVzaXJlZCBjaGlsZHJlbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUNoaWxkcmVuKG5vZGUsIGNoaWxkcmVuKSB7XG4gIHZhciBvbGRDaGlsZHJlbiA9IG5vZGUuY2hpbGROb2RlcztcblxuICBmb3IgKHZhciBpID0gMDsgdHJ1ZTsgKytpKSB7XG4gICAgdmFyIG9sZENoaWxkID0gb2xkQ2hpbGRyZW5baV07XG4gICAgdmFyIG5ld0NoaWxkID0gY2hpbGRyZW5baV07IC8vIGNoZWNrIGlmIG91ciB3b3JrIGlzIGRvbmVcblxuICAgIGlmICghb2xkQ2hpbGQgJiYgIW5ld0NoaWxkKSB7XG4gICAgICBicmVhaztcbiAgICB9IC8vIGNoZWNrIGlmIGNoaWxkcmVuIG1hdGNoXG5cblxuICAgIGlmIChvbGRDaGlsZCA9PT0gbmV3Q2hpbGQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gLy8gY2hlY2sgaWYgYSBuZXcgY2hpbGQgbmVlZHMgdG8gYmUgYWRkZWRcblxuXG4gICAgaWYgKCFvbGRDaGlsZCkge1xuICAgICAgbm9kZS5hcHBlbmRDaGlsZChuZXdDaGlsZCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9IC8vIGNoZWNrIGlmIGFuIG9sZCBjaGlsZCBuZWVkcyB0byBiZSByZW1vdmVkXG5cblxuICAgIGlmICghbmV3Q2hpbGQpIHtcbiAgICAgIG5vZGUucmVtb3ZlQ2hpbGQob2xkQ2hpbGQpO1xuICAgICAgLS1pO1xuICAgICAgY29udGludWU7XG4gICAgfSAvLyByZW9yZGVyXG5cblxuICAgIG5vZGUuaW5zZXJ0QmVmb3JlKG5ld0NoaWxkLCBvbGRDaGlsZCk7XG4gIH1cbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhc1xuICovXG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuLi9PYmplY3QuanMnO1xuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4uL2V2ZW50cy9UYXJnZXQuanMnO1xuaW1wb3J0IHsgV09SS0VSX09GRlNDUkVFTl9DQU5WQVMgfSBmcm9tICcuLi9oYXMuanMnO1xuaW1wb3J0IHsgY2xlYXIgfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi4vZG9tLmpzJztcbmltcG9ydCB7IGdldEZvbnRQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vY3NzLmpzJztcbmltcG9ydCB7IHRvU3RyaW5nIH0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRmlsbFN0YXRlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IGZpbGxTdHlsZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgTGFiZWxcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3aWR0aFxuICogQHByb3BlcnR5IHtudW1iZXJ9IGhlaWdodFxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmd8bnVtYmVyPn0gY29udGV4dEluc3RydWN0aW9uc1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRmlsbFN0cm9rZVN0YXRlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IFtjdXJyZW50RmlsbFN0eWxlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBbY3VycmVudFN0cm9rZVN0eWxlXVxuICogQHByb3BlcnR5IHtDYW52YXNMaW5lQ2FwfSBbY3VycmVudExpbmVDYXBdXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IGN1cnJlbnRMaW5lRGFzaFxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjdXJyZW50TGluZURhc2hPZmZzZXRdXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVKb2lufSBbY3VycmVudExpbmVKb2luXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjdXJyZW50TGluZVdpZHRoXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjdXJyZW50TWl0ZXJMaW1pdF1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGFzdFN0cm9rZV1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gW2ZpbGxTdHlsZV1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gW3N0cm9rZVN0eWxlXVxuICogQHByb3BlcnR5IHtDYW52YXNMaW5lQ2FwfSBbbGluZUNhcF1cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gbGluZURhc2hcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZURhc2hPZmZzZXRdXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVKb2lufSBbbGluZUpvaW5dXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVXaWR0aF1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWl0ZXJMaW1pdF1cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFN0cm9rZVN0YXRlXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVDYXB9IGxpbmVDYXBcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gbGluZURhc2hcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsaW5lRGFzaE9mZnNldFxuICogQHByb3BlcnR5IHtDYW52YXNMaW5lSm9pbn0gbGluZUpvaW5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsaW5lV2lkdGhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaXRlckxpbWl0XG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IHN0cm9rZVN0eWxlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUZXh0U3RhdGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmb250XG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3RleHRBbGlnbl1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB0ZXh0QmFzZWxpbmVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbcGxhY2VtZW50XVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhBbmdsZV1cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW292ZXJmbG93XVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zdHlsZS9GaWxsLmpzXCIpLmRlZmF1bHR9IFtiYWNrZ3JvdW5kRmlsbF1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc3R5bGUvU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFtiYWNrZ3JvdW5kU3Ryb2tlXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFtzY2FsZV1cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW3BhZGRpbmddXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTZXJpYWxpemFibGVJbnN0cnVjdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8Kj59IGluc3RydWN0aW9ucyBUaGUgcmVuZGVyaW5nIGluc3RydWN0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8Kj59IGhpdERldGVjdGlvbkluc3RydWN0aW9ucyBUaGUgcmVuZGVyaW5nIGhpdCBkZXRlY3Rpb24gaW5zdHJ1Y3Rpb25zLlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBjb29yZGluYXRlcyBUaGUgYXJyYXkgb2YgYWxsIGNvb3JkaW5hdGVzLlxuICogQHByb3BlcnR5IHshT2JqZWN0PHN0cmluZywgVGV4dFN0YXRlPn0gW3RleHRTdGF0ZXNdIFRoZSB0ZXh0IHN0YXRlcyAoZGVjbHV0dGVyaW5nKS5cbiAqIEBwcm9wZXJ0eSB7IU9iamVjdDxzdHJpbmcsIEZpbGxTdGF0ZT59IFtmaWxsU3RhdGVzXSBUaGUgZmlsbCBzdGF0ZXMgKGRlY2x1dHRlcmluZykuXG4gKiBAcHJvcGVydHkgeyFPYmplY3Q8c3RyaW5nLCBTdHJva2VTdGF0ZT59IFtzdHJva2VTdGF0ZXNdIFRoZSBzdHJva2Ugc3RhdGVzIChkZWNsdXR0ZXJpbmcpLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdDxudW1iZXIsIGltcG9ydChcIi4vY2FudmFzL0V4ZWN1dG9yLmpzXCIpLlJlcGxheUltYWdlT3JMYWJlbEFyZ3M+fSBEZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XG4gKi9cblxuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0Rm9udCA9ICcxMHB4IHNhbnMtc2VyaWYnO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdEZpbGxTdHlsZSA9ICcjMDAwJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7Q2FudmFzTGluZUNhcH1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRMaW5lQ2FwID0gJ3JvdW5kJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRMaW5lRGFzaCA9IFtdO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0TGluZURhc2hPZmZzZXQgPSAwO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtDYW52YXNMaW5lSm9pbn1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRMaW5lSm9pbiA9ICdyb3VuZCc7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRNaXRlckxpbWl0ID0gMTA7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9XG4gKi9cblxuZXhwb3J0IHZhciBkZWZhdWx0U3Ryb2tlU3R5bGUgPSAnIzAwMCc7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRUZXh0QWxpZ24gPSAnY2VudGVyJztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdFRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICovXG5cbmV4cG9ydCB2YXIgZGVmYXVsdFBhZGRpbmcgPSBbMCwgMCwgMCwgMF07XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIGRlZmF1bHRMaW5lV2lkdGggPSAxO1xuLyoqXG4gKiBAdHlwZSB7QmFzZU9iamVjdH1cbiAqL1xuXG5leHBvcnQgdmFyIGNoZWNrZWRGb250cyA9IG5ldyBCYXNlT2JqZWN0KCk7XG4vKipcbiAqIFRoZSBsYWJlbCBjYWNoZSBmb3IgdGV4dCByZW5kZXJpbmcuIFRvIGNoYW5nZSB0aGUgZGVmYXVsdCBjYWNoZSBzaXplIG9mIDIwNDhcbiAqIGVudHJpZXMsIHVzZSB7QGxpbmsgbW9kdWxlOm9sL3N0cnVjdHMvTFJVQ2FjaGUjc2V0U2l6ZX0uXG4gKiBEZXByZWNhdGVkIC0gdGhlcmUgaXMgbm8gbGFiZWwgY2FjaGUgYW55IG1vcmUuXG4gKiBAdHlwZSB7P31cbiAqIEBhcGlcbiAqIEBkZXByZWNhdGVkXG4gKi9cblxuZXhwb3J0IHZhciBsYWJlbENhY2hlID0gbmV3IEV2ZW50VGFyZ2V0KCk7XG5cbmxhYmVsQ2FjaGUuc2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc29sZS53YXJuKCdsYWJlbENhY2hlIGlzIGRlcHJlY2F0ZWQuJyk7IC8vZXNsaW50LWRpc2FibGUtbGluZVxufTtcbi8qKlxuICogQHR5cGUge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH1cbiAqL1xuXG5cbnZhciBtZWFzdXJlQ29udGV4dCA9IG51bGw7XG4vKipcbiAqIEB0eXBlIHtzdHJpbmd9XG4gKi9cblxudmFyIG1lYXN1cmVGb250O1xuLyoqXG4gKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIG51bWJlcj59XG4gKi9cblxuZXhwb3J0IHZhciB0ZXh0SGVpZ2h0cyA9IHt9O1xuLyoqXG4gKiBDbGVhcnMgdGhlIGxhYmVsIGNhY2hlIHdoZW4gYSBmb250IGJlY29tZXMgYXZhaWxhYmxlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnRTcGVjIENTUyBmb250IHNwZWMuXG4gKi9cblxuZXhwb3J0IHZhciByZWdpc3RlckZvbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciByZXRyaWVzID0gMTAwO1xuICB2YXIgc2l6ZSA9ICczMnB4ICc7XG4gIHZhciByZWZlcmVuY2VGb250cyA9IFsnbW9ub3NwYWNlJywgJ3NlcmlmJ107XG4gIHZhciBsZW4gPSByZWZlcmVuY2VGb250cy5sZW5ndGg7XG4gIHZhciB0ZXh0ID0gXCJ3bXl0emlsV01ZVFpJTEAjLyY/JCUxMFxcdUYwMTNcIjtcbiAgdmFyIGludGVydmFsLCByZWZlcmVuY2VXaWR0aDtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmb250U3R5bGUgQ3NzIGZvbnQtc3R5bGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZvbnRXZWlnaHQgQ3NzIGZvbnQtd2VpZ2h0XG4gICAqIEBwYXJhbSB7Kn0gZm9udEZhbWlseSBDc3MgZm9udC1mYW1pbHlcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gRm9udCB3aXRoIHN0eWxlIGFuZCB3ZWlnaHQgaXMgYXZhaWxhYmxlXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGlzQXZhaWxhYmxlKGZvbnRTdHlsZSwgZm9udFdlaWdodCwgZm9udEZhbWlseSkge1xuICAgIHZhciBhdmFpbGFibGUgPSB0cnVlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgdmFyIHJlZmVyZW5jZUZvbnQgPSByZWZlcmVuY2VGb250c1tpXTtcbiAgICAgIHJlZmVyZW5jZVdpZHRoID0gbWVhc3VyZVRleHRXaWR0aChmb250U3R5bGUgKyAnICcgKyBmb250V2VpZ2h0ICsgJyAnICsgc2l6ZSArIHJlZmVyZW5jZUZvbnQsIHRleHQpO1xuXG4gICAgICBpZiAoZm9udEZhbWlseSAhPSByZWZlcmVuY2VGb250KSB7XG4gICAgICAgIHZhciB3aWR0aCA9IG1lYXN1cmVUZXh0V2lkdGgoZm9udFN0eWxlICsgJyAnICsgZm9udFdlaWdodCArICcgJyArIHNpemUgKyBmb250RmFtaWx5ICsgJywnICsgcmVmZXJlbmNlRm9udCwgdGV4dCk7IC8vIElmIHdpZHRoIGFuZCByZWZlcmVuY2VXaWR0aCBhcmUgdGhlIHNhbWUsIHRoZW4gdGhlIGZhbGxiYWNrIHdhcyB1c2VkXG4gICAgICAgIC8vIGluc3RlYWQgb2YgdGhlIGZvbnQgd2Ugd2FudGVkLCBzbyB0aGUgZm9udCBpcyBub3QgYXZhaWxhYmxlLlxuXG4gICAgICAgIGF2YWlsYWJsZSA9IGF2YWlsYWJsZSAmJiB3aWR0aCAhPSByZWZlcmVuY2VXaWR0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXZhaWxhYmxlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBjaGVjaygpIHtcbiAgICB2YXIgZG9uZSA9IHRydWU7XG4gICAgdmFyIGZvbnRzID0gY2hlY2tlZEZvbnRzLmdldEtleXMoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZvbnRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBmb250ID0gZm9udHNbaV07XG5cbiAgICAgIGlmIChjaGVja2VkRm9udHMuZ2V0KGZvbnQpIDwgcmV0cmllcykge1xuICAgICAgICBpZiAoaXNBdmFpbGFibGUuYXBwbHkodGhpcywgZm9udC5zcGxpdCgnXFxuJykpKSB7XG4gICAgICAgICAgY2xlYXIodGV4dEhlaWdodHMpOyAvLyBNYWtlIHN1cmUgdGhhdCBsb2FkZWQgZm9udHMgYXJlIHBpY2tlZCB1cCBieSBTYWZhcmlcblxuICAgICAgICAgIG1lYXN1cmVDb250ZXh0ID0gbnVsbDtcbiAgICAgICAgICBtZWFzdXJlRm9udCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBjaGVja2VkRm9udHMuc2V0KGZvbnQsIHJldHJpZXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNoZWNrZWRGb250cy5zZXQoZm9udCwgY2hlY2tlZEZvbnRzLmdldChmb250KSArIDEsIHRydWUpO1xuICAgICAgICAgIGRvbmUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkb25lKSB7XG4gICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgICAgIGludGVydmFsID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZm9udFNwZWMpIHtcbiAgICB2YXIgZm9udCA9IGdldEZvbnRQYXJhbWV0ZXJzKGZvbnRTcGVjKTtcblxuICAgIGlmICghZm9udCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBmYW1pbGllcyA9IGZvbnQuZmFtaWxpZXM7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBmYW1pbGllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZmFtaWx5ID0gZmFtaWxpZXNbaV07XG4gICAgICB2YXIga2V5ID0gZm9udC5zdHlsZSArICdcXG4nICsgZm9udC53ZWlnaHQgKyAnXFxuJyArIGZhbWlseTtcblxuICAgICAgaWYgKGNoZWNrZWRGb250cy5nZXQoa2V5KSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNoZWNrZWRGb250cy5zZXQoa2V5LCByZXRyaWVzLCB0cnVlKTtcblxuICAgICAgICBpZiAoIWlzQXZhaWxhYmxlKGZvbnQuc3R5bGUsIGZvbnQud2VpZ2h0LCBmYW1pbHkpKSB7XG4gICAgICAgICAgY2hlY2tlZEZvbnRzLnNldChrZXksIDAsIHRydWUpO1xuXG4gICAgICAgICAgaWYgKGludGVydmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGludGVydmFsID0gc2V0SW50ZXJ2YWwoY2hlY2ssIDMyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG59KCk7XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBmb250IEZvbnQgdG8gdXNlIGZvciBtZWFzdXJpbmcuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IE1lYXN1cmVtZW50LlxuICovXG5cbmV4cG9ydCB2YXIgbWVhc3VyZVRleHRIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAdHlwZSB7SFRNTERpdkVsZW1lbnR9XG4gICAqL1xuICB2YXIgZGl2O1xuICByZXR1cm4gZnVuY3Rpb24gKGZvbnRTcGVjKSB7XG4gICAgdmFyIGhlaWdodCA9IHRleHRIZWlnaHRzW2ZvbnRTcGVjXTtcblxuICAgIGlmIChoZWlnaHQgPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoV09SS0VSX09GRlNDUkVFTl9DQU5WQVMpIHtcbiAgICAgICAgdmFyIGZvbnQgPSBnZXRGb250UGFyYW1ldGVycyhmb250U3BlYyk7XG4gICAgICAgIHZhciBtZXRyaWNzID0gbWVhc3VyZVRleHQoZm9udFNwZWMsICfFvWcnKTtcbiAgICAgICAgdmFyIGxpbmVIZWlnaHQgPSBpc05hTihOdW1iZXIoZm9udC5saW5lSGVpZ2h0KSkgPyAxLjIgOiBOdW1iZXIoZm9udC5saW5lSGVpZ2h0KTtcbiAgICAgICAgaGVpZ2h0ID0gbGluZUhlaWdodCAqIChtZXRyaWNzLmFjdHVhbEJvdW5kaW5nQm94QXNjZW50ICsgbWV0cmljcy5hY3R1YWxCb3VuZGluZ0JveERlc2NlbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCFkaXYpIHtcbiAgICAgICAgICBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gJ00nO1xuICAgICAgICAgIGRpdi5zdHlsZS5tYXJnaW4gPSAnMCAhaW1wb3J0YW50JztcbiAgICAgICAgICBkaXYuc3R5bGUucGFkZGluZyA9ICcwICFpbXBvcnRhbnQnO1xuICAgICAgICAgIGRpdi5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSAhaW1wb3J0YW50JztcbiAgICAgICAgICBkaXYuc3R5bGUubGVmdCA9ICctOTk5OTlweCAhaW1wb3J0YW50JztcbiAgICAgICAgfVxuXG4gICAgICAgIGRpdi5zdHlsZS5mb250ID0gZm9udFNwZWM7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2KTtcbiAgICAgICAgaGVpZ2h0ID0gZGl2Lm9mZnNldEhlaWdodDtcbiAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChkaXYpO1xuICAgICAgfVxuXG4gICAgICB0ZXh0SGVpZ2h0c1tmb250U3BlY10gPSBoZWlnaHQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhlaWdodDtcbiAgfTtcbn0oKTtcbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgRm9udC5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQuXG4gKiBAcmV0dXJuIHtUZXh0TWV0cmljc30gVGV4dCBtZXRyaWNzLlxuICovXG5cbmZ1bmN0aW9uIG1lYXN1cmVUZXh0KGZvbnQsIHRleHQpIHtcbiAgaWYgKCFtZWFzdXJlQ29udGV4dCkge1xuICAgIG1lYXN1cmVDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEpO1xuICB9XG5cbiAgaWYgKGZvbnQgIT0gbWVhc3VyZUZvbnQpIHtcbiAgICBtZWFzdXJlQ29udGV4dC5mb250ID0gZm9udDtcbiAgICBtZWFzdXJlRm9udCA9IG1lYXN1cmVDb250ZXh0LmZvbnQ7XG4gIH1cblxuICByZXR1cm4gbWVhc3VyZUNvbnRleHQubWVhc3VyZVRleHQodGV4dCk7XG59XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBmb250IEZvbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXh0LlxuICogQHJldHVybiB7bnVtYmVyfSBXaWR0aC5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBtZWFzdXJlVGV4dFdpZHRoKGZvbnQsIHRleHQpIHtcbiAgcmV0dXJuIG1lYXN1cmVUZXh0KGZvbnQsIHRleHQpLndpZHRoO1xufVxuLyoqXG4gKiBNZWFzdXJlIHRleHQgd2lkdGggdXNpbmcgYSBjYWNoZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmb250IFRoZSBmb250LlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gbWVhc3VyZS5cbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgbnVtYmVyPn0gY2FjaGUgQSBsb29rdXAgb2YgY2FjaGVkIHdpZHRocyBieSB0ZXh0LlxuICogQHJldHVybnMge251bWJlcn0gVGhlIHRleHQgd2lkdGguXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aChmb250LCB0ZXh0LCBjYWNoZSkge1xuICBpZiAodGV4dCBpbiBjYWNoZSkge1xuICAgIHJldHVybiBjYWNoZVt0ZXh0XTtcbiAgfVxuXG4gIHZhciB3aWR0aCA9IG1lYXN1cmVUZXh0V2lkdGgoZm9udCwgdGV4dCk7XG4gIGNhY2hlW3RleHRdID0gd2lkdGg7XG4gIHJldHVybiB3aWR0aDtcbn1cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgRm9udCB0byB1c2UgZm9yIG1lYXN1cmluZy5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gbGluZXMgTGluZXMgdG8gbWVhc3VyZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gd2lkdGhzIEFycmF5IHdpbGwgYmUgcG9wdWxhdGVkIHdpdGggdGhlIHdpZHRocyBvZlxuICogZWFjaCBsaW5lLlxuICogQHJldHVybiB7bnVtYmVyfSBXaWR0aCBvZiB0aGUgd2hvbGUgdGV4dC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbWVhc3VyZVRleHRXaWR0aHMoZm9udCwgbGluZXMsIHdpZHRocykge1xuICB2YXIgbnVtTGluZXMgPSBsaW5lcy5sZW5ndGg7XG4gIHZhciB3aWR0aCA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1MaW5lczsgKytpKSB7XG4gICAgdmFyIGN1cnJlbnRXaWR0aCA9IG1lYXN1cmVUZXh0V2lkdGgoZm9udCwgbGluZXNbaV0pO1xuICAgIHdpZHRoID0gTWF0aC5tYXgod2lkdGgsIGN1cnJlbnRXaWR0aCk7XG4gICAgd2lkdGhzLnB1c2goY3VycmVudFdpZHRoKTtcbiAgfVxuXG4gIHJldHVybiB3aWR0aDtcbn1cbi8qKlxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRYIFggb2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFkgWSBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZUF0T2Zmc2V0KGNvbnRleHQsIHJvdGF0aW9uLCBvZmZzZXRYLCBvZmZzZXRZKSB7XG4gIGlmIChyb3RhdGlvbiAhPT0gMCkge1xuICAgIGNvbnRleHQudHJhbnNsYXRlKG9mZnNldFgsIG9mZnNldFkpO1xuICAgIGNvbnRleHQucm90YXRlKHJvdGF0aW9uKTtcbiAgICBjb250ZXh0LnRyYW5zbGF0ZSgtb2Zmc2V0WCwgLW9mZnNldFkpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm18bnVsbH0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gKiBAcGFyYW0ge0xhYmVsfEhUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gbGFiZWxPckltYWdlIExhYmVsLlxuICogQHBhcmFtIHtudW1iZXJ9IG9yaWdpblggT3JpZ2luIFguXG4gKiBAcGFyYW0ge251bWJlcn0gb3JpZ2luWSBPcmlnaW4gWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB3IFdpZHRoLlxuICogQHBhcmFtIHtudW1iZXJ9IGggSGVpZ2h0LlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gc2NhbGUgU2NhbGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRyYXdJbWFnZU9yTGFiZWwoY29udGV4dCwgdHJhbnNmb3JtLCBvcGFjaXR5LCBsYWJlbE9ySW1hZ2UsIG9yaWdpblgsIG9yaWdpblksIHcsIGgsIHgsIHksIHNjYWxlKSB7XG4gIGNvbnRleHQuc2F2ZSgpO1xuXG4gIGlmIChvcGFjaXR5ICE9PSAxKSB7XG4gICAgY29udGV4dC5nbG9iYWxBbHBoYSAqPSBvcGFjaXR5O1xuICB9XG5cbiAgaWYgKHRyYW5zZm9ybSkge1xuICAgIGNvbnRleHQuc2V0VHJhbnNmb3JtLmFwcGx5KGNvbnRleHQsIHRyYW5zZm9ybSk7XG4gIH1cblxuICBpZiAoXG4gIC8qKiBAdHlwZSB7Kn0gKi9cbiAgbGFiZWxPckltYWdlLmNvbnRleHRJbnN0cnVjdGlvbnMpIHtcbiAgICAvLyBsYWJlbFxuICAgIGNvbnRleHQudHJhbnNsYXRlKHgsIHkpO1xuICAgIGNvbnRleHQuc2NhbGUoc2NhbGVbMF0sIHNjYWxlWzFdKTtcbiAgICBleGVjdXRlTGFiZWxJbnN0cnVjdGlvbnMoXG4gICAgLyoqIEB0eXBlIHtMYWJlbH0gKi9cbiAgICBsYWJlbE9ySW1hZ2UsIGNvbnRleHQpO1xuICB9IGVsc2UgaWYgKHNjYWxlWzBdIDwgMCB8fCBzY2FsZVsxXSA8IDApIHtcbiAgICAvLyBmbGlwcGVkIGltYWdlXG4gICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgY29udGV4dC5zY2FsZShzY2FsZVswXSwgc2NhbGVbMV0pO1xuICAgIGNvbnRleHQuZHJhd0ltYWdlKFxuICAgIC8qKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSAqL1xuICAgIGxhYmVsT3JJbWFnZSwgb3JpZ2luWCwgb3JpZ2luWSwgdywgaCwgMCwgMCwgdywgaCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gaWYgaW1hZ2Ugbm90IGZsaXBwZWQgdHJhbnNsYXRlIGFuZCBzY2FsZSBjYW4gYmUgYXZvaWRlZFxuICAgIGNvbnRleHQuZHJhd0ltYWdlKFxuICAgIC8qKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSAqL1xuICAgIGxhYmVsT3JJbWFnZSwgb3JpZ2luWCwgb3JpZ2luWSwgdywgaCwgeCwgeSwgdyAqIHNjYWxlWzBdLCBoICogc2NhbGVbMV0pO1xuICB9XG5cbiAgY29udGV4dC5yZXN0b3JlKCk7XG59XG4vKipcbiAqIEBwYXJhbSB7TGFiZWx9IGxhYmVsIExhYmVsLlxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAqL1xuXG5mdW5jdGlvbiBleGVjdXRlTGFiZWxJbnN0cnVjdGlvbnMobGFiZWwsIGNvbnRleHQpIHtcbiAgdmFyIGNvbnRleHRJbnN0cnVjdGlvbnMgPSBsYWJlbC5jb250ZXh0SW5zdHJ1Y3Rpb25zO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvbnRleHRJbnN0cnVjdGlvbnMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRleHRJbnN0cnVjdGlvbnNbaSArIDFdKSkge1xuICAgICAgY29udGV4dFtjb250ZXh0SW5zdHJ1Y3Rpb25zW2ldXS5hcHBseShjb250ZXh0LCBjb250ZXh0SW5zdHJ1Y3Rpb25zW2kgKyAxXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHRbY29udGV4dEluc3RydWN0aW9uc1tpXV0gPSBjb250ZXh0SW5zdHJ1Y3Rpb25zW2kgKyAxXTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fVxuICogQHByaXZhdGVcbiAqL1xuXG5cbnZhciBjcmVhdGVUcmFuc2Zvcm1TdHJpbmdDYW52YXMgPSBudWxsO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcmV0dXJuIHtzdHJpbmd9IENTUyB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zZm9ybVN0cmluZyh0cmFuc2Zvcm0pIHtcbiAgaWYgKFdPUktFUl9PRkZTQ1JFRU5fQ0FOVkFTKSB7XG4gICAgcmV0dXJuIHRvU3RyaW5nKHRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFjcmVhdGVUcmFuc2Zvcm1TdHJpbmdDYW52YXMpIHtcbiAgICAgIGNyZWF0ZVRyYW5zZm9ybVN0cmluZ0NhbnZhcyA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCgxLCAxKS5jYW52YXM7XG4gICAgfVxuXG4gICAgY3JlYXRlVHJhbnNmb3JtU3RyaW5nQ2FudmFzLnN0eWxlLnRyYW5zZm9ybSA9IHRvU3RyaW5nKHRyYW5zZm9ybSk7XG4gICAgcmV0dXJuIGNyZWF0ZVRyYW5zZm9ybVN0cmluZ0NhbnZhcy5zdHlsZS50cmFuc2Zvcm07XG4gIH1cbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL0NvbXBvc2l0ZVxuICovXG5cblxuaW1wb3J0IE1hcFJlbmRlcmVyIGZyb20gJy4vTWFwLmpzJztcbmltcG9ydCBPYmplY3RFdmVudFR5cGUgZnJvbSAnLi4vT2JqZWN0RXZlbnRUeXBlLmpzJztcbmltcG9ydCBSZW5kZXJFdmVudCBmcm9tICcuLi9yZW5kZXIvRXZlbnQuanMnO1xuaW1wb3J0IFJlbmRlckV2ZW50VHlwZSBmcm9tICcuLi9yZW5kZXIvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBTb3VyY2VTdGF0ZSBmcm9tICcuLi9zb3VyY2UvU3RhdGUuanMnO1xuaW1wb3J0IHsgQ0xBU1NfVU5TRUxFQ1RBQkxFIH0gZnJvbSAnLi4vY3NzLmpzJztcbmltcG9ydCB7IGNoZWNrZWRGb250cyB9IGZyb20gJy4uL3JlbmRlci9jYW52YXMuanMnO1xuaW1wb3J0IHsgaW5WaWV3IH0gZnJvbSAnLi4vbGF5ZXIvTGF5ZXIuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vZXZlbnRzLmpzJztcbmltcG9ydCB7IHJlcGxhY2VDaGlsZHJlbiB9IGZyb20gJy4uL2RvbS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENhbnZhcyBtYXAgcmVuZGVyZXIuXG4gKiBAYXBpXG4gKi9cblxudmFyIENvbXBvc2l0ZU1hcFJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENvbXBvc2l0ZU1hcFJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDb21wb3NpdGVNYXBSZW5kZXJlcihtYXApIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBtYXApIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5FdmVudHNLZXl9XG4gICAgICovXG5cblxuICAgIF90aGlzLmZvbnRDaGFuZ2VMaXN0ZW5lcktleV8gPSBsaXN0ZW4oY2hlY2tlZEZvbnRzLCBPYmplY3RFdmVudFR5cGUuUFJPUEVSVFlDSEFOR0UsIG1hcC5yZWRyYXdUZXh0LmJpbmQobWFwKSk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTERpdkVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5lbGVtZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHZhciBzdHlsZSA9IF90aGlzLmVsZW1lbnRfLnN0eWxlO1xuICAgIHN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBzdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBzdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgc3R5bGUuekluZGV4ID0gJzAnO1xuICAgIF90aGlzLmVsZW1lbnRfLmNsYXNzTmFtZSA9IENMQVNTX1VOU0VMRUNUQUJMRSArICcgb2wtbGF5ZXJzJztcbiAgICB2YXIgY29udGFpbmVyID0gbWFwLmdldFZpZXdwb3J0KCk7XG4gICAgY29udGFpbmVyLmluc2VydEJlZm9yZShfdGhpcy5lbGVtZW50XywgY29udGFpbmVyLmZpcnN0Q2hpbGQgfHwgbnVsbCk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8SFRNTEVsZW1lbnQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2hpbGRyZW5fID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkVmlzaWJsZV8gPSB0cnVlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvRXZlbnRUeXBlLmpzXCIpLmRlZmF1bHR9IHR5cGUgRXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBDb21wb3NpdGVNYXBSZW5kZXJlci5wcm90b3R5cGUuZGlzcGF0Y2hSZW5kZXJFdmVudCA9IGZ1bmN0aW9uICh0eXBlLCBmcmFtZVN0YXRlKSB7XG4gICAgdmFyIG1hcCA9IHRoaXMuZ2V0TWFwKCk7XG5cbiAgICBpZiAobWFwLmhhc0xpc3RlbmVyKHR5cGUpKSB7XG4gICAgICB2YXIgZXZlbnRfMSA9IG5ldyBSZW5kZXJFdmVudCh0eXBlLCB1bmRlZmluZWQsIGZyYW1lU3RhdGUpO1xuICAgICAgbWFwLmRpc3BhdGNoRXZlbnQoZXZlbnRfMSk7XG4gICAgfVxuICB9O1xuXG4gIENvbXBvc2l0ZU1hcFJlbmRlcmVyLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgdW5saXN0ZW5CeUtleSh0aGlzLmZvbnRDaGFuZ2VMaXN0ZW5lcktleV8pO1xuICAgIHRoaXMuZWxlbWVudF8ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmVsZW1lbnRfKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIuXG4gICAqIEBwYXJhbSB7P2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIENvbXBvc2l0ZU1hcFJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgaWYgKCFmcmFtZVN0YXRlKSB7XG4gICAgICBpZiAodGhpcy5yZW5kZXJlZFZpc2libGVfKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudF8uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgdGhpcy5yZW5kZXJlZFZpc2libGVfID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmNhbGN1bGF0ZU1hdHJpY2VzMkQoZnJhbWVTdGF0ZSk7XG4gICAgdGhpcy5kaXNwYXRjaFJlbmRlckV2ZW50KFJlbmRlckV2ZW50VHlwZS5QUkVDT01QT1NFLCBmcmFtZVN0YXRlKTtcbiAgICB2YXIgbGF5ZXJTdGF0ZXNBcnJheSA9IGZyYW1lU3RhdGUubGF5ZXJTdGF0ZXNBcnJheS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gYS56SW5kZXggLSBiLnpJbmRleDtcbiAgICB9KTtcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdGhpcy5jaGlsZHJlbl8ubGVuZ3RoID0gMDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vbGF5ZXIvQmFzZVZlY3Rvci5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIHZhciBkZWNsdXR0ZXJMYXllcnMgPSBbXTtcbiAgICB2YXIgcHJldmlvdXNFbGVtZW50ID0gbnVsbDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxheWVyU3RhdGVzQXJyYXkubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGxheWVyU3RhdGUgPSBsYXllclN0YXRlc0FycmF5W2ldO1xuICAgICAgZnJhbWVTdGF0ZS5sYXllckluZGV4ID0gaTtcblxuICAgICAgaWYgKCFpblZpZXcobGF5ZXJTdGF0ZSwgdmlld1N0YXRlKSB8fCBsYXllclN0YXRlLnNvdXJjZVN0YXRlICE9IFNvdXJjZVN0YXRlLlJFQURZICYmIGxheWVyU3RhdGUuc291cmNlU3RhdGUgIT0gU291cmNlU3RhdGUuVU5ERUZJTkVEKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGF5ZXIgPSBsYXllclN0YXRlLmxheWVyO1xuICAgICAgdmFyIGVsZW1lbnQgPSBsYXllci5yZW5kZXIoZnJhbWVTdGF0ZSwgcHJldmlvdXNFbGVtZW50KTtcblxuICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudCAhPT0gcHJldmlvdXNFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuY2hpbGRyZW5fLnB1c2goZWxlbWVudCk7XG4gICAgICAgIHByZXZpb3VzRWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICB9XG5cbiAgICAgIGlmICgnZ2V0RGVjbHV0dGVyJyBpbiBsYXllcikge1xuICAgICAgICBkZWNsdXR0ZXJMYXllcnMucHVzaChsYXllcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IGRlY2x1dHRlckxheWVycy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgZGVjbHV0dGVyTGF5ZXJzW2ldLnJlbmRlckRlY2x1dHRlcihmcmFtZVN0YXRlKTtcbiAgICB9XG5cbiAgICByZXBsYWNlQ2hpbGRyZW4odGhpcy5lbGVtZW50XywgdGhpcy5jaGlsZHJlbl8pO1xuICAgIHRoaXMuZGlzcGF0Y2hSZW5kZXJFdmVudChSZW5kZXJFdmVudFR5cGUuUE9TVENPTVBPU0UsIGZyYW1lU3RhdGUpO1xuXG4gICAgaWYgKCF0aGlzLnJlbmRlcmVkVmlzaWJsZV8pIHtcbiAgICAgIHRoaXMuZWxlbWVudF8uc3R5bGUuZGlzcGxheSA9ICcnO1xuICAgICAgdGhpcy5yZW5kZXJlZFZpc2libGVfID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnNjaGVkdWxlRXhwaXJlSWNvbkNhY2hlKGZyYW1lU3RhdGUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWVTdGF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGhpdFRvbGVyYW5jZSBIaXQgdG9sZXJhbmNlIGluIHBpeGVscy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0LCAoVWludDhDbGFtcGVkQXJyYXl8VWludDhBcnJheSkpOiBUfSBjYWxsYmFjayBMYXllclxuICAgKiAgICAgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCk6IGJvb2xlYW59IGxheWVyRmlsdGVyIExheWVyIGZpbHRlclxuICAgKiAgICAgZnVuY3Rpb24sIG9ubHkgbGF5ZXJzIHdoaWNoIGFyZSB2aXNpYmxlIGFuZCBmb3Igd2hpY2ggdGhpcyBmdW5jdGlvblxuICAgKiAgICAgcmV0dXJucyBgdHJ1ZWAgd2lsbCBiZSB0ZXN0ZWQgZm9yIGZlYXR1cmVzLiAgQnkgZGVmYXVsdCwgYWxsIHZpc2libGVcbiAgICogICAgIGxheWVycyB3aWxsIGJlIHRlc3RlZC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICovXG5cblxuICBDb21wb3NpdGVNYXBSZW5kZXJlci5wcm90b3R5cGUuZm9yRWFjaExheWVyQXRQaXhlbCA9IGZ1bmN0aW9uIChwaXhlbCwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlLCBjYWxsYmFjaywgbGF5ZXJGaWx0ZXIpIHtcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdmFyIGxheWVyU3RhdGVzID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5O1xuICAgIHZhciBudW1MYXllcnMgPSBsYXllclN0YXRlcy5sZW5ndGg7XG5cbiAgICBmb3IgKHZhciBpID0gbnVtTGF5ZXJzIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHZhciBsYXllclN0YXRlID0gbGF5ZXJTdGF0ZXNbaV07XG4gICAgICB2YXIgbGF5ZXIgPSBsYXllclN0YXRlLmxheWVyO1xuXG4gICAgICBpZiAobGF5ZXIuaGFzUmVuZGVyZXIoKSAmJiBpblZpZXcobGF5ZXJTdGF0ZSwgdmlld1N0YXRlKSAmJiBsYXllckZpbHRlcihsYXllcikpIHtcbiAgICAgICAgdmFyIGxheWVyUmVuZGVyZXIgPSBsYXllci5nZXRSZW5kZXJlcigpO1xuICAgICAgICB2YXIgZGF0YSA9IGxheWVyUmVuZGVyZXIuZ2V0RGF0YUF0UGl4ZWwocGl4ZWwsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSk7XG5cbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gY2FsbGJhY2sobGF5ZXIsIGRhdGEpO1xuXG4gICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuXG4gIHJldHVybiBDb21wb3NpdGVNYXBSZW5kZXJlcjtcbn0oTWFwUmVuZGVyZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDb21wb3NpdGVNYXBSZW5kZXJlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvQ29sbGVjdGlvbkV2ZW50VHlwZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gYW4gaXRlbSBpcyBhZGRlZCB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9Db2xsZWN0aW9uLkNvbGxlY3Rpb25FdmVudCNhZGRcbiAgICogQGFwaVxuICAgKi9cbiAgQUREOiAnYWRkJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gYW4gaXRlbSBpcyByZW1vdmVkIGZyb20gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEBldmVudCBtb2R1bGU6b2wvQ29sbGVjdGlvbi5Db2xsZWN0aW9uRXZlbnQjcmVtb3ZlXG4gICAqIEBhcGlcbiAgICovXG4gIFJFTU9WRTogJ3JlbW92ZSdcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9Db2xsZWN0aW9uXG4gKi9cblxuXG5pbXBvcnQgQXNzZXJ0aW9uRXJyb3IgZnJvbSAnLi9Bc3NlcnRpb25FcnJvci5qcyc7XG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuL09iamVjdC5qcyc7XG5pbXBvcnQgQ29sbGVjdGlvbkV2ZW50VHlwZSBmcm9tICcuL0NvbGxlY3Rpb25FdmVudFR5cGUuanMnO1xuaW1wb3J0IEV2ZW50IGZyb20gJy4vZXZlbnRzL0V2ZW50LmpzJztcbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIFByb3BlcnR5ID0ge1xuICBMRU5HVEg6ICdsZW5ndGgnXG59O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb25+Q29sbGVjdGlvbn0gaW5zdGFuY2VzIGFyZSBpbnN0YW5jZXMgb2YgdGhpc1xuICogdHlwZS5cbiAqL1xuXG52YXIgQ29sbGVjdGlvbkV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENvbGxlY3Rpb25FdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Db2xsZWN0aW9uRXZlbnRUeXBlLmpzXCIpLmRlZmF1bHR9IHR5cGUgVHlwZS5cbiAgICogQHBhcmFtIHsqPX0gb3B0X2VsZW1lbnQgRWxlbWVudC5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfaW5kZXggVGhlIGluZGV4IG9mIHRoZSBhZGRlZCBvciByZW1vdmVkIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ29sbGVjdGlvbkV2ZW50KHR5cGUsIG9wdF9lbGVtZW50LCBvcHRfaW5kZXgpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0eXBlKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoZSBlbGVtZW50IHRoYXQgaXMgYWRkZWQgdG8gb3IgcmVtb3ZlZCBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICAgICAqIEB0eXBlIHsqfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZWxlbWVudCA9IG9wdF9lbGVtZW50O1xuICAgIC8qKlxuICAgICAqIFRoZSBpbmRleCBvZiB0aGUgYWRkZWQgb3IgcmVtb3ZlZCBlbGVtZW50LlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW5kZXggPSBvcHRfaW5kZXg7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIENvbGxlY3Rpb25FdmVudDtcbn0oRXZlbnQpO1xuXG5leHBvcnQgeyBDb2xsZWN0aW9uRXZlbnQgfTtcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtib29sZWFufSBbdW5pcXVlPWZhbHNlXSBEaXNhbGxvdyB0aGUgc2FtZSBpdGVtIGZyb20gYmVpbmcgYWRkZWQgdG9cbiAqIHRoZSBjb2xsZWN0aW9uIHR3aWNlLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQW4gZXhwYW5kZWQgdmVyc2lvbiBvZiBzdGFuZGFyZCBKUyBBcnJheSwgYWRkaW5nIGNvbnZlbmllbmNlIG1ldGhvZHMgZm9yXG4gKiBtYW5pcHVsYXRpb24uIEFkZCBhbmQgcmVtb3ZlIGNoYW5nZXMgdG8gdGhlIENvbGxlY3Rpb24gdHJpZ2dlciBhIENvbGxlY3Rpb25cbiAqIGV2ZW50LiBOb3RlIHRoYXQgdGhpcyBkb2VzIG5vdCBjb3ZlciBjaGFuZ2VzIHRvIHRoZSBvYmplY3RzIF93aXRoaW5fIHRoZVxuICogQ29sbGVjdGlvbjsgdGhleSB0cmlnZ2VyIGV2ZW50cyBvbiB0aGUgYXBwcm9wcmlhdGUgb2JqZWN0LCBub3Qgb24gdGhlXG4gKiBDb2xsZWN0aW9uIGFzIGEgd2hvbGUuXG4gKlxuICogQGZpcmVzIENvbGxlY3Rpb25FdmVudFxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAYXBpXG4gKi9cblxudmFyIENvbGxlY3Rpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ29sbGVjdGlvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8VD49fSBvcHRfYXJyYXkgQXJyYXkuXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIENvbGxlY3Rpb24gb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDb2xsZWN0aW9uKG9wdF9hcnJheSwgb3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMudW5pcXVlXyA9ICEhb3B0aW9ucy51bmlxdWU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUFycmF5PFQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYXJyYXlfID0gb3B0X2FycmF5ID8gb3B0X2FycmF5IDogW107XG5cbiAgICBpZiAoX3RoaXMudW5pcXVlXykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gX3RoaXMuYXJyYXlfLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgX3RoaXMuYXNzZXJ0VW5pcXVlXyhfdGhpcy5hcnJheV9baV0sIGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIF90aGlzLnVwZGF0ZUxlbmd0aF8oKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBlbGVtZW50cyBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgd2hpbGUgKHRoaXMuZ2V0TGVuZ3RoKCkgPiAwKSB7XG4gICAgICB0aGlzLnBvcCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEFkZCBlbGVtZW50cyB0byB0aGUgY29sbGVjdGlvbi4gIFRoaXMgcHVzaGVzIGVhY2ggaXRlbSBpbiB0aGUgcHJvdmlkZWQgYXJyYXlcbiAgICogdG8gdGhlIGVuZCBvZiB0aGUgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIHshQXJyYXk8VD59IGFyciBBcnJheS5cbiAgICogQHJldHVybiB7Q29sbGVjdGlvbjxUPn0gVGhpcyBjb2xsZWN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUuZXh0ZW5kID0gZnVuY3Rpb24gKGFycikge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGFyci5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB0aGlzLnB1c2goYXJyW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBlYWNoIGVsZW1lbnQsIGNhbGxpbmcgdGhlIHByb3ZpZGVkIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFQsIG51bWJlciwgQXJyYXk8VD4pOiAqfSBmIFRoZSBmdW5jdGlvbiB0byBjYWxsXG4gICAqICAgICBmb3IgZXZlcnkgZWxlbWVudC4gVGhpcyBmdW5jdGlvbiB0YWtlcyAzIGFyZ3VtZW50cyAodGhlIGVsZW1lbnQsIHRoZVxuICAgKiAgICAgaW5kZXggYW5kIHRoZSBhcnJheSkuIFRoZSByZXR1cm4gdmFsdWUgaXMgaWdub3JlZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoZikge1xuICAgIHZhciBhcnJheSA9IHRoaXMuYXJyYXlfO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJyYXkubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgZihhcnJheVtpXSwgaSwgYXJyYXkpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBBcnJheSBvYmplY3QuIFdhcm5pbmc6IGlmIHRoZSBhcnJheVxuICAgKiBpcyBtdXRhdGVkLCBubyBldmVudHMgd2lsbCBiZSBkaXNwYXRjaGVkIGJ5IHRoZSBjb2xsZWN0aW9uLCBhbmQgdGhlXG4gICAqIGNvbGxlY3Rpb24ncyBcImxlbmd0aFwiIHByb3BlcnR5IHdvbid0IGJlIGluIHN5bmMgd2l0aCB0aGUgYWN0dWFsIGxlbmd0aFxuICAgKiBvZiB0aGUgYXJyYXkuXG4gICAqIEByZXR1cm4geyFBcnJheTxUPn0gQXJyYXkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5nZXRBcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5hcnJheV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGVsZW1lbnQgYXQgdGhlIHByb3ZpZGVkIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXguXG4gICAqIEByZXR1cm4ge1R9IEVsZW1lbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5pdGVtID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMuYXJyYXlfW2luZGV4XTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbGVuZ3RoIG9mIHRoaXMgY29sbGVjdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbGVuZ3RoIG9mIHRoZSBhcnJheS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLmdldExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoUHJvcGVydHkuTEVOR1RIKTtcbiAgfTtcbiAgLyoqXG4gICAqIEluc2VydCBhbiBlbGVtZW50IGF0IHRoZSBwcm92aWRlZCBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IEluZGV4LlxuICAgKiBAcGFyYW0ge1R9IGVsZW0gRWxlbWVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLmluc2VydEF0ID0gZnVuY3Rpb24gKGluZGV4LCBlbGVtKSB7XG4gICAgaWYgKHRoaXMudW5pcXVlXykge1xuICAgICAgdGhpcy5hc3NlcnRVbmlxdWVfKGVsZW0pO1xuICAgIH1cblxuICAgIHRoaXMuYXJyYXlfLnNwbGljZShpbmRleCwgMCwgZWxlbSk7XG4gICAgdGhpcy51cGRhdGVMZW5ndGhfKCk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBDb2xsZWN0aW9uRXZlbnQoQ29sbGVjdGlvbkV2ZW50VHlwZS5BREQsIGVsZW0sIGluZGV4KSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGxhc3QgZWxlbWVudCBvZiB0aGUgY29sbGVjdGlvbiBhbmQgcmV0dXJuIGl0LlxuICAgKiBSZXR1cm4gYHVuZGVmaW5lZGAgaWYgdGhlIGNvbGxlY3Rpb24gaXMgZW1wdHkuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBFbGVtZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlbW92ZUF0KHRoaXMuZ2V0TGVuZ3RoKCkgLSAxKTtcbiAgfTtcbiAgLyoqXG4gICAqIEluc2VydCB0aGUgcHJvdmlkZWQgZWxlbWVudCBhdCB0aGUgZW5kIG9mIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge1R9IGVsZW0gRWxlbWVudC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBOZXcgbGVuZ3RoIG9mIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgaWYgKHRoaXMudW5pcXVlXykge1xuICAgICAgdGhpcy5hc3NlcnRVbmlxdWVfKGVsZW0pO1xuICAgIH1cblxuICAgIHZhciBuID0gdGhpcy5nZXRMZW5ndGgoKTtcbiAgICB0aGlzLmluc2VydEF0KG4sIGVsZW0pO1xuICAgIHJldHVybiB0aGlzLmdldExlbmd0aCgpO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIHRoZSBmaXJzdCBvY2N1cnJlbmNlIG9mIGFuIGVsZW1lbnQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIHtUfSBlbGVtIEVsZW1lbnQuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBUaGUgcmVtb3ZlZCBlbGVtZW50IG9yIHVuZGVmaW5lZCBpZiBub25lIGZvdW5kLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29sbGVjdGlvbi5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKGVsZW0pIHtcbiAgICB2YXIgYXJyID0gdGhpcy5hcnJheV87XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBhcnIubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgaWYgKGFycltpXSA9PT0gZWxlbSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVBdChpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIHRoZSBlbGVtZW50IGF0IHRoZSBwcm92aWRlZCBpbmRleCBhbmQgcmV0dXJuIGl0LlxuICAgKiBSZXR1cm4gYHVuZGVmaW5lZGAgaWYgdGhlIGNvbGxlY3Rpb24gZG9lcyBub3QgY29udGFpbiB0aGlzIGluZGV4LlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXguXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBWYWx1ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLnJlbW92ZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgdmFyIHByZXYgPSB0aGlzLmFycmF5X1tpbmRleF07XG4gICAgdGhpcy5hcnJheV8uc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLnVwZGF0ZUxlbmd0aF8oKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IENvbGxlY3Rpb25FdmVudChDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSwgcHJldiwgaW5kZXgpKTtcbiAgICByZXR1cm4gcHJldjtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZWxlbWVudCBhdCB0aGUgcHJvdmlkZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHBhcmFtIHtUfSBlbGVtIEVsZW1lbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS5zZXRBdCA9IGZ1bmN0aW9uIChpbmRleCwgZWxlbSkge1xuICAgIHZhciBuID0gdGhpcy5nZXRMZW5ndGgoKTtcblxuICAgIGlmIChpbmRleCA8IG4pIHtcbiAgICAgIGlmICh0aGlzLnVuaXF1ZV8pIHtcbiAgICAgICAgdGhpcy5hc3NlcnRVbmlxdWVfKGVsZW0sIGluZGV4KTtcbiAgICAgIH1cblxuICAgICAgdmFyIHByZXYgPSB0aGlzLmFycmF5X1tpbmRleF07XG4gICAgICB0aGlzLmFycmF5X1tpbmRleF0gPSBlbGVtO1xuICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBDb2xsZWN0aW9uRXZlbnQoQ29sbGVjdGlvbkV2ZW50VHlwZS5SRU1PVkUsIHByZXYsIGluZGV4KSk7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IENvbGxlY3Rpb25FdmVudChDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCwgZWxlbSwgaW5kZXgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaiA9IG47IGogPCBpbmRleDsgKytqKSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0QXQoaiwgdW5kZWZpbmVkKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbnNlcnRBdChpbmRleCwgZWxlbSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDb2xsZWN0aW9uLnByb3RvdHlwZS51cGRhdGVMZW5ndGhfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5LkxFTkdUSCwgdGhpcy5hcnJheV8ubGVuZ3RoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7VH0gZWxlbSBFbGVtZW50LlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9leGNlcHQgT3B0aW9uYWwgaW5kZXggdG8gaWdub3JlLlxuICAgKi9cblxuXG4gIENvbGxlY3Rpb24ucHJvdG90eXBlLmFzc2VydFVuaXF1ZV8gPSBmdW5jdGlvbiAoZWxlbSwgb3B0X2V4Y2VwdCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMuYXJyYXlfLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIGlmICh0aGlzLmFycmF5X1tpXSA9PT0gZWxlbSAmJiBpICE9PSBvcHRfZXhjZXB0KSB7XG4gICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcig1OCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBDb2xsZWN0aW9uO1xufShCYXNlT2JqZWN0KTtcblxuZXhwb3J0IGRlZmF1bHQgQ29sbGVjdGlvbjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL0dyb3VwXG4gKi9cblxuXG5pbXBvcnQgQmFzZUxheWVyIGZyb20gJy4vQmFzZS5qcyc7XG5pbXBvcnQgQ29sbGVjdGlvbiBmcm9tICcuLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCBDb2xsZWN0aW9uRXZlbnRUeXBlIGZyb20gJy4uL0NvbGxlY3Rpb25FdmVudFR5cGUuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBPYmplY3RFdmVudFR5cGUgZnJvbSAnLi4vT2JqZWN0RXZlbnRUeXBlLmpzJztcbmltcG9ydCBTb3VyY2VTdGF0ZSBmcm9tICcuLi9zb3VyY2UvU3RhdGUuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBhc3NpZ24sIGNsZWFyIH0gZnJvbSAnLi4vb2JqLmpzJztcbmltcG9ydCB7IGdldENoYW5nZUV2ZW50VHlwZSB9IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgeyBnZXRJbnRlcnNlY3Rpb24gfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuLi9ldmVudHMuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSAoMCwgMSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt2aXNpYmxlPXRydWVdIFZpc2liaWxpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBib3VuZGluZyBleHRlbnQgZm9yIGxheWVyIHJlbmRlcmluZy4gIFRoZSBsYXllciB3aWxsIG5vdCBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGlzIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBUaGUgei1pbmRleCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgQXQgcmVuZGVyaW5nIHRpbWUsIHRoZSBsYXllcnNcbiAqIHdpbGwgYmUgb3JkZXJlZCwgZmlyc3QgYnkgWi1pbmRleCBhbmQgdGhlbiBieSBwb3NpdGlvbi4gV2hlbiBgdW5kZWZpbmVkYCwgYSBgekluZGV4YCBvZiAwIGlzIGFzc3VtZWRcbiAqIGZvciBsYXllcnMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIG1hcCdzIGBsYXllcnNgIGNvbGxlY3Rpb24sIG9yIGBJbmZpbml0eWAgd2hlbiB0aGUgbGF5ZXIncyBgc2V0TWFwKClgXG4gKiBtZXRob2Qgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIChleGNsdXNpdmUpIGJlbG93IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHQ+fGltcG9ydChcIi4uL0NvbGxlY3Rpb24uanNcIikuZGVmYXVsdDxpbXBvcnQoXCIuL0Jhc2UuanNcIikuZGVmYXVsdD59IFtsYXllcnNdIENoaWxkIGxheWVycy5cbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciBQcm9wZXJ0eSA9IHtcbiAgTEFZRVJTOiAnbGF5ZXJzJ1xufTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQSB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb25+Q29sbGVjdGlvbn0gb2YgbGF5ZXJzIHRoYXQgYXJlIGhhbmRsZWQgdG9nZXRoZXIuXG4gKlxuICogQSBnZW5lcmljIGBjaGFuZ2VgIGV2ZW50IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBncm91cC9Db2xsZWN0aW9uIGNoYW5nZXMuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBMYXllckdyb3VwID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKExheWVyR3JvdXAsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBMYXllciBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIExheWVyR3JvdXAob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgYmFzZU9wdGlvbnMgPVxuICAgIC8qKiBAdHlwZSB7T3B0aW9uc30gKi9cbiAgICBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy5sYXllcnM7XG4gICAgdmFyIGxheWVycyA9IG9wdGlvbnMubGF5ZXJzO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgYmFzZU9wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXllcnNMaXN0ZW5lcktleXNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMubGlzdGVuZXJLZXlzXyA9IHt9O1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoUHJvcGVydHkuTEFZRVJTKSwgX3RoaXMuaGFuZGxlTGF5ZXJzQ2hhbmdlZF8pO1xuXG4gICAgaWYgKGxheWVycykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGF5ZXJzKSkge1xuICAgICAgICBsYXllcnMgPSBuZXcgQ29sbGVjdGlvbihsYXllcnMuc2xpY2UoKSwge1xuICAgICAgICAgIHVuaXF1ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2VydCh0eXBlb2ZcbiAgICAgICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgICAgICBsYXllcnMuZ2V0QXJyYXkgPT09ICdmdW5jdGlvbicsIDQzKTsgLy8gRXhwZWN0ZWQgYGxheWVyc2AgdG8gYmUgYW4gYXJyYXkgb3IgYSBgQ29sbGVjdGlvbmBcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGF5ZXJzID0gbmV3IENvbGxlY3Rpb24odW5kZWZpbmVkLCB7XG4gICAgICAgIHVuaXF1ZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3RoaXMuc2V0TGF5ZXJzKGxheWVycyk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuaGFuZGxlTGF5ZXJDaGFuZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5oYW5kbGVMYXllcnNDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmxheWVyc0xpc3RlbmVyS2V5c18uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICB0aGlzLmxheWVyc0xpc3RlbmVyS2V5c18ubGVuZ3RoID0gMDtcbiAgICB2YXIgbGF5ZXJzID0gdGhpcy5nZXRMYXllcnMoKTtcbiAgICB0aGlzLmxheWVyc0xpc3RlbmVyS2V5c18ucHVzaChsaXN0ZW4obGF5ZXJzLCBDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCwgdGhpcy5oYW5kbGVMYXllcnNBZGRfLCB0aGlzKSwgbGlzdGVuKGxheWVycywgQ29sbGVjdGlvbkV2ZW50VHlwZS5SRU1PVkUsIHRoaXMuaGFuZGxlTGF5ZXJzUmVtb3ZlXywgdGhpcykpO1xuXG4gICAgZm9yICh2YXIgaWQgaW4gdGhpcy5saXN0ZW5lcktleXNfKSB7XG4gICAgICB0aGlzLmxpc3RlbmVyS2V5c19baWRdLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gICAgfVxuXG4gICAgY2xlYXIodGhpcy5saXN0ZW5lcktleXNfKTtcbiAgICB2YXIgbGF5ZXJzQXJyYXkgPSBsYXllcnMuZ2V0QXJyYXkoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxheWVyc0FycmF5Lmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICAgIHZhciBsYXllciA9IGxheWVyc0FycmF5W2ldO1xuICAgICAgdGhpcy5saXN0ZW5lcktleXNfW2dldFVpZChsYXllcildID0gW2xpc3RlbihsYXllciwgT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFLCB0aGlzLmhhbmRsZUxheWVyQ2hhbmdlXywgdGhpcyksIGxpc3RlbihsYXllciwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVMYXllckNoYW5nZV8sIHRoaXMpXTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGNvbGxlY3Rpb25FdmVudCBDb2xsZWN0aW9uRXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuaGFuZGxlTGF5ZXJzQWRkXyA9IGZ1bmN0aW9uIChjb2xsZWN0aW9uRXZlbnQpIHtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgY29sbGVjdGlvbkV2ZW50LmVsZW1lbnQ7XG4gICAgdGhpcy5saXN0ZW5lcktleXNfW2dldFVpZChsYXllcildID0gW2xpc3RlbihsYXllciwgT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFLCB0aGlzLmhhbmRsZUxheWVyQ2hhbmdlXywgdGhpcyksIGxpc3RlbihsYXllciwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVMYXllckNoYW5nZV8sIHRoaXMpXTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGNvbGxlY3Rpb25FdmVudCBDb2xsZWN0aW9uRXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuaGFuZGxlTGF5ZXJzUmVtb3ZlXyA9IGZ1bmN0aW9uIChjb2xsZWN0aW9uRXZlbnQpIHtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgY29sbGVjdGlvbkV2ZW50LmVsZW1lbnQ7XG4gICAgdmFyIGtleSA9IGdldFVpZChsYXllcik7XG4gICAgdGhpcy5saXN0ZW5lcktleXNfW2tleV0uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICBkZWxldGUgdGhpcy5saXN0ZW5lcktleXNfW2tleV07XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb24gY29sbGVjdGlvbn0gb2Yge0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllcn5MYXllciBsYXllcnN9XG4gICAqIGluIHRoaXMgZ3JvdXAuXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi9Db2xsZWN0aW9uLmpzXCIpLmRlZmF1bHQ8aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHQ+fSBDb2xsZWN0aW9uIG9mXG4gICAqICAge0BsaW5rIG1vZHVsZTpvbC9sYXllci9CYXNlIGxheWVyc30gdGhhdCBhcmUgcGFydCBvZiB0aGlzIGdyb3VwLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuZ2V0TGF5ZXJzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUgeyFpbXBvcnQoXCIuLi9Db2xsZWN0aW9uLmpzXCIpLmRlZmF1bHQ8aW1wb3J0KFwiLi9CYXNlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgICAgdGhpcy5nZXQoUHJvcGVydHkuTEFZRVJTKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbiBjb2xsZWN0aW9ufSBvZiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyfkxheWVyIGxheWVyc31cbiAgICogaW4gdGhpcyBncm91cC5cbiAgICogQHBhcmFtIHshaW1wb3J0KFwiLi4vQ29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0PGltcG9ydChcIi4vQmFzZS5qc1wiKS5kZWZhdWx0Pn0gbGF5ZXJzIENvbGxlY3Rpb24gb2ZcbiAgICogICB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0Jhc2UgbGF5ZXJzfSB0aGF0IGFyZSBwYXJ0IG9mIHRoaXMgZ3JvdXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMYXllckdyb3VwLnByb3RvdHlwZS5zZXRMYXllcnMgPSBmdW5jdGlvbiAobGF5ZXJzKSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuTEFZRVJTLCBsYXllcnMpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLmRlZmF1bHQ+PX0gb3B0X2FycmF5IEFycmF5IG9mIGxheWVycyAodG8gYmUgbW9kaWZpZWQgaW4gcGxhY2UpLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLmRlZmF1bHQ+fSBBcnJheSBvZiBsYXllcnMuXG4gICAqL1xuXG5cbiAgTGF5ZXJHcm91cC5wcm90b3R5cGUuZ2V0TGF5ZXJzQXJyYXkgPSBmdW5jdGlvbiAob3B0X2FycmF5KSB7XG4gICAgdmFyIGFycmF5ID0gb3B0X2FycmF5ICE9PSB1bmRlZmluZWQgPyBvcHRfYXJyYXkgOiBbXTtcbiAgICB0aGlzLmdldExheWVycygpLmZvckVhY2goZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgICBsYXllci5nZXRMYXllcnNBcnJheShhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFycmF5O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0xheWVyLmpzXCIpLlN0YXRlPj19IG9wdF9zdGF0ZXMgT3B0aW9uYWwgbGlzdCBvZiBsYXllciBzdGF0ZXMgKHRvIGJlIG1vZGlmaWVkIGluIHBsYWNlKS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9MYXllci5qc1wiKS5TdGF0ZT59IExpc3Qgb2YgbGF5ZXIgc3RhdGVzLlxuICAgKi9cblxuXG4gIExheWVyR3JvdXAucHJvdG90eXBlLmdldExheWVyU3RhdGVzQXJyYXkgPSBmdW5jdGlvbiAob3B0X3N0YXRlcykge1xuICAgIHZhciBzdGF0ZXMgPSBvcHRfc3RhdGVzICE9PSB1bmRlZmluZWQgPyBvcHRfc3RhdGVzIDogW107XG4gICAgdmFyIHBvcyA9IHN0YXRlcy5sZW5ndGg7XG4gICAgdGhpcy5nZXRMYXllcnMoKS5mb3JFYWNoKGZ1bmN0aW9uIChsYXllcikge1xuICAgICAgbGF5ZXIuZ2V0TGF5ZXJTdGF0ZXNBcnJheShzdGF0ZXMpO1xuICAgIH0pO1xuICAgIHZhciBvd25MYXllclN0YXRlID0gdGhpcy5nZXRMYXllclN0YXRlKCk7XG5cbiAgICBmb3IgKHZhciBpID0gcG9zLCBpaSA9IHN0YXRlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICB2YXIgbGF5ZXJTdGF0ZSA9IHN0YXRlc1tpXTtcbiAgICAgIGxheWVyU3RhdGUub3BhY2l0eSAqPSBvd25MYXllclN0YXRlLm9wYWNpdHk7XG4gICAgICBsYXllclN0YXRlLnZpc2libGUgPSBsYXllclN0YXRlLnZpc2libGUgJiYgb3duTGF5ZXJTdGF0ZS52aXNpYmxlO1xuICAgICAgbGF5ZXJTdGF0ZS5tYXhSZXNvbHV0aW9uID0gTWF0aC5taW4obGF5ZXJTdGF0ZS5tYXhSZXNvbHV0aW9uLCBvd25MYXllclN0YXRlLm1heFJlc29sdXRpb24pO1xuICAgICAgbGF5ZXJTdGF0ZS5taW5SZXNvbHV0aW9uID0gTWF0aC5tYXgobGF5ZXJTdGF0ZS5taW5SZXNvbHV0aW9uLCBvd25MYXllclN0YXRlLm1pblJlc29sdXRpb24pO1xuICAgICAgbGF5ZXJTdGF0ZS5taW5ab29tID0gTWF0aC5tYXgobGF5ZXJTdGF0ZS5taW5ab29tLCBvd25MYXllclN0YXRlLm1pblpvb20pO1xuICAgICAgbGF5ZXJTdGF0ZS5tYXhab29tID0gTWF0aC5taW4obGF5ZXJTdGF0ZS5tYXhab29tLCBvd25MYXllclN0YXRlLm1heFpvb20pO1xuXG4gICAgICBpZiAob3duTGF5ZXJTdGF0ZS5leHRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAobGF5ZXJTdGF0ZS5leHRlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxheWVyU3RhdGUuZXh0ZW50ID0gZ2V0SW50ZXJzZWN0aW9uKGxheWVyU3RhdGUuZXh0ZW50LCBvd25MYXllclN0YXRlLmV4dGVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGF5ZXJTdGF0ZS5leHRlbnQgPSBvd25MYXllclN0YXRlLmV4dGVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZXM7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zb3VyY2UvU3RhdGUuanNcIikuZGVmYXVsdH0gU291cmNlIHN0YXRlLlxuICAgKi9cblxuXG4gIExheWVyR3JvdXAucHJvdG90eXBlLmdldFNvdXJjZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBTb3VyY2VTdGF0ZS5SRUFEWTtcbiAgfTtcblxuICByZXR1cm4gTGF5ZXJHcm91cDtcbn0oQmFzZUxheWVyKTtcblxuZXhwb3J0IGRlZmF1bHQgTGF5ZXJHcm91cDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL01hcEV2ZW50XG4gKi9cblxuXG5pbXBvcnQgRXZlbnQgZnJvbSAnLi9ldmVudHMvRXZlbnQuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBhcyBtYXAgZXZlbnRzIGFyZSBpbnN0YW5jZXMgb2YgdGhpcyB0eXBlLlxuICogU2VlIHtAbGluayBtb2R1bGU6b2wvUGx1Z2dhYmxlTWFwflBsdWdnYWJsZU1hcH0gZm9yIHdoaWNoIGV2ZW50cyB0cmlnZ2VyIGEgbWFwIGV2ZW50LlxuICovXG5cbnZhciBNYXBFdmVudCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNYXBFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIEV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICogQHBhcmFtIHs/aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZT19IG9wdF9mcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1hcEV2ZW50KHR5cGUsIG1hcCwgb3B0X2ZyYW1lU3RhdGUpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0eXBlKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoZSBtYXAgd2hlcmUgdGhlIGV2ZW50IG9jY3VycmVkLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWFwID0gbWFwO1xuICAgIC8qKlxuICAgICAqIFRoZSBmcmFtZSBzdGF0ZSBhdCB0aGUgdGltZSBvZiB0aGUgZXZlbnQuXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLmZyYW1lU3RhdGUgPSBvcHRfZnJhbWVTdGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0X2ZyYW1lU3RhdGUgOiBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuXG4gIHJldHVybiBNYXBFdmVudDtcbn0oRXZlbnQpO1xuXG5leHBvcnQgZGVmYXVsdCBNYXBFdmVudDsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL01hcEJyb3dzZXJFdmVudFxuICovXG5cblxuaW1wb3J0IE1hcEV2ZW50IGZyb20gJy4vTWFwRXZlbnQuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBhcyBtYXAgYnJvd3NlciBldmVudHMgYXJlIGluc3RhbmNlcyBvZiB0aGlzIHR5cGUuXG4gKiBTZWUge0BsaW5rIG1vZHVsZTpvbC9QbHVnZ2FibGVNYXB+UGx1Z2dhYmxlTWFwfSBmb3Igd2hpY2ggZXZlbnRzIHRyaWdnZXIgYSBtYXAgYnJvd3NlciBldmVudC5cbiAqIEB0ZW1wbGF0ZSB7VUlFdmVudH0gRVZFTlRcbiAqL1xuXG52YXIgTWFwQnJvd3NlckV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE1hcEJyb3dzZXJFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIEV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICogQHBhcmFtIHtFVkVOVH0gb3JpZ2luYWxFdmVudCBPcmlnaW5hbCBldmVudC5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2RyYWdnaW5nIElzIHRoZSBtYXAgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQ/XG4gICAqIEBwYXJhbSB7P2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGU9fSBvcHRfZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNYXBCcm93c2VyRXZlbnQodHlwZSwgbWFwLCBvcmlnaW5hbEV2ZW50LCBvcHRfZHJhZ2dpbmcsIG9wdF9mcmFtZVN0YXRlKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSwgbWFwLCBvcHRfZnJhbWVTdGF0ZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUaGUgb3JpZ2luYWwgYnJvd3NlciBldmVudC5cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7RVZFTlR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5vcmlnaW5hbEV2ZW50ID0gb3JpZ2luYWxFdmVudDtcbiAgICAvKipcbiAgICAgKiBUaGUgbWFwIHBpeGVsIHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydCBjb3JyZXNwb25kaW5nIHRvIHRoZSBvcmlnaW5hbCBicm93c2VyIGV2ZW50LlxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogVGhlIGNvb3JkaW5hdGUgaW4gdGhlIHVzZXIgcHJvamVjdGlvbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBvcmlnaW5hbCBicm93c2VyIGV2ZW50LlxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb29yZGluYXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBtYXAgaXMgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQuIE9ubHkgc2V0IGZvclxuICAgICAqIGBQT0lOVEVSRFJBR2AgYW5kIGBQT0lOVEVSTU9WRWAgZXZlbnRzLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgICBfdGhpcy5kcmFnZ2luZyA9IG9wdF9kcmFnZ2luZyAhPT0gdW5kZWZpbmVkID8gb3B0X2RyYWdnaW5nIDogZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE1hcEJyb3dzZXJFdmVudC5wcm90b3R5cGUsIFwicGl4ZWxcIiwge1xuICAgIC8qKlxuICAgICAqIFRoZSBtYXAgcGl4ZWwgcmVsYXRpdmUgdG8gdGhlIHZpZXdwb3J0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIG9yaWdpbmFsIGV2ZW50LlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfVxuICAgICAqIEBhcGlcbiAgICAgKi9cbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIGlmICghdGhpcy5waXhlbF8pIHtcbiAgICAgICAgdGhpcy5waXhlbF8gPSB0aGlzLm1hcC5nZXRFdmVudFBpeGVsKHRoaXMub3JpZ2luYWxFdmVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnBpeGVsXztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KHBpeGVsKSB7XG4gICAgICB0aGlzLnBpeGVsXyA9IHBpeGVsO1xuICAgIH0sXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTWFwQnJvd3NlckV2ZW50LnByb3RvdHlwZSwgXCJjb29yZGluYXRlXCIsIHtcbiAgICAvKipcbiAgICAgKiBUaGUgY29vcmRpbmF0ZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBvcmlnaW5hbCBicm93c2VyIGV2ZW50LiAgVGhpcyB3aWxsIGJlIGluIHRoZSB1c2VyXG4gICAgICogcHJvamVjdGlvbiBpZiBvbmUgaXMgc2V0LiAgT3RoZXJ3aXNlIGl0IHdpbGwgYmUgaW4gdGhlIHZpZXcgcHJvamVjdGlvbi5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICogQGFwaVxuICAgICAqL1xuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgaWYgKCF0aGlzLmNvb3JkaW5hdGVfKSB7XG4gICAgICAgIHRoaXMuY29vcmRpbmF0ZV8gPSB0aGlzLm1hcC5nZXRDb29yZGluYXRlRnJvbVBpeGVsKHRoaXMucGl4ZWwpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5jb29yZGluYXRlXztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KGNvb3JkaW5hdGUpIHtcbiAgICAgIHRoaXMuY29vcmRpbmF0ZV8gPSBjb29yZGluYXRlO1xuICAgIH0sXG4gICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlXG4gIH0pO1xuICAvKipcbiAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYnJvd3NlciBhY3Rpb24uXG4gICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvZXZlbnQucHJldmVudERlZmF1bHQuXG4gICAqIEBhcGlcbiAgICovXG5cbiAgTWFwQnJvd3NlckV2ZW50LnByb3RvdHlwZS5wcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICBfc3VwZXIucHJvdG90eXBlLnByZXZlbnREZWZhdWx0LmNhbGwodGhpcyk7XG5cbiAgICB0aGlzLm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFByZXZlbnRzIGZ1cnRoZXIgcHJvcGFnYXRpb24gb2YgdGhlIGN1cnJlbnQgZXZlbnQuXG4gICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvZXZlbnQuc3RvcFByb3BhZ2F0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgX3N1cGVyLnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24uY2FsbCh0aGlzKTtcblxuICAgIHRoaXMub3JpZ2luYWxFdmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfTtcblxuICByZXR1cm4gTWFwQnJvd3NlckV2ZW50O1xufShNYXBFdmVudCk7XG5cbmV4cG9ydCBkZWZhdWx0IE1hcEJyb3dzZXJFdmVudDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvTWFwQnJvd3NlckV2ZW50VHlwZVxuICovXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG4vKipcbiAqIENvbnN0YW50cyBmb3IgZXZlbnQgbmFtZXMuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIEEgdHJ1ZSBzaW5nbGUgY2xpY2sgd2l0aCBubyBkcmFnZ2luZyBhbmQgbm8gZG91YmxlIGNsaWNrLiBOb3RlIHRoYXQgdGhpc1xuICAgKiBldmVudCBpcyBkZWxheWVkIGJ5IDI1MCBtcyB0byBlbnN1cmUgdGhhdCBpdCBpcyBub3QgYSBkb3VibGUgY2xpY2suXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudCNzaW5nbGVjbGlja1xuICAgKiBAYXBpXG4gICAqL1xuICBTSU5HTEVDTElDSzogJ3NpbmdsZWNsaWNrJyxcblxuICAvKipcbiAgICogQSBjbGljayB3aXRoIG5vIGRyYWdnaW5nLiBBIGRvdWJsZSBjbGljayB3aWxsIGZpcmUgdHdvIG9mIHRoaXMuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudCNjbGlja1xuICAgKiBAYXBpXG4gICAqL1xuICBDTElDSzogRXZlbnRUeXBlLkNMSUNLLFxuXG4gIC8qKlxuICAgKiBBIHRydWUgZG91YmxlIGNsaWNrLCB3aXRoIG5vIGRyYWdnaW5nLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnQjZGJsY2xpY2tcbiAgICogQGFwaVxuICAgKi9cbiAgREJMQ0xJQ0s6IEV2ZW50VHlwZS5EQkxDTElDSyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gYSBwb2ludGVyIGlzIGRyYWdnZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudCNwb2ludGVyZHJhZ1xuICAgKiBAYXBpXG4gICAqL1xuICBQT0lOVEVSRFJBRzogJ3BvaW50ZXJkcmFnJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gYSBwb2ludGVyIGlzIG1vdmVkLiBOb3RlIHRoYXQgb24gdG91Y2ggZGV2aWNlcyB0aGlzIGlzXG4gICAqIHRyaWdnZXJlZCB3aGVuIHRoZSBtYXAgaXMgcGFubmVkLCBzbyBpcyBub3QgdGhlIHNhbWUgYXMgbW91c2Vtb3ZlLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnQjcG9pbnRlcm1vdmVcbiAgICogQGFwaVxuICAgKi9cbiAgUE9JTlRFUk1PVkU6ICdwb2ludGVybW92ZScsXG4gIFBPSU5URVJET1dOOiAncG9pbnRlcmRvd24nLFxuICBQT0lOVEVSVVA6ICdwb2ludGVydXAnLFxuICBQT0lOVEVST1ZFUjogJ3BvaW50ZXJvdmVyJyxcbiAgUE9JTlRFUk9VVDogJ3BvaW50ZXJvdXQnLFxuICBQT0lOVEVSRU5URVI6ICdwb2ludGVyZW50ZXInLFxuICBQT0lOVEVSTEVBVkU6ICdwb2ludGVybGVhdmUnLFxuICBQT0lOVEVSQ0FOQ0VMOiAncG9pbnRlcmNhbmNlbCdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3BvaW50ZXIvRXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBDb25zdGFudHMgZm9yIGV2ZW50IG5hbWVzLlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBQT0lOVEVSTU9WRTogJ3BvaW50ZXJtb3ZlJyxcbiAgUE9JTlRFUkRPV046ICdwb2ludGVyZG93bicsXG4gIFBPSU5URVJVUDogJ3BvaW50ZXJ1cCcsXG4gIFBPSU5URVJPVkVSOiAncG9pbnRlcm92ZXInLFxuICBQT0lOVEVST1VUOiAncG9pbnRlcm91dCcsXG4gIFBPSU5URVJFTlRFUjogJ3BvaW50ZXJlbnRlcicsXG4gIFBPSU5URVJMRUFWRTogJ3BvaW50ZXJsZWF2ZScsXG4gIFBPSU5URVJDQU5DRUw6ICdwb2ludGVyY2FuY2VsJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvTWFwQnJvd3NlckV2ZW50SGFuZGxlclxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudHMvVGFyZ2V0LmpzJztcbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBNYXBCcm93c2VyRXZlbnQgZnJvbSAnLi9NYXBCcm93c2VyRXZlbnQuanMnO1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudFR5cGUgZnJvbSAnLi9NYXBCcm93c2VyRXZlbnRUeXBlLmpzJztcbmltcG9ydCBQb2ludGVyRXZlbnRUeXBlIGZyb20gJy4vcG9pbnRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgREVWSUNFX1BJWEVMX1JBVElPLCBQQVNTSVZFX0VWRU5UX0xJU1RFTkVSUyB9IGZyb20gJy4vaGFzLmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4vZXZlbnRzLmpzJztcblxudmFyIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTWFwQnJvd3NlckV2ZW50SGFuZGxlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIFRoZSBtYXAgd2l0aCB0aGUgdmlld3BvcnQgdG8gbGlzdGVuIHRvIGV2ZW50cyBvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBtb3ZlVG9sZXJhbmNlIFRoZSBtaW5pbWFsIGRpc3RhbmNlIHRoZSBwb2ludGVyIG11c3QgdHJhdmVsIHRvIHRyaWdnZXIgYSBtb3ZlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIobWFwLCBtb3ZlVG9sZXJhbmNlKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgbWFwKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgdGhlIGVsZW1lbnQgdGhhdCB3ZSB3aWxsIGxpc3RlbiB0byB0aGUgcmVhbCBldmVudHMgb24uXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWFwXyA9IG1hcDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7YW55fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5jbGlja1RpbWVvdXRJZF87XG4gICAgLyoqXG4gICAgICogRW11bGF0ZSBkYmxjbGljayBhbmQgc2luZ2xlY2xpY2suIFdpbGwgYmUgdHJ1ZSB3aGVuIG9ubHkgb25lIHBvaW50ZXIgaXMgYWN0aXZlLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuZW11bGF0ZUNsaWNrc18gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHJhZ2dpbmdfID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFBcnJheTxpbXBvcnQoXCIuL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5kcmFnTGlzdGVuZXJLZXlzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLm1vdmVUb2xlcmFuY2VfID0gbW92ZVRvbGVyYW5jZSA/IG1vdmVUb2xlcmFuY2UgKiBERVZJQ0VfUElYRUxfUkFUSU8gOiBERVZJQ0VfUElYRUxfUkFUSU87XG4gICAgLyoqXG4gICAgICogVGhlIG1vc3QgcmVjZW50IFwiZG93blwiIHR5cGUgZXZlbnQgKG9yIG51bGwgaWYgbm9uZSBoYXZlIG9jY3VycmVkKS5cbiAgICAgKiBTZXQgb24gcG9pbnRlcmRvd24uXG4gICAgICogQHR5cGUge1BvaW50ZXJFdmVudH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuZG93bl8gPSBudWxsO1xuXG4gICAgdmFyIGVsZW1lbnQgPSBfdGhpcy5tYXBfLmdldFZpZXdwb3J0KCk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5hY3RpdmVQb2ludGVyc18gPSAwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PG51bWJlciwgYm9vbGVhbj59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnRyYWNrZWRUb3VjaGVzXyA9IHt9O1xuICAgIF90aGlzLmVsZW1lbnRfID0gZWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMucG9pbnRlcmRvd25MaXN0ZW5lcktleV8gPSBsaXN0ZW4oZWxlbWVudCwgUG9pbnRlckV2ZW50VHlwZS5QT0lOVEVSRE9XTiwgX3RoaXMuaGFuZGxlUG9pbnRlckRvd25fLCBfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge1BvaW50ZXJFdmVudH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMub3JpZ2luYWxQb2ludGVyTW92ZUV2ZW50XztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVsYXllZExpc3RlbmVyS2V5XyA9IGxpc3RlbihlbGVtZW50LCBQb2ludGVyRXZlbnRUeXBlLlBPSU5URVJNT1ZFLCBfdGhpcy5yZWxheUV2ZW50XywgX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZVRvdWNoTW92ZV8gPSBfdGhpcy5oYW5kbGVUb3VjaE1vdmVfLmJpbmQoX3RoaXMpO1xuXG4gICAgX3RoaXMuZWxlbWVudF8uYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuVE9VQ0hNT1ZFLCBfdGhpcy5ib3VuZEhhbmRsZVRvdWNoTW92ZV8sIFBBU1NJVkVfRVZFTlRfTElTVEVORVJTID8ge1xuICAgICAgcGFzc2l2ZTogZmFsc2VcbiAgICB9IDogZmFsc2UpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1BvaW50ZXJFdmVudH0gcG9pbnRlckV2ZW50IFBvaW50ZXJcbiAgICogZXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUuZW11bGF0ZUNsaWNrXyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICB2YXIgbmV3RXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KE1hcEJyb3dzZXJFdmVudFR5cGUuQ0xJQ0ssIHRoaXMubWFwXywgcG9pbnRlckV2ZW50KTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3RXZlbnQpO1xuXG4gICAgaWYgKHRoaXMuY2xpY2tUaW1lb3V0SWRfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGRvdWJsZS1jbGlja1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuY2xpY2tUaW1lb3V0SWRfKTtcbiAgICAgIHRoaXMuY2xpY2tUaW1lb3V0SWRfID0gdW5kZWZpbmVkO1xuICAgICAgbmV3RXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KE1hcEJyb3dzZXJFdmVudFR5cGUuREJMQ0xJQ0ssIHRoaXMubWFwXywgcG9pbnRlckV2ZW50KTtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNsaWNrXG4gICAgICB0aGlzLmNsaWNrVGltZW91dElkXyA9IHNldFRpbWVvdXQoXG4gICAgICAvKiogQHRoaXMge01hcEJyb3dzZXJFdmVudEhhbmRsZXJ9ICovXG4gICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuY2xpY2tUaW1lb3V0SWRfID0gdW5kZWZpbmVkO1xuICAgICAgICB2YXIgbmV3RXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KE1hcEJyb3dzZXJFdmVudFR5cGUuU0lOR0xFQ0xJQ0ssIHRoaXMubWFwXywgcG9pbnRlckV2ZW50KTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ld0V2ZW50KTtcbiAgICAgIH0uYmluZCh0aGlzKSwgMjUwKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBLZWVwcyB0cmFjayBvbiBob3cgbWFueSBwb2ludGVycyBhcmUgY3VycmVudGx5IGFjdGl2ZS5cbiAgICpcbiAgICogQHBhcmFtIHtQb2ludGVyRXZlbnR9IHBvaW50ZXJFdmVudCBQb2ludGVyXG4gICAqIGV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIucHJvdG90eXBlLnVwZGF0ZUFjdGl2ZVBvaW50ZXJzXyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICB2YXIgZXZlbnQgPSBwb2ludGVyRXZlbnQ7XG5cbiAgICBpZiAoZXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCB8fCBldmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkNBTkNFTCkge1xuICAgICAgZGVsZXRlIHRoaXMudHJhY2tlZFRvdWNoZXNfW2V2ZW50LnBvaW50ZXJJZF07XG4gICAgfSBlbHNlIGlmIChldmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkRPV04pIHtcbiAgICAgIHRoaXMudHJhY2tlZFRvdWNoZXNfW2V2ZW50LnBvaW50ZXJJZF0gPSB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuYWN0aXZlUG9pbnRlcnNfID0gT2JqZWN0LmtleXModGhpcy50cmFja2VkVG91Y2hlc18pLmxlbmd0aDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVQb2ludGVyVXBfID0gZnVuY3Rpb24gKHBvaW50ZXJFdmVudCkge1xuICAgIHRoaXMudXBkYXRlQWN0aXZlUG9pbnRlcnNfKHBvaW50ZXJFdmVudCk7XG4gICAgdmFyIG5ld0V2ZW50ID0gbmV3IE1hcEJyb3dzZXJFdmVudChNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCwgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7IC8vIFdlIGVtdWxhdGUgY2xpY2sgZXZlbnRzIG9uIGxlZnQgbW91c2UgYnV0dG9uIGNsaWNrLCB0b3VjaCBjb250YWN0LCBhbmQgcGVuXG4gICAgLy8gY29udGFjdC4gaXNNb3VzZUFjdGlvbkJ1dHRvbiByZXR1cm5zIHRydWUgaW4gdGhlc2UgY2FzZXMgKGV2dC5idXR0b24gaXMgc2V0XG4gICAgLy8gdG8gMCkuXG4gICAgLy8gU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3BvaW50ZXJldmVudHMvI2J1dHRvbi1zdGF0ZXNcbiAgICAvLyBXZSBvbmx5IGZpcmUgY2xpY2ssIHNpbmdsZWNsaWNrLCBhbmQgZG91YmxlY2xpY2sgaWYgbm9ib2R5IGhhcyBjYWxsZWRcbiAgICAvLyBldmVudC5zdG9wUHJvcGFnYXRpb24oKSBvciBldmVudC5wcmV2ZW50RGVmYXVsdCgpLlxuXG4gICAgaWYgKHRoaXMuZW11bGF0ZUNsaWNrc18gJiYgIW5ld0V2ZW50LnByb3BhZ2F0aW9uU3RvcHBlZCAmJiAhdGhpcy5kcmFnZ2luZ18gJiYgdGhpcy5pc01vdXNlQWN0aW9uQnV0dG9uXyhwb2ludGVyRXZlbnQpKSB7XG4gICAgICB0aGlzLmVtdWxhdGVDbGlja18odGhpcy5kb3duXyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWN0aXZlUG9pbnRlcnNfID09PSAwKSB7XG4gICAgICB0aGlzLmRyYWdMaXN0ZW5lcktleXNfLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gICAgICB0aGlzLmRyYWdMaXN0ZW5lcktleXNfLmxlbmd0aCA9IDA7XG4gICAgICB0aGlzLmRyYWdnaW5nXyA9IGZhbHNlO1xuICAgICAgdGhpcy5kb3duXyA9IG51bGw7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtQb2ludGVyRXZlbnR9IHBvaW50ZXJFdmVudCBQb2ludGVyXG4gICAqIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgbGVmdCBtb3VzZSBidXR0b24gd2FzIHByZXNzZWQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUuaXNNb3VzZUFjdGlvbkJ1dHRvbl8gPSBmdW5jdGlvbiAocG9pbnRlckV2ZW50KSB7XG4gICAgcmV0dXJuIHBvaW50ZXJFdmVudC5idXR0b24gPT09IDA7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1BvaW50ZXJFdmVudH0gcG9pbnRlckV2ZW50IFBvaW50ZXJcbiAgICogZXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUuaGFuZGxlUG9pbnRlckRvd25fID0gZnVuY3Rpb24gKHBvaW50ZXJFdmVudCkge1xuICAgIHRoaXMuZW11bGF0ZUNsaWNrc18gPSB0aGlzLmFjdGl2ZVBvaW50ZXJzXyA9PT0gMDtcbiAgICB0aGlzLnVwZGF0ZUFjdGl2ZVBvaW50ZXJzXyhwb2ludGVyRXZlbnQpO1xuICAgIHZhciBuZXdFdmVudCA9IG5ldyBNYXBCcm93c2VyRXZlbnQoTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRE9XTiwgdGhpcy5tYXBfLCBwb2ludGVyRXZlbnQpO1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXdFdmVudCk7XG4gICAgdGhpcy5kb3duXyA9IHBvaW50ZXJFdmVudDtcblxuICAgIGlmICh0aGlzLmRyYWdMaXN0ZW5lcktleXNfLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdmFyIGRvYyA9IHRoaXMubWFwXy5nZXRPd25lckRvY3VtZW50KCk7XG4gICAgICB0aGlzLmRyYWdMaXN0ZW5lcktleXNfLnB1c2gobGlzdGVuKGRvYywgTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSTU9WRSwgdGhpcy5oYW5kbGVQb2ludGVyTW92ZV8sIHRoaXMpLCBsaXN0ZW4oZG9jLCBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCwgdGhpcy5oYW5kbGVQb2ludGVyVXBfLCB0aGlzKSxcbiAgICAgIC8qIE5vdGUgdGhhdCB0aGUgbGlzdGVuZXIgZm9yIGBwb2ludGVyY2FuY2VsIGlzIHNldCB1cCBvblxuICAgICAgICogYHBvaW50ZXJFdmVudEhhbmRsZXJfYCBhbmQgbm90IGBkb2N1bWVudFBvaW50ZXJFdmVudEhhbmRsZXJfYCBsaWtlXG4gICAgICAgKiB0aGUgYHBvaW50ZXJ1cGAgYW5kIGBwb2ludGVybW92ZWAgbGlzdGVuZXJzLlxuICAgICAgICpcbiAgICAgICAqIFRoZSByZWFzb24gZm9yIHRoaXMgaXMgdGhlIGZvbGxvd2luZzogYFRvdWNoU291cmNlLnZhY3V1bVRvdWNoZXNfKClgXG4gICAgICAgKiBpc3N1ZXMgYHBvaW50ZXJjYW5jZWxgIGV2ZW50cywgd2hlbiB0aGVyZSB3YXMgbm8gYHRvdWNoZW5kYCBmb3IgYVxuICAgICAgICogYHRvdWNoc3RhcnRgLiBOb3csIGxldCdzIHNheSBhIGZpcnN0IGB0b3VjaHN0YXJ0YCBpcyByZWdpc3RlcmVkIG9uXG4gICAgICAgKiBgcG9pbnRlckV2ZW50SGFuZGxlcl9gLiBUaGUgYGRvY3VtZW50UG9pbnRlckV2ZW50SGFuZGxlcl9gIGlzIHNldCB1cC5cbiAgICAgICAqIEJ1dCBgZG9jdW1lbnRQb2ludGVyRXZlbnRIYW5kbGVyX2AgZG9lc24ndCBrbm93IGFib3V0IHRoZSBmaXJzdFxuICAgICAgICogYHRvdWNoc3RhcnRgLiBJZiB0aGVyZSBpcyBubyBgdG91Y2hlbmRgIGZvciB0aGUgYHRvdWNoc3RhcnRgLCB3ZSBjYW5cbiAgICAgICAqIG9ubHkgcmVjZWl2ZSBhIGB0b3VjaGNhbmNlbGAgZnJvbSBgcG9pbnRlckV2ZW50SGFuZGxlcl9gLCBiZWNhdXNlIGl0IGlzXG4gICAgICAgKiBvbmx5IHJlZ2lzdGVyZWQgdGhlcmUuXG4gICAgICAgKi9cbiAgICAgIGxpc3Rlbih0aGlzLmVsZW1lbnRfLCBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJDQU5DRUwsIHRoaXMuaGFuZGxlUG9pbnRlclVwXywgdGhpcykpO1xuXG4gICAgICBpZiAodGhpcy5lbGVtZW50Xy5nZXRSb290Tm9kZSAmJiB0aGlzLmVsZW1lbnRfLmdldFJvb3ROb2RlKCkgIT09IGRvYykge1xuICAgICAgICB0aGlzLmRyYWdMaXN0ZW5lcktleXNfLnB1c2gobGlzdGVuKHRoaXMuZWxlbWVudF8uZ2V0Um9vdE5vZGUoKSwgTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSVVAsIHRoaXMuaGFuZGxlUG9pbnRlclVwXywgdGhpcykpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVQb2ludGVyTW92ZV8gPSBmdW5jdGlvbiAocG9pbnRlckV2ZW50KSB7XG4gICAgLy8gQmV0d2VlbiBwb2ludGVyZG93biBhbmQgcG9pbnRlcnVwLCBwb2ludGVybW92ZSBldmVudHMgYXJlIHRyaWdnZXJlZC5cbiAgICAvLyBUbyBhdm9pZCBhICdmYWxzZScgdG91Y2htb3ZlIGV2ZW50IHRvIGJlIGRpc3BhdGNoZWQsIHdlIHRlc3QgaWYgdGhlIHBvaW50ZXJcbiAgICAvLyBtb3ZlZCBhIHNpZ25pZmljYW50IGRpc3RhbmNlLlxuICAgIGlmICh0aGlzLmlzTW92aW5nXyhwb2ludGVyRXZlbnQpKSB7XG4gICAgICB0aGlzLmRyYWdnaW5nXyA9IHRydWU7XG4gICAgICB2YXIgbmV3RXZlbnQgPSBuZXcgTWFwQnJvd3NlckV2ZW50KE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkRSQUcsIHRoaXMubWFwXywgcG9pbnRlckV2ZW50LCB0aGlzLmRyYWdnaW5nXyk7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3RXZlbnQpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFdyYXAgYW5kIHJlbGF5IGEgcG9pbnRlciBldmVudC4gIE5vdGUgdGhhdCB0aGlzIHJlcXVpcmVzIHRoYXQgdGhlIHR5cGVcbiAgICogc3RyaW5nIGZvciB0aGUgTWFwQnJvd3NlckV2ZW50IG1hdGNoZXMgdGhlIFBvaW50ZXJFdmVudCB0eXBlLlxuICAgKiBAcGFyYW0ge1BvaW50ZXJFdmVudH0gcG9pbnRlckV2ZW50IFBvaW50ZXJcbiAgICogZXZlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUucmVsYXlFdmVudF8gPSBmdW5jdGlvbiAocG9pbnRlckV2ZW50KSB7XG4gICAgdGhpcy5vcmlnaW5hbFBvaW50ZXJNb3ZlRXZlbnRfID0gcG9pbnRlckV2ZW50O1xuICAgIHZhciBkcmFnZ2luZyA9ICEhKHRoaXMuZG93bl8gJiYgdGhpcy5pc01vdmluZ18ocG9pbnRlckV2ZW50KSk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBNYXBCcm93c2VyRXZlbnQocG9pbnRlckV2ZW50LnR5cGUsIHRoaXMubWFwXywgcG9pbnRlckV2ZW50LCBkcmFnZ2luZykpO1xuICB9O1xuICAvKipcbiAgICogRmxleGlibGUgaGFuZGxpbmcgb2YgYSBgdG91Y2gtYWN0aW9uOiBub25lYCBjc3MgZXF1aXZhbGVudDogYmVjYXVzZSBjYWxsaW5nXG4gICAqIGBwcmV2ZW50RGVmYXVsdCgpYCBvbiBhIGBwb2ludGVybW92ZWAgZXZlbnQgZG9lcyBub3Qgc3RvcCBuYXRpdmUgcGFnZSBzY3JvbGxpbmdcbiAgICogYW5kIHpvb21pbmcsIHdlIGFsc28gbGlzdGVuIGZvciBgdG91Y2htb3ZlYCBhbmQgY2FsbCBgcHJldmVudERlZmF1bHQoKWAgb24gaXRcbiAgICogd2hlbiBhbiBpbnRlcmFjdGlvbiAoY3VycmVudGx5IGBEcmFnUGFuYCBoYW5kbGVzIHRoZSBldmVudC5cbiAgICogQHBhcmFtIHtUb3VjaEV2ZW50fSBldmVudCBFdmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNYXBCcm93c2VyRXZlbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUb3VjaE1vdmVfID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgLy8gRHVlIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9tcGl6ZW5iZXJnL2VsbS1wZXAvaXNzdWVzLzIsIGB0aGlzLm9yaWdpbmFsUG9pbnRlck1vdmVFdmVudF9gXG4gICAgLy8gbWF5IG5vdCBiZSBpbml0aWFsaXplZCB5ZXQgd2hlbiB3ZSBnZXQgaGVyZSBvbiBhIHBsYXRmb3JtIHdpdGhvdXQgbmF0aXZlIHBvaW50ZXIgZXZlbnRzLlxuICAgIGlmICghdGhpcy5vcmlnaW5hbFBvaW50ZXJNb3ZlRXZlbnRfIHx8IHRoaXMub3JpZ2luYWxQb2ludGVyTW92ZUV2ZW50Xy5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7UG9pbnRlckV2ZW50fSBwb2ludGVyRXZlbnQgUG9pbnRlclxuICAgKiBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgbW92aW5nLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1hcEJyb3dzZXJFdmVudEhhbmRsZXIucHJvdG90eXBlLmlzTW92aW5nXyA9IGZ1bmN0aW9uIChwb2ludGVyRXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5kcmFnZ2luZ18gfHwgTWF0aC5hYnMocG9pbnRlckV2ZW50LmNsaWVudFggLSB0aGlzLmRvd25fLmNsaWVudFgpID4gdGhpcy5tb3ZlVG9sZXJhbmNlXyB8fCBNYXRoLmFicyhwb2ludGVyRXZlbnQuY2xpZW50WSAtIHRoaXMuZG93bl8uY2xpZW50WSkgPiB0aGlzLm1vdmVUb2xlcmFuY2VfO1xuICB9O1xuICAvKipcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgTWFwQnJvd3NlckV2ZW50SGFuZGxlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnJlbGF5ZWRMaXN0ZW5lcktleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy5yZWxheWVkTGlzdGVuZXJLZXlfKTtcbiAgICAgIHRoaXMucmVsYXllZExpc3RlbmVyS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5lbGVtZW50Xy5yZW1vdmVFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5UT1VDSE1PVkUsIHRoaXMuYm91bmRIYW5kbGVUb3VjaE1vdmVfKTtcblxuICAgIGlmICh0aGlzLnBvaW50ZXJkb3duTGlzdGVuZXJLZXlfKSB7XG4gICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMucG9pbnRlcmRvd25MaXN0ZW5lcktleV8pO1xuICAgICAgdGhpcy5wb2ludGVyZG93bkxpc3RlbmVyS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnTGlzdGVuZXJLZXlzXy5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgIHRoaXMuZHJhZ0xpc3RlbmVyS2V5c18ubGVuZ3RoID0gMDtcbiAgICB0aGlzLmVsZW1lbnRfID0gbnVsbDtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIE1hcEJyb3dzZXJFdmVudEhhbmRsZXI7XG59KEV2ZW50VGFyZ2V0KTtcblxuZXhwb3J0IGRlZmF1bHQgTWFwQnJvd3NlckV2ZW50SGFuZGxlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvTWFwRXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgYWZ0ZXIgYSBtYXAgZnJhbWUgaXMgcmVuZGVyZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwRXZlbnR+TWFwRXZlbnQjcG9zdHJlbmRlclxuICAgKiBAYXBpXG4gICAqL1xuICBQT1NUUkVOREVSOiAncG9zdHJlbmRlcicsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIHRoZSBtYXAgc3RhcnRzIG1vdmluZy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9NYXBFdmVudH5NYXBFdmVudCNtb3Zlc3RhcnRcbiAgICogQGFwaVxuICAgKi9cbiAgTU9WRVNUQVJUOiAnbW92ZXN0YXJ0JyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIGFmdGVyIHRoZSBtYXAgaXMgbW92ZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvTWFwRXZlbnR+TWFwRXZlbnQjbW92ZWVuZFxuICAgKiBAYXBpXG4gICAqL1xuICBNT1ZFRU5EOiAnbW92ZWVuZCdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL01hcFByb3BlcnR5XG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIExBWUVSR1JPVVA6ICdsYXllcmdyb3VwJyxcbiAgU0laRTogJ3NpemUnLFxuICBUQVJHRVQ6ICd0YXJnZXQnLFxuICBWSUVXOiAndmlldydcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0cnVjdHMvUHJpb3JpdHlRdWV1ZVxuICovXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGNsZWFyIH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIERST1AgPSBJbmZpbml0eTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJpb3JpdHkgcXVldWUuXG4gKlxuICogVGhlIGltcGxlbWVudGF0aW9uIGlzIGluc3BpcmVkIGZyb20gdGhlIENsb3N1cmUgTGlicmFyeSdzIEhlYXAgY2xhc3MgYW5kXG4gKiBQeXRob24ncyBoZWFwcSBtb2R1bGUuXG4gKlxuICogU2VlIGh0dHA6Ly9jbG9zdXJlLWxpYnJhcnkuZ29vZ2xlY29kZS5jb20vc3ZuL2RvY3MvY2xvc3VyZV9nb29nX3N0cnVjdHNfaGVhcC5qcy5zb3VyY2UuaHRtbFxuICogYW5kIGh0dHA6Ly9oZy5weXRob24ub3JnL2NweXRob24vZmlsZS8yLjcvTGliL2hlYXBxLnB5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cblxudmFyIFByaW9yaXR5UXVldWUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtmdW5jdGlvbihUKTogbnVtYmVyfSBwcmlvcml0eUZ1bmN0aW9uIFByaW9yaXR5IGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFQpOiBzdHJpbmd9IGtleUZ1bmN0aW9uIEtleSBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIFByaW9yaXR5UXVldWUocHJpb3JpdHlGdW5jdGlvbiwga2V5RnVuY3Rpb24pIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oVCk6IG51bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMucHJpb3JpdHlGdW5jdGlvbl8gPSBwcmlvcml0eUZ1bmN0aW9uO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtmdW5jdGlvbihUKTogc3RyaW5nfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLmtleUZ1bmN0aW9uXyA9IGtleUZ1bmN0aW9uO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxUPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy5lbGVtZW50c18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgdGhpcy5wcmlvcml0aWVzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgYm9vbGVhbj59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMucXVldWVkRWxlbWVudHNfID0ge307XG4gIH1cbiAgLyoqXG4gICAqIEZJWE1FIGVtcHR5IGRlc2NyaXB0aW9uIGZvciBqc2RvY1xuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZWxlbWVudHNfLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5wcmlvcml0aWVzXy5sZW5ndGggPSAwO1xuICAgIGNsZWFyKHRoaXMucXVldWVkRWxlbWVudHNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbmQgcmV0dXJuIHRoZSBoaWdoZXN0LXByaW9yaXR5IGVsZW1lbnQuIE8obG9nIE4pLlxuICAgKiBAcmV0dXJuIHtUfSBFbGVtZW50LlxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmRlcXVldWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50c187XG4gICAgdmFyIHByaW9yaXRpZXMgPSB0aGlzLnByaW9yaXRpZXNfO1xuICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNbMF07XG5cbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoID09IDEpIHtcbiAgICAgIGVsZW1lbnRzLmxlbmd0aCA9IDA7XG4gICAgICBwcmlvcml0aWVzLmxlbmd0aCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnRzWzBdID0gZWxlbWVudHMucG9wKCk7XG4gICAgICBwcmlvcml0aWVzWzBdID0gcHJpb3JpdGllcy5wb3AoKTtcbiAgICAgIHRoaXMuc2lmdFVwXygwKTtcbiAgICB9XG5cbiAgICB2YXIgZWxlbWVudEtleSA9IHRoaXMua2V5RnVuY3Rpb25fKGVsZW1lbnQpO1xuICAgIGRlbGV0ZSB0aGlzLnF1ZXVlZEVsZW1lbnRzX1tlbGVtZW50S2V5XTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfTtcbiAgLyoqXG4gICAqIEVucXVldWUgYW4gZWxlbWVudC4gTyhsb2cgTikuXG4gICAqIEBwYXJhbSB7VH0gZWxlbWVudCBFbGVtZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgZWxlbWVudCB3YXMgYWRkZWQgdG8gdGhlIHF1ZXVlLlxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmVucXVldWUgPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgIGFzc2VydCghKHRoaXMua2V5RnVuY3Rpb25fKGVsZW1lbnQpIGluIHRoaXMucXVldWVkRWxlbWVudHNfKSwgMzEpOyAvLyBUcmllZCB0byBlbnF1ZXVlIGFuIGBlbGVtZW50YCB0aGF0IHdhcyBhbHJlYWR5IGFkZGVkIHRvIHRoZSBxdWV1ZVxuXG4gICAgdmFyIHByaW9yaXR5ID0gdGhpcy5wcmlvcml0eUZ1bmN0aW9uXyhlbGVtZW50KTtcblxuICAgIGlmIChwcmlvcml0eSAhPSBEUk9QKSB7XG4gICAgICB0aGlzLmVsZW1lbnRzXy5wdXNoKGVsZW1lbnQpO1xuICAgICAgdGhpcy5wcmlvcml0aWVzXy5wdXNoKHByaW9yaXR5KTtcbiAgICAgIHRoaXMucXVldWVkRWxlbWVudHNfW3RoaXMua2V5RnVuY3Rpb25fKGVsZW1lbnQpXSA9IHRydWU7XG4gICAgICB0aGlzLnNpZnREb3duXygwLCB0aGlzLmVsZW1lbnRzXy5sZW5ndGggLSAxKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gQ291bnQuXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuZ2V0Q291bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudHNfLmxlbmd0aDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldHMgdGhlIGluZGV4IG9mIHRoZSBsZWZ0IGNoaWxkIG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBnZXQgdGhlIGxlZnQgY2hpbGQgZm9yLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBpbmRleCBvZiB0aGUgbGVmdCBjaGlsZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5nZXRMZWZ0Q2hpbGRJbmRleF8gPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICByZXR1cm4gaW5kZXggKiAyICsgMTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldHMgdGhlIGluZGV4IG9mIHRoZSByaWdodCBjaGlsZCBvZiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIG5vZGUgdG8gZ2V0IHRoZSByaWdodCBjaGlsZCBmb3IuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSByaWdodCBjaGlsZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5nZXRSaWdodENoaWxkSW5kZXhfID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4ICogMiArIDI7XG4gIH07XG4gIC8qKlxuICAgKiBHZXRzIHRoZSBpbmRleCBvZiB0aGUgcGFyZW50IG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBnZXQgdGhlIHBhcmVudCBmb3IuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIGluZGV4IG9mIHRoZSBwYXJlbnQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUuZ2V0UGFyZW50SW5kZXhfID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgcmV0dXJuIGluZGV4IC0gMSA+PiAxO1xuICB9O1xuICAvKipcbiAgICogTWFrZSB0aGlzIGEgaGVhcC4gTyhOKS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5oZWFwaWZ5XyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaTtcblxuICAgIGZvciAoaSA9ICh0aGlzLmVsZW1lbnRzXy5sZW5ndGggPj4gMSkgLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdGhpcy5zaWZ0VXBfKGkpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElzIGVtcHR5LlxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudHNfLmxlbmd0aCA9PT0gMDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBrZXkgcXVldWVkLlxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmlzS2V5UXVldWVkID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiBrZXkgaW4gdGhpcy5xdWV1ZWRFbGVtZW50c187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1R9IGVsZW1lbnQgRWxlbWVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgcXVldWVkLlxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLmlzUXVldWVkID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gdGhpcy5pc0tleVF1ZXVlZCh0aGlzLmtleUZ1bmN0aW9uXyhlbGVtZW50KSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBub2RlIHRvIG1vdmUgZG93bi5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZS5zaWZ0VXBfID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgdmFyIGVsZW1lbnRzID0gdGhpcy5lbGVtZW50c187XG4gICAgdmFyIHByaW9yaXRpZXMgPSB0aGlzLnByaW9yaXRpZXNfO1xuICAgIHZhciBjb3VudCA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRzW2luZGV4XTtcbiAgICB2YXIgcHJpb3JpdHkgPSBwcmlvcml0aWVzW2luZGV4XTtcbiAgICB2YXIgc3RhcnRJbmRleCA9IGluZGV4O1xuXG4gICAgd2hpbGUgKGluZGV4IDwgY291bnQgPj4gMSkge1xuICAgICAgdmFyIGxJbmRleCA9IHRoaXMuZ2V0TGVmdENoaWxkSW5kZXhfKGluZGV4KTtcbiAgICAgIHZhciBySW5kZXggPSB0aGlzLmdldFJpZ2h0Q2hpbGRJbmRleF8oaW5kZXgpO1xuICAgICAgdmFyIHNtYWxsZXJDaGlsZEluZGV4ID0gckluZGV4IDwgY291bnQgJiYgcHJpb3JpdGllc1tySW5kZXhdIDwgcHJpb3JpdGllc1tsSW5kZXhdID8gckluZGV4IDogbEluZGV4O1xuICAgICAgZWxlbWVudHNbaW5kZXhdID0gZWxlbWVudHNbc21hbGxlckNoaWxkSW5kZXhdO1xuICAgICAgcHJpb3JpdGllc1tpbmRleF0gPSBwcmlvcml0aWVzW3NtYWxsZXJDaGlsZEluZGV4XTtcbiAgICAgIGluZGV4ID0gc21hbGxlckNoaWxkSW5kZXg7XG4gICAgfVxuXG4gICAgZWxlbWVudHNbaW5kZXhdID0gZWxlbWVudDtcbiAgICBwcmlvcml0aWVzW2luZGV4XSA9IHByaW9yaXR5O1xuICAgIHRoaXMuc2lmdERvd25fKHN0YXJ0SW5kZXgsIGluZGV4KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydEluZGV4IFRoZSBpbmRleCBvZiB0aGUgcm9vdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCBvZiB0aGUgbm9kZSB0byBtb3ZlIHVwLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFByaW9yaXR5UXVldWUucHJvdG90eXBlLnNpZnREb3duXyA9IGZ1bmN0aW9uIChzdGFydEluZGV4LCBpbmRleCkge1xuICAgIHZhciBlbGVtZW50cyA9IHRoaXMuZWxlbWVudHNfO1xuICAgIHZhciBwcmlvcml0aWVzID0gdGhpcy5wcmlvcml0aWVzXztcbiAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRzW2luZGV4XTtcbiAgICB2YXIgcHJpb3JpdHkgPSBwcmlvcml0aWVzW2luZGV4XTtcblxuICAgIHdoaWxlIChpbmRleCA+IHN0YXJ0SW5kZXgpIHtcbiAgICAgIHZhciBwYXJlbnRJbmRleCA9IHRoaXMuZ2V0UGFyZW50SW5kZXhfKGluZGV4KTtcblxuICAgICAgaWYgKHByaW9yaXRpZXNbcGFyZW50SW5kZXhdID4gcHJpb3JpdHkpIHtcbiAgICAgICAgZWxlbWVudHNbaW5kZXhdID0gZWxlbWVudHNbcGFyZW50SW5kZXhdO1xuICAgICAgICBwcmlvcml0aWVzW2luZGV4XSA9IHByaW9yaXRpZXNbcGFyZW50SW5kZXhdO1xuICAgICAgICBpbmRleCA9IHBhcmVudEluZGV4O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZWxlbWVudHNbaW5kZXhdID0gZWxlbWVudDtcbiAgICBwcmlvcml0aWVzW2luZGV4XSA9IHByaW9yaXR5O1xuICB9O1xuICAvKipcbiAgICogRklYTUUgZW1wdHkgZGVzY3JpcHRpb24gZm9yIGpzZG9jXG4gICAqL1xuXG5cbiAgUHJpb3JpdHlRdWV1ZS5wcm90b3R5cGUucmVwcmlvcml0aXplID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcmlvcml0eUZ1bmN0aW9uID0gdGhpcy5wcmlvcml0eUZ1bmN0aW9uXztcbiAgICB2YXIgZWxlbWVudHMgPSB0aGlzLmVsZW1lbnRzXztcbiAgICB2YXIgcHJpb3JpdGllcyA9IHRoaXMucHJpb3JpdGllc187XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbiA9IGVsZW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgZWxlbWVudCwgaSwgcHJpb3JpdHk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBlbGVtZW50ID0gZWxlbWVudHNbaV07XG4gICAgICBwcmlvcml0eSA9IHByaW9yaXR5RnVuY3Rpb24oZWxlbWVudCk7XG5cbiAgICAgIGlmIChwcmlvcml0eSA9PSBEUk9QKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnF1ZXVlZEVsZW1lbnRzX1t0aGlzLmtleUZ1bmN0aW9uXyhlbGVtZW50KV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmlvcml0aWVzW2luZGV4XSA9IHByaW9yaXR5O1xuICAgICAgICBlbGVtZW50c1tpbmRleCsrXSA9IGVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZWxlbWVudHMubGVuZ3RoID0gaW5kZXg7XG4gICAgcHJpb3JpdGllcy5sZW5ndGggPSBpbmRleDtcbiAgICB0aGlzLmhlYXBpZnlfKCk7XG4gIH07XG5cbiAgcmV0dXJuIFByaW9yaXR5UXVldWU7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IFByaW9yaXR5UXVldWU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL1RpbGVTdGF0ZVxuICovXG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBJRExFOiAwLFxuICBMT0FESU5HOiAxLFxuICBMT0FERUQ6IDIsXG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGF0IHRpbGUgbG9hZGluZyBmYWlsZWRcbiAgICogQHR5cGUge251bWJlcn1cbiAgICovXG4gIEVSUk9SOiAzLFxuICBFTVBUWTogNFxufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL1RpbGVRdWV1ZVxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFByaW9yaXR5UXVldWUsIHsgRFJPUCB9IGZyb20gJy4vc3RydWN0cy9Qcmlvcml0eVF1ZXVlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi9UaWxlU3RhdGUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9UaWxlLmpzXCIpLmRlZmF1bHQsIHN0cmluZywgaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUsIG51bWJlcik6IG51bWJlcn0gUHJpb3JpdHlGdW5jdGlvblxuICovXG5cbnZhciBUaWxlUXVldWUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZVF1ZXVlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtQcmlvcml0eUZ1bmN0aW9ufSB0aWxlUHJpb3JpdHlGdW5jdGlvbiBUaWxlIHByaW9yaXR5IGZ1bmN0aW9uLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCk6ID99IHRpbGVDaGFuZ2VDYWxsYmFjayBGdW5jdGlvbiBjYWxsZWQgb24gZWFjaCB0aWxlIGNoYW5nZSBldmVudC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUaWxlUXVldWUodGlsZVByaW9yaXR5RnVuY3Rpb24sIHRpbGVDaGFuZ2VDYWxsYmFjaykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcnJheX0gZWxlbWVudCBFbGVtZW50LlxuICAgICAqIEByZXR1cm4ge251bWJlcn0gUHJpb3JpdHkuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiB0aWxlUHJpb3JpdHlGdW5jdGlvbi5hcHBseShudWxsLCBlbGVtZW50KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGVsZW1lbnQgRWxlbWVudC5cbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IEtleS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZWxlbWVudFswXS5nZXRLZXkoKVxuICAgICAgKTtcbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKiBAcHJpdmF0ZSAqL1xuXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZVRpbGVDaGFuZ2VfID0gX3RoaXMuaGFuZGxlVGlsZUNoYW5nZS5iaW5kKF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtmdW5jdGlvbigpOiA/fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZUNoYW5nZUNhbGxiYWNrXyA9IHRpbGVDaGFuZ2VDYWxsYmFjaztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlc0xvYWRpbmdfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZyxib29sZWFuPn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVzTG9hZGluZ0tleXNfID0ge307XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5fSBlbGVtZW50IEVsZW1lbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBlbGVtZW50IHdhcyBhZGRlZCB0byB0aGUgcXVldWUuXG4gICAqL1xuXG5cbiAgVGlsZVF1ZXVlLnByb3RvdHlwZS5lbnF1ZXVlID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB2YXIgYWRkZWQgPSBfc3VwZXIucHJvdG90eXBlLmVucXVldWUuY2FsbCh0aGlzLCBlbGVtZW50KTtcblxuICAgIGlmIChhZGRlZCkge1xuICAgICAgdmFyIHRpbGUgPSBlbGVtZW50WzBdO1xuICAgICAgdGlsZS5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMuYm91bmRIYW5kbGVUaWxlQ2hhbmdlXyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFkZGVkO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBOdW1iZXIgb2YgdGlsZXMgbG9hZGluZy5cbiAgICovXG5cblxuICBUaWxlUXVldWUucHJvdG90eXBlLmdldFRpbGVzTG9hZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlc0xvYWRpbmdfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBFdmVudC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVRdWV1ZS5wcm90b3R5cGUuaGFuZGxlVGlsZUNoYW5nZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciB0aWxlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIGV2ZW50LnRhcmdldDtcbiAgICB2YXIgc3RhdGUgPSB0aWxlLmdldFN0YXRlKCk7XG5cbiAgICBpZiAodGlsZS5oaWZpICYmIHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IgfHwgc3RhdGUgPT09IFRpbGVTdGF0ZS5FTVBUWSkge1xuICAgICAgdGlsZS5yZW1vdmVFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMuYm91bmRIYW5kbGVUaWxlQ2hhbmdlXyk7XG4gICAgICB2YXIgdGlsZUtleSA9IHRpbGUuZ2V0S2V5KCk7XG5cbiAgICAgIGlmICh0aWxlS2V5IGluIHRoaXMudGlsZXNMb2FkaW5nS2V5c18pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMudGlsZXNMb2FkaW5nS2V5c19bdGlsZUtleV07XG4gICAgICAgIC0tdGhpcy50aWxlc0xvYWRpbmdfO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnRpbGVDaGFuZ2VDYWxsYmFja18oKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4VG90YWxMb2FkaW5nIE1heGltdW0gbnVtYmVyIHRpbGVzIHRvIGxvYWQgc2ltdWx0YW5lb3VzbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhOZXdMb2FkcyBNYXhpbXVtIG51bWJlciBvZiBuZXcgdGlsZXMgdG8gbG9hZC5cbiAgICovXG5cblxuICBUaWxlUXVldWUucHJvdG90eXBlLmxvYWRNb3JlVGlsZXMgPSBmdW5jdGlvbiAobWF4VG90YWxMb2FkaW5nLCBtYXhOZXdMb2Fkcykge1xuICAgIHZhciBuZXdMb2FkcyA9IDA7XG4gICAgdmFyIHN0YXRlLCB0aWxlLCB0aWxlS2V5O1xuXG4gICAgd2hpbGUgKHRoaXMudGlsZXNMb2FkaW5nXyA8IG1heFRvdGFsTG9hZGluZyAmJiBuZXdMb2FkcyA8IG1heE5ld0xvYWRzICYmIHRoaXMuZ2V0Q291bnQoKSA+IDApIHtcbiAgICAgIHRpbGUgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIHRoaXMuZGVxdWV1ZSgpWzBdO1xuICAgICAgdGlsZUtleSA9IHRpbGUuZ2V0S2V5KCk7XG4gICAgICBzdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcblxuICAgICAgaWYgKHN0YXRlID09PSBUaWxlU3RhdGUuSURMRSAmJiAhKHRpbGVLZXkgaW4gdGhpcy50aWxlc0xvYWRpbmdLZXlzXykpIHtcbiAgICAgICAgdGhpcy50aWxlc0xvYWRpbmdLZXlzX1t0aWxlS2V5XSA9IHRydWU7XG4gICAgICAgICsrdGhpcy50aWxlc0xvYWRpbmdfO1xuICAgICAgICArK25ld0xvYWRzO1xuICAgICAgICB0aWxlLmxvYWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFRpbGVRdWV1ZTtcbn0oUHJpb3JpdHlRdWV1ZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFRpbGVRdWV1ZTtcbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoJy4vUGx1Z2dhYmxlTWFwLmpzJykuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0aWxlU291cmNlS2V5IFRpbGUgc291cmNlIGtleS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHRpbGVDZW50ZXIgVGlsZSBjZW50ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gdGlsZVJlc29sdXRpb24gVGlsZSByZXNvbHV0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBUaWxlIHByaW9yaXR5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaWxlUHJpb3JpdHkoZnJhbWVTdGF0ZSwgdGlsZSwgdGlsZVNvdXJjZUtleSwgdGlsZUNlbnRlciwgdGlsZVJlc29sdXRpb24pIHtcbiAgLy8gRmlsdGVyIG91dCB0aWxlcyBhdCBoaWdoZXIgem9vbSBsZXZlbHMgdGhhbiB0aGUgY3VycmVudCB6b29tIGxldmVsLCBvciB0aGF0XG4gIC8vIGFyZSBvdXRzaWRlIHRoZSB2aXNpYmxlIGV4dGVudC5cbiAgaWYgKCFmcmFtZVN0YXRlIHx8ICEodGlsZVNvdXJjZUtleSBpbiBmcmFtZVN0YXRlLndhbnRlZFRpbGVzKSkge1xuICAgIHJldHVybiBEUk9QO1xuICB9XG5cbiAgaWYgKCFmcmFtZVN0YXRlLndhbnRlZFRpbGVzW3RpbGVTb3VyY2VLZXldW3RpbGUuZ2V0S2V5KCldKSB7XG4gICAgcmV0dXJuIERST1A7XG4gIH0gLy8gUHJpb3JpdGl6ZSB0aGUgaGlnaGVzdCB6b29tIGxldmVsIHRpbGVzIGNsb3Nlc3QgdG8gdGhlIGZvY3VzLlxuICAvLyBUaWxlcyBhdCBoaWdoZXIgem9vbSBsZXZlbHMgYXJlIHByaW9yaXRpemVkIHVzaW5nIE1hdGgubG9nKHRpbGVSZXNvbHV0aW9uKS5cbiAgLy8gV2l0aGluIGEgem9vbSBsZXZlbCwgdGlsZXMgYXJlIHByaW9yaXRpemVkIGJ5IHRoZSBkaXN0YW5jZSBpbiBwaXhlbHMgYmV0d2VlblxuICAvLyB0aGUgY2VudGVyIG9mIHRoZSB0aWxlIGFuZCB0aGUgY2VudGVyIG9mIHRoZSB2aWV3cG9ydC4gIFRoZSBmYWN0b3Igb2YgNjU1MzZcbiAgLy8gbWVhbnMgdGhhdCB0aGUgcHJpb3JpdGl6YXRpb24gc2hvdWxkIGJlaGF2ZSBhcyBkZXNpcmVkIGZvciB0aWxlcyB1cCB0b1xuICAvLyA2NTUzNiAqIE1hdGgubG9nKDIpID0gNDU0MjYgcGl4ZWxzIGZyb20gdGhlIGZvY3VzLlxuXG5cbiAgdmFyIGNlbnRlciA9IGZyYW1lU3RhdGUudmlld1N0YXRlLmNlbnRlcjtcbiAgdmFyIGRlbHRhWCA9IHRpbGVDZW50ZXJbMF0gLSBjZW50ZXJbMF07XG4gIHZhciBkZWx0YVkgPSB0aWxlQ2VudGVyWzFdIC0gY2VudGVyWzFdO1xuICByZXR1cm4gNjU1MzYgKiBNYXRoLmxvZyh0aWxlUmVzb2x1dGlvbikgKyBNYXRoLnNxcnQoZGVsdGFYICogZGVsdGFYICsgZGVsdGFZICogZGVsdGFZKSAvIHRpbGVSZXNvbHV0aW9uO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL0dlb21ldHJ5VHlwZVxuICovXG5cbi8qKlxuICogVGhlIGdlb21ldHJ5IHR5cGUuIE9uZSBvZiBgJ1BvaW50J2AsIGAnTGluZVN0cmluZydgLCBgJ0xpbmVhclJpbmcnYCxcbiAqIGAnUG9seWdvbidgLCBgJ011bHRpUG9pbnQnYCwgYCdNdWx0aUxpbmVTdHJpbmcnYCwgYCdNdWx0aVBvbHlnb24nYCxcbiAqIGAnR2VvbWV0cnlDb2xsZWN0aW9uJ2AsIGAnQ2lyY2xlJ2AuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFBPSU5UOiAnUG9pbnQnLFxuICBMSU5FX1NUUklORzogJ0xpbmVTdHJpbmcnLFxuICBMSU5FQVJfUklORzogJ0xpbmVhclJpbmcnLFxuICBQT0xZR09OOiAnUG9seWdvbicsXG4gIE1VTFRJX1BPSU5UOiAnTXVsdGlQb2ludCcsXG4gIE1VTFRJX0xJTkVfU1RSSU5HOiAnTXVsdGlMaW5lU3RyaW5nJyxcbiAgTVVMVElfUE9MWUdPTjogJ011bHRpUG9seWdvbicsXG4gIEdFT01FVFJZX0NPTExFQ1RJT046ICdHZW9tZXRyeUNvbGxlY3Rpb24nLFxuICBDSVJDTEU6ICdDaXJjbGUnXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL1VuaXRzXG4gKi9cblxuLyoqXG4gKiBQcm9qZWN0aW9uIHVuaXRzOiBgJ2RlZ3JlZXMnYCwgYCdmdCdgLCBgJ20nYCwgYCdwaXhlbHMnYCwgYCd0aWxlLXBpeGVscydgIG9yXG4gKiBgJ3VzLWZ0J2AuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG52YXIgVW5pdHMgPSB7XG4gIC8qKlxuICAgKiBEZWdyZWVzXG4gICAqIEBhcGlcbiAgICovXG4gIERFR1JFRVM6ICdkZWdyZWVzJyxcblxuICAvKipcbiAgICogRmVldFxuICAgKiBAYXBpXG4gICAqL1xuICBGRUVUOiAnZnQnLFxuXG4gIC8qKlxuICAgKiBNZXRlcnNcbiAgICogQGFwaVxuICAgKi9cbiAgTUVURVJTOiAnbScsXG5cbiAgLyoqXG4gICAqIFBpeGVsc1xuICAgKiBAYXBpXG4gICAqL1xuICBQSVhFTFM6ICdwaXhlbHMnLFxuXG4gIC8qKlxuICAgKiBUaWxlIFBpeGVsc1xuICAgKiBAYXBpXG4gICAqL1xuICBUSUxFX1BJWEVMUzogJ3RpbGUtcGl4ZWxzJyxcblxuICAvKipcbiAgICogVVMgRmVldFxuICAgKiBAYXBpXG4gICAqL1xuICBVU0ZFRVQ6ICd1cy1mdCdcbn07XG4vKipcbiAqIE1ldGVycyBwZXIgdW5pdCBsb29rdXAgdGFibGUuXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtPYmplY3Q8VW5pdHMsIG51bWJlcj59XG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBNRVRFUlNfUEVSX1VOSVQgPSB7fTsgLy8gdXNlIHRoZSByYWRpdXMgb2YgdGhlIE5vcm1hbCBzcGhlcmVcblxuTUVURVJTX1BFUl9VTklUW1VuaXRzLkRFR1JFRVNdID0gMiAqIE1hdGguUEkgKiA2MzcwOTk3IC8gMzYwO1xuTUVURVJTX1BFUl9VTklUW1VuaXRzLkZFRVRdID0gMC4zMDQ4O1xuTUVURVJTX1BFUl9VTklUW1VuaXRzLk1FVEVSU10gPSAxO1xuTUVURVJTX1BFUl9VTklUW1VuaXRzLlVTRkVFVF0gPSAxMjAwIC8gMzkzNztcbmV4cG9ydCBkZWZhdWx0IFVuaXRzOyIsIi8qKlxuICogQG1vZHVsZSBvbC9WaWV3SGludFxuICovXG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBBTklNQVRJTkc6IDAsXG4gIElOVEVSQUNUSU5HOiAxXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9WaWV3UHJvcGVydHlcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgQ0VOVEVSOiAnY2VudGVyJyxcbiAgUkVTT0xVVElPTjogJ3Jlc29sdXRpb24nLFxuICBST1RBVElPTjogJ3JvdGF0aW9uJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvdGlsZWdyaWQvY29tbW9uXG4gKi9cblxuLyoqXG4gKiBEZWZhdWx0IG1heGltdW0gem9vbSBmb3IgZGVmYXVsdCB0aWxlIGdyaWRzLlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuZXhwb3J0IHZhciBERUZBVUxUX01BWF9aT09NID0gNDI7XG4vKipcbiAqIERlZmF1bHQgdGlsZSBzaXplLlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIERFRkFVTFRfVElMRV9TSVpFID0gMjU2OyIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL1Byb2plY3Rpb25cbiAqL1xuaW1wb3J0IHsgTUVURVJTX1BFUl9VTklUIH0gZnJvbSAnLi9Vbml0cy5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBjb2RlIFRoZSBTUlMgaWRlbnRpZmllciBjb2RlLCBlLmcuIGBFUFNHOjQzMjZgLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1VuaXRzLmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBbdW5pdHNdIFVuaXRzLiBSZXF1aXJlZCB1bmxlc3MgYVxuICogcHJvajQgcHJvamVjdGlvbiBpcyBkZWZpbmVkIGZvciBgY29kZWAuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSB2YWxpZGl0eSBleHRlbnQgZm9yIHRoZSBTUlMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2F4aXNPcmllbnRhdGlvbj0nZW51J10gVGhlIGF4aXMgb3JpZW50YXRpb24gYXMgc3BlY2lmaWVkIGluIFByb2o0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZ2xvYmFsPWZhbHNlXSBXaGV0aGVyIHRoZSBwcm9qZWN0aW9uIGlzIHZhbGlkIGZvciB0aGUgd2hvbGUgZ2xvYmUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21ldGVyc1BlclVuaXRdIFRoZSBtZXRlcnMgcGVyIHVuaXQgZm9yIHRoZSBTUlMuXG4gKiBJZiBub3QgcHJvdmlkZWQsIHRoZSBgdW5pdHNgIGFyZSB1c2VkIHRvIGdldCB0aGUgbWV0ZXJzIHBlciB1bml0IGZyb20gdGhlIHtAbGluayBtb2R1bGU6b2wvcHJvai9Vbml0c35NRVRFUlNfUEVSX1VOSVR9XG4gKiBsb29rdXAgdGFibGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFt3b3JsZEV4dGVudF0gVGhlIHdvcmxkIGV4dGVudCBmb3IgdGhlIFNSUy5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOm51bWJlcn0gW2dldFBvaW50UmVzb2x1dGlvbl1cbiAqIEZ1bmN0aW9uIHRvIGRldGVybWluZSByZXNvbHV0aW9uIGF0IGEgcG9pbnQuIFRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCBhXG4gKiBge251bWJlcn1gIHZpZXcgcmVzb2x1dGlvbiBhbmQgYW4gYHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9YCBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm5zXG4gKiB0aGUgYHtudW1iZXJ9YCByZXNvbHV0aW9uIGluIHByb2plY3Rpb24gdW5pdHMgYXQgdGhlIHBhc3NlZCBjb29yZGluYXRlLiBJZiB0aGlzIGlzIGB1bmRlZmluZWRgLFxuICogdGhlIGRlZmF1bHQge0BsaW5rIG1vZHVsZTpvbC9wcm9qI2dldFBvaW50UmVzb2x1dGlvbn0gZnVuY3Rpb24gd2lsbCBiZSB1c2VkLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJvamVjdGlvbiBkZWZpbml0aW9uIGNsYXNzLiBPbmUgb2YgdGhlc2UgaXMgY3JlYXRlZCBmb3IgZWFjaCBwcm9qZWN0aW9uXG4gKiBzdXBwb3J0ZWQgaW4gdGhlIGFwcGxpY2F0aW9uIGFuZCBzdG9yZWQgaW4gdGhlIHtAbGluayBtb2R1bGU6b2wvcHJvan0gbmFtZXNwYWNlLlxuICogWW91IGNhbiB1c2UgdGhlc2UgaW4gYXBwbGljYXRpb25zLCBidXQgdGhpcyBpcyBub3QgcmVxdWlyZWQsIGFzIEFQSSBwYXJhbXNcbiAqIGFuZCBvcHRpb25zIHVzZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+UHJvamVjdGlvbkxpa2V9IHdoaWNoIG1lYW5zIHRoZSBzaW1wbGUgc3RyaW5nXG4gKiBjb2RlIHdpbGwgc3VmZmljZS5cbiAqXG4gKiBZb3UgY2FuIHVzZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+Z2V0fSB0byByZXRyaWV2ZSB0aGUgb2JqZWN0IGZvciBhIHBhcnRpY3VsYXJcbiAqIHByb2plY3Rpb24uXG4gKlxuICogVGhlIGxpYnJhcnkgaW5jbHVkZXMgZGVmaW5pdGlvbnMgZm9yIGBFUFNHOjQzMjZgIGFuZCBgRVBTRzozODU3YCwgdG9nZXRoZXJcbiAqIHdpdGggdGhlIGZvbGxvd2luZyBhbGlhc2VzOlxuICogKiBgRVBTRzo0MzI2YDogQ1JTOjg0LCB1cm46b2djOmRlZjpjcnM6RVBTRzo2LjY6NDMyNixcbiAqICAgICB1cm46b2djOmRlZjpjcnM6T0dDOjEuMzpDUlM4NCwgdXJuOm9nYzpkZWY6Y3JzOk9HQzoyOjg0LFxuICogICAgIGh0dHA6Ly93d3cub3Blbmdpcy5uZXQvZ21sL3Nycy9lcHNnLnhtbCM0MzI2LFxuICogICAgIHVybjp4LW9nYzpkZWY6Y3JzOkVQU0c6NDMyNlxuICogKiBgRVBTRzozODU3YDogRVBTRzoxMDIxMDAsIEVQU0c6MTAyMTEzLCBFUFNHOjkwMDkxMyxcbiAqICAgICB1cm46b2djOmRlZjpjcnM6RVBTRzo2LjE4OjM6Mzg1NyxcbiAqICAgICBodHRwOi8vd3d3Lm9wZW5naXMubmV0L2dtbC9zcnMvZXBzZy54bWwjMzg1N1xuICpcbiAqIElmIHlvdSB1c2UgW3Byb2o0anNdKGh0dHBzOi8vZ2l0aHViLmNvbS9wcm9qNGpzL3Byb2o0anMpLCBhbGlhc2VzIGNhblxuICogYmUgYWRkZWQgdXNpbmcgYHByb2o0LmRlZnMoKWAuIEFmdGVyIGFsbCByZXF1aXJlZCBwcm9qZWN0aW9uIGRlZmluaXRpb25zIGFyZVxuICogYWRkZWQsIGNhbGwgdGhlIHtAbGluayBtb2R1bGU6b2wvcHJvai9wcm9qNH5yZWdpc3Rlcn0gZnVuY3Rpb24uXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBQcm9qZWN0aW9uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBQcm9qZWN0aW9uIG9wdGlvbnMuXG4gICAqL1xuICBmdW5jdGlvbiBQcm9qZWN0aW9uKG9wdGlvbnMpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5jb2RlXyA9IG9wdGlvbnMuY29kZTtcbiAgICAvKipcbiAgICAgKiBVbml0cyBvZiBwcm9qZWN0ZWQgY29vcmRpbmF0ZXMuIFdoZW4gc2V0IHRvIGBUSUxFX1BJWEVMU2AsIGFcbiAgICAgKiBgdGhpcy5leHRlbnRfYCBhbmQgYHRoaXMud29ybGRFeHRlbnRfYCBtdXN0IGJlIGNvbmZpZ3VyZWQgcHJvcGVybHkgZm9yIGVhY2hcbiAgICAgKiB0aWxlLlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vVW5pdHMuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMudW5pdHNfID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vVW5pdHMuanNcIikuZGVmYXVsdH0gKi9cbiAgICBvcHRpb25zLnVuaXRzO1xuICAgIC8qKlxuICAgICAqIFZhbGlkaXR5IGV4dGVudCBvZiB0aGUgcHJvamVjdGlvbiBpbiBwcm9qZWN0ZWQgY29vcmRpbmF0ZXMuIEZvciBwcm9qZWN0aW9uc1xuICAgICAqIHdpdGggYFRJTEVfUElYRUxTYCB1bml0cywgdGhpcyBpcyB0aGUgZXh0ZW50IG9mIHRoZSB0aWxlIGluXG4gICAgICogdGlsZSBwaXhlbCBzcGFjZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgdGhpcy5leHRlbnRfID0gb3B0aW9ucy5leHRlbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZXh0ZW50IDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBFeHRlbnQgb2YgdGhlIHdvcmxkIGluIEVQU0c6NDMyNi4gRm9yIHByb2plY3Rpb25zIHdpdGhcbiAgICAgKiBgVElMRV9QSVhFTFNgIHVuaXRzLCB0aGlzIGlzIHRoZSBleHRlbnQgb2YgdGhlIHRpbGUgaW5cbiAgICAgKiBwcm9qZWN0ZWQgY29vcmRpbmF0ZSBzcGFjZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgdGhpcy53b3JsZEV4dGVudF8gPSBvcHRpb25zLndvcmxkRXh0ZW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLndvcmxkRXh0ZW50IDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLmF4aXNPcmllbnRhdGlvbl8gPSBvcHRpb25zLmF4aXNPcmllbnRhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5heGlzT3JpZW50YXRpb24gOiAnZW51JztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdGhpcy5nbG9iYWxfID0gb3B0aW9ucy5nbG9iYWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZ2xvYmFsIDogZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHRoaXMuY2FuV3JhcFhfID0gISEodGhpcy5nbG9iYWxfICYmIHRoaXMuZXh0ZW50Xyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24obnVtYmVyLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOm51bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLmdldFBvaW50UmVzb2x1dGlvbkZ1bmNfID0gb3B0aW9ucy5nZXRQb2ludFJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuZGVmYXVsdFRpbGVHcmlkXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMubWV0ZXJzUGVyVW5pdF8gPSBvcHRpb25zLm1ldGVyc1BlclVuaXQ7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBwcm9qZWN0aW9uIGlzIHN1aXRhYmxlIGZvciB3cmFwcGluZyB0aGUgeC1heGlzXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuY2FuV3JhcFggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FuV3JhcFhfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb2RlIGZvciB0aGlzIHByb2plY3Rpb24sIGUuZy4gJ0VQU0c6NDMyNicuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQ29kZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLmdldENvZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29kZV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbGlkaXR5IGV4dGVudCBmb3IgdGhpcyBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBFeHRlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5nZXRFeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW50XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdW5pdHMgb2YgdGhpcyBwcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1VuaXRzLmpzXCIpLmRlZmF1bHR9IFVuaXRzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0VW5pdHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudW5pdHNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBhbW91bnQgb2YgbWV0ZXJzIHBlciB1bml0IG9mIHRoaXMgcHJvamVjdGlvbi4gIElmIHRoZSBwcm9qZWN0aW9uIGlzXG4gICAqIG5vdCBjb25maWd1cmVkIHdpdGggYG1ldGVyc1BlclVuaXRgIG9yIGEgdW5pdHMgaWRlbnRpZmllciwgdGhlIHJldHVybiBpc1xuICAgKiBgdW5kZWZpbmVkYC5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gTWV0ZXJzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0TWV0ZXJzUGVyVW5pdCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRlcnNQZXJVbml0XyB8fCBNRVRFUlNfUEVSX1VOSVRbdGhpcy51bml0c19dO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB3b3JsZCBleHRlbnQgZm9yIHRoaXMgcHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0V29ybGRFeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMud29ybGRFeHRlbnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBheGlzIG9yaWVudGF0aW9uIG9mIHRoaXMgcHJvamVjdGlvbi5cbiAgICogRXhhbXBsZSB2YWx1ZXMgYXJlOlxuICAgKiBlbnUgLSB0aGUgZGVmYXVsdCBlYXN0aW5nLCBub3J0aGluZywgZWxldmF0aW9uLlxuICAgKiBuZXUgLSBub3J0aGluZywgZWFzdGluZywgdXAgLSB1c2VmdWwgZm9yIFwibGF0L2xvbmdcIiBnZW9ncmFwaGljIGNvb3JkaW5hdGVzLFxuICAgKiAgICAgb3Igc291dGggb3JpZW50YXRlZCB0cmFuc3ZlcnNlIG1lcmNhdG9yLlxuICAgKiB3bnUgLSB3ZXN0aW5nLCBub3J0aGluZywgdXAgLSBzb21lIHBsYW5ldGFyeSBjb29yZGluYXRlIHN5c3RlbXMgaGF2ZVxuICAgKiAgICAgXCJ3ZXN0IHBvc2l0aXZlXCIgY29vcmRpbmF0ZSBzeXN0ZW1zXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQXhpcyBvcmllbnRhdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLmdldEF4aXNPcmllbnRhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5heGlzT3JpZW50YXRpb25fO1xuICB9O1xuICAvKipcbiAgICogSXMgdGhpcyBwcm9qZWN0aW9uIGEgZ2xvYmFsIHByb2plY3Rpb24gd2hpY2ggc3BhbnMgdGhlIHdob2xlIHdvcmxkP1xuICAgKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBwcm9qZWN0aW9uIGlzIGdsb2JhbC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLmlzR2xvYmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdsb2JhbF87XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgaWYgdGhlIHByb2plY3Rpb24gaXMgYSBnbG9iYWwgcHJvamVjdGlvbiB3aGljaCBzcGFucyB0aGUgd2hvbGUgd29ybGRcbiAgICogQHBhcmFtIHtib29sZWFufSBnbG9iYWwgV2hldGhlciB0aGUgcHJvamVjdGlvbiBpcyBnbG9iYWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5zZXRHbG9iYWwgPSBmdW5jdGlvbiAoZ2xvYmFsKSB7XG4gICAgdGhpcy5nbG9iYWxfID0gZ2xvYmFsO1xuICAgIHRoaXMuY2FuV3JhcFhfID0gISEoZ2xvYmFsICYmIHRoaXMuZXh0ZW50Xyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBUaGUgZGVmYXVsdCB0aWxlIGdyaWQuXG4gICAqL1xuXG5cbiAgUHJvamVjdGlvbi5wcm90b3R5cGUuZ2V0RGVmYXVsdFRpbGVHcmlkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRUaWxlR3JpZF87XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHRpbGVHcmlkIFRoZSBkZWZhdWx0IHRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5zZXREZWZhdWx0VGlsZUdyaWQgPSBmdW5jdGlvbiAodGlsZUdyaWQpIHtcbiAgICB0aGlzLmRlZmF1bHRUaWxlR3JpZF8gPSB0aWxlR3JpZDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdmFsaWRpdHkgZXh0ZW50IGZvciB0aGlzIHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLnNldEV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICB0aGlzLmV4dGVudF8gPSBleHRlbnQ7XG4gICAgdGhpcy5jYW5XcmFwWF8gPSAhISh0aGlzLmdsb2JhbF8gJiYgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgd29ybGQgZXh0ZW50IGZvciB0aGlzIHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gd29ybGRFeHRlbnQgV29ybGQgZXh0ZW50XG4gICAqICAgICBbbWlubG9uLCBtaW5sYXQsIG1heGxvbiwgbWF4bGF0XS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLnNldFdvcmxkRXh0ZW50ID0gZnVuY3Rpb24gKHdvcmxkRXh0ZW50KSB7XG4gICAgdGhpcy53b3JsZEV4dGVudF8gPSB3b3JsZEV4dGVudDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZ2V0UG9pbnRSZXNvbHV0aW9uIGZ1bmN0aW9uIChzZWUge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmdldFBvaW50UmVzb2x1dGlvbn1cbiAgICogZm9yIHRoaXMgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6bnVtYmVyfSBmdW5jIEZ1bmN0aW9uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQcm9qZWN0aW9uLnByb3RvdHlwZS5zZXRHZXRQb2ludFJlc29sdXRpb24gPSBmdW5jdGlvbiAoZnVuYykge1xuICAgIHRoaXMuZ2V0UG9pbnRSZXNvbHV0aW9uRnVuY18gPSBmdW5jO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjdXN0b20gcG9pbnQgcmVzb2x1dGlvbiBmdW5jdGlvbiBmb3IgdGhpcyBwcm9qZWN0aW9uIChpZiBzZXQpLlxuICAgKiBAcmV0dXJuIHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6bnVtYmVyfHVuZGVmaW5lZH0gVGhlIGN1c3RvbSBwb2ludFxuICAgKiByZXNvbHV0aW9uIGZ1bmN0aW9uIChpZiBzZXQpLlxuICAgKi9cblxuXG4gIFByb2plY3Rpb24ucHJvdG90eXBlLmdldFBvaW50UmVzb2x1dGlvbkZ1bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UG9pbnRSZXNvbHV0aW9uRnVuY187XG4gIH07XG5cbiAgcmV0dXJuIFByb2plY3Rpb247XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IFByb2plY3Rpb247IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL2Vwc2czODU3XG4gKi9cblxuXG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL1Byb2plY3Rpb24uanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4vVW5pdHMuanMnO1xuaW1wb3J0IHsgY29zaCB9IGZyb20gJy4uL21hdGguanMnO1xuLyoqXG4gKiBSYWRpdXMgb2YgV0dTODQgc3BoZXJlXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgUkFESVVTID0gNjM3ODEzNztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgSEFMRl9TSVpFID0gTWF0aC5QSSAqIFJBRElVUztcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAqL1xuXG5leHBvcnQgdmFyIEVYVEVOVCA9IFstSEFMRl9TSVpFLCAtSEFMRl9TSVpFLCBIQUxGX1NJWkUsIEhBTEZfU0laRV07XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gKi9cblxuZXhwb3J0IHZhciBXT1JMRF9FWFRFTlQgPSBbLTE4MCwgLTg1LCAxODAsIDg1XTtcbi8qKlxuICogTWF4aW11bSBzYWZlIHZhbHVlIGluIHkgZGlyZWN0aW9uXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBNQVhfU0FGRV9ZID0gUkFESVVTICogTWF0aC5sb2coTWF0aC50YW4oTWF0aC5QSSAvIDIpKTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJvamVjdGlvbiBvYmplY3QgZm9yIHdlYi9zcGhlcmljYWwgTWVyY2F0b3IgKEVQU0c6Mzg1NykuXG4gKi9cblxudmFyIEVQU0czODU3UHJvamVjdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhFUFNHMzg1N1Byb2plY3Rpb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29kZSBDb2RlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEVQU0czODU3UHJvamVjdGlvbihjb2RlKSB7XG4gICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGNvZGU6IGNvZGUsXG4gICAgICB1bml0czogVW5pdHMuTUVURVJTLFxuICAgICAgZXh0ZW50OiBFWFRFTlQsXG4gICAgICBnbG9iYWw6IHRydWUsXG4gICAgICB3b3JsZEV4dGVudDogV09STERfRVhURU5ULFxuICAgICAgZ2V0UG9pbnRSZXNvbHV0aW9uOiBmdW5jdGlvbiBnZXRQb2ludFJlc29sdXRpb24ocmVzb2x1dGlvbiwgcG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdXRpb24gLyBjb3NoKHBvaW50WzFdIC8gUkFESVVTKTtcbiAgICAgIH1cbiAgICB9KSB8fCB0aGlzO1xuICB9XG5cbiAgcmV0dXJuIEVQU0czODU3UHJvamVjdGlvbjtcbn0oUHJvamVjdGlvbik7XG4vKipcbiAqIFByb2plY3Rpb25zIGVxdWFsIHRvIEVQU0c6Mzg1Ny5cbiAqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdD59XG4gKi9cblxuXG5leHBvcnQgdmFyIFBST0pFQ1RJT05TID0gW25ldyBFUFNHMzg1N1Byb2plY3Rpb24oJ0VQU0c6Mzg1NycpLCBuZXcgRVBTRzM4NTdQcm9qZWN0aW9uKCdFUFNHOjEwMjEwMCcpLCBuZXcgRVBTRzM4NTdQcm9qZWN0aW9uKCdFUFNHOjEwMjExMycpLCBuZXcgRVBTRzM4NTdQcm9qZWN0aW9uKCdFUFNHOjkwMDkxMycpLCBuZXcgRVBTRzM4NTdQcm9qZWN0aW9uKCdodHRwOi8vd3d3Lm9wZW5naXMubmV0L2dtbC9zcnMvZXBzZy54bWwjMzg1NycpXTtcbi8qKlxuICogVHJhbnNmb3JtYXRpb24gZnJvbSBFUFNHOjQzMjYgdG8gRVBTRzozODU3LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gaW5wdXQgSW5wdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24gKGRlZmF1bHQgaXMgYDJgKS5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUVQU0c0MzI2KGlucHV0LCBvcHRfb3V0cHV0LCBvcHRfZGltZW5zaW9uKSB7XG4gIHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gIHZhciBkaW1lbnNpb24gPSBvcHRfZGltZW5zaW9uID4gMSA/IG9wdF9kaW1lbnNpb24gOiAyO1xuICB2YXIgb3V0cHV0ID0gb3B0X291dHB1dDtcblxuICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoZGltZW5zaW9uID4gMikge1xuICAgICAgLy8gcHJlc2VydmUgdmFsdWVzIGJleW9uZCBzZWNvbmQgZGltZW5zaW9uXG4gICAgICBvdXRwdXQgPSBpbnB1dC5zbGljZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBkaW1lbnNpb24pIHtcbiAgICBvdXRwdXRbaV0gPSBIQUxGX1NJWkUgKiBpbnB1dFtpXSAvIDE4MDtcbiAgICB2YXIgeSA9IFJBRElVUyAqIE1hdGgubG9nKE1hdGgudGFuKE1hdGguUEkgKiAoK2lucHV0W2kgKyAxXSArIDkwKSAvIDM2MCkpO1xuXG4gICAgaWYgKHkgPiBNQVhfU0FGRV9ZKSB7XG4gICAgICB5ID0gTUFYX1NBRkVfWTtcbiAgICB9IGVsc2UgaWYgKHkgPCAtTUFYX1NBRkVfWSkge1xuICAgICAgeSA9IC1NQVhfU0FGRV9ZO1xuICAgIH1cblxuICAgIG91dHB1dFtpICsgMV0gPSB5O1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cbi8qKlxuICogVHJhbnNmb3JtYXRpb24gZnJvbSBFUFNHOjM4NTcgdG8gRVBTRzo0MzI2LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gaW5wdXQgSW5wdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24gKGRlZmF1bHQgaXMgYDJgKS5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9FUFNHNDMyNihpbnB1dCwgb3B0X291dHB1dCwgb3B0X2RpbWVuc2lvbikge1xuICB2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICB2YXIgZGltZW5zaW9uID0gb3B0X2RpbWVuc2lvbiA+IDEgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgdmFyIG91dHB1dCA9IG9wdF9vdXRwdXQ7XG5cbiAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGRpbWVuc2lvbiA+IDIpIHtcbiAgICAgIC8vIHByZXNlcnZlIHZhbHVlcyBiZXlvbmQgc2Vjb25kIGRpbWVuc2lvblxuICAgICAgb3V0cHV0ID0gaW5wdXQuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0ID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gZGltZW5zaW9uKSB7XG4gICAgb3V0cHV0W2ldID0gMTgwICogaW5wdXRbaV0gLyBIQUxGX1NJWkU7XG4gICAgb3V0cHV0W2kgKyAxXSA9IDM2MCAqIE1hdGguYXRhbihNYXRoLmV4cChpbnB1dFtpICsgMV0gLyBSQURJVVMpKSAvIE1hdGguUEkgLSA5MDtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL2Vwc2c0MzI2XG4gKi9cblxuXG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL1Byb2plY3Rpb24uanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4vVW5pdHMuanMnO1xuLyoqXG4gKiBTZW1pLW1ham9yIHJhZGl1cyBvZiB0aGUgV0dTODQgZWxsaXBzb2lkLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIFJBRElVUyA9IDYzNzgxMzc7XG4vKipcbiAqIEV4dGVudCBvZiB0aGUgRVBTRzo0MzI2IHByb2plY3Rpb24gd2hpY2ggaXMgdGhlIHdob2xlIHdvcmxkLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gKi9cblxuZXhwb3J0IHZhciBFWFRFTlQgPSBbLTE4MCwgLTkwLCAxODAsIDkwXTtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgTUVURVJTX1BFUl9VTklUID0gTWF0aC5QSSAqIFJBRElVUyAvIDE4MDtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJvamVjdGlvbiBvYmplY3QgZm9yIFdHUzg0IGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMgKEVQU0c6NDMyNikuXG4gKlxuICogTm90ZSB0aGF0IE9wZW5MYXllcnMgZG9lcyBub3Qgc3RyaWN0bHkgY29tcGx5IHdpdGggdGhlIEVQU0cgZGVmaW5pdGlvbi5cbiAqIFRoZSBFUFNHIHJlZ2lzdHJ5IGRlZmluZXMgNDMyNiBhcyBhIENSUyBmb3IgTGF0aXR1ZGUsTG9uZ2l0dWRlICh5LHgpLlxuICogT3BlbkxheWVycyB0cmVhdHMgRVBTRzo0MzI2IGFzIGEgcHNldWRvLXByb2plY3Rpb24sIHdpdGggeCx5IGNvb3JkaW5hdGVzLlxuICovXG5cbnZhciBFUFNHNDMyNlByb2plY3Rpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoRVBTRzQzMjZQcm9qZWN0aW9uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgQ29kZS5cbiAgICogQHBhcmFtIHtzdHJpbmc9fSBvcHRfYXhpc09yaWVudGF0aW9uIEF4aXMgb3JpZW50YXRpb24uXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRVBTRzQzMjZQcm9qZWN0aW9uKGNvZGUsIG9wdF9heGlzT3JpZW50YXRpb24pIHtcbiAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgY29kZTogY29kZSxcbiAgICAgIHVuaXRzOiBVbml0cy5ERUdSRUVTLFxuICAgICAgZXh0ZW50OiBFWFRFTlQsXG4gICAgICBheGlzT3JpZW50YXRpb246IG9wdF9heGlzT3JpZW50YXRpb24sXG4gICAgICBnbG9iYWw6IHRydWUsXG4gICAgICBtZXRlcnNQZXJVbml0OiBNRVRFUlNfUEVSX1VOSVQsXG4gICAgICB3b3JsZEV4dGVudDogRVhURU5UXG4gICAgfSkgfHwgdGhpcztcbiAgfVxuXG4gIHJldHVybiBFUFNHNDMyNlByb2plY3Rpb247XG59KFByb2plY3Rpb24pO1xuLyoqXG4gKiBQcm9qZWN0aW9ucyBlcXVhbCB0byBFUFNHOjQzMjYuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICovXG5cblxuZXhwb3J0IHZhciBQUk9KRUNUSU9OUyA9IFtuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCdDUlM6ODQnKSwgbmV3IEVQU0c0MzI2UHJvamVjdGlvbignRVBTRzo0MzI2JywgJ25ldScpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCd1cm46b2djOmRlZjpjcnM6T0dDOjEuMzpDUlM4NCcpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCd1cm46b2djOmRlZjpjcnM6T0dDOjI6ODQnKSwgbmV3IEVQU0c0MzI2UHJvamVjdGlvbignaHR0cDovL3d3dy5vcGVuZ2lzLm5ldC9nbWwvc3JzL2Vwc2cueG1sIzQzMjYnLCAnbmV1JyldOyIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL3Byb2plY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICovXG52YXIgY2FjaGUgPSB7fTtcbi8qKlxuICogQ2xlYXIgdGhlIHByb2plY3Rpb25zIGNhY2hlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhcigpIHtcbiAgY2FjaGUgPSB7fTtcbn1cbi8qKlxuICogR2V0IGEgY2FjaGVkIHByb2plY3Rpb24gYnkgY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIFRoZSBjb2RlIGZvciB0aGUgcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBUaGUgcHJvamVjdGlvbiAoaWYgY2FjaGVkKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0KGNvZGUpIHtcbiAgcmV0dXJuIGNhY2hlW2NvZGVdIHx8IGNhY2hlW2NvZGUucmVwbGFjZSgvdXJuOih4LSk/b2djOmRlZjpjcnM6RVBTRzooLio6KT8oXFx3KykkLywgJ0VQU0c6JDMnKV0gfHwgbnVsbDtcbn1cbi8qKlxuICogQWRkIGEgcHJvamVjdGlvbiB0byB0aGUgY2FjaGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29kZSBUaGUgcHJvamVjdGlvbiBjb2RlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBUaGUgcHJvamVjdGlvbiB0byBjYWNoZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKGNvZGUsIHByb2plY3Rpb24pIHtcbiAgY2FjaGVbY29kZV0gPSBwcm9qZWN0aW9uO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL3RyYW5zZm9ybXNcbiAqL1xuaW1wb3J0IHsgaXNFbXB0eSB9IGZyb20gJy4uL29iai5qcyc7XG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIE9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb24+Pn1cbiAqL1xuXG52YXIgdHJhbnNmb3JtcyA9IHt9O1xuLyoqXG4gKiBDbGVhciB0aGUgdHJhbnNmb3JtIGNhY2hlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhcigpIHtcbiAgdHJhbnNmb3JtcyA9IHt9O1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgYSBjb252ZXJzaW9uIGZ1bmN0aW9uIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgZnJvbSB0aGUgc291cmNlXG4gKiBwcm9qZWN0aW9uIHRvIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHNvdXJjZSBTb3VyY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQoc291cmNlLCBkZXN0aW5hdGlvbiwgdHJhbnNmb3JtRm4pIHtcbiAgdmFyIHNvdXJjZUNvZGUgPSBzb3VyY2UuZ2V0Q29kZSgpO1xuICB2YXIgZGVzdGluYXRpb25Db2RlID0gZGVzdGluYXRpb24uZ2V0Q29kZSgpO1xuXG4gIGlmICghKHNvdXJjZUNvZGUgaW4gdHJhbnNmb3JtcykpIHtcbiAgICB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdID0ge307XG4gIH1cblxuICB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdW2Rlc3RpbmF0aW9uQ29kZV0gPSB0cmFuc2Zvcm1Gbjtcbn1cbi8qKlxuICogVW5yZWdpc3RlcnMgdGhlIGNvbnZlcnNpb24gZnVuY3Rpb24gdG8gY29udmVydCBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2VcbiAqIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24uICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGNsZWFuIHVwXG4gKiBjYWNoZWQgdHJhbnNmb3JtcyBkdXJpbmcgdGVzdGluZy5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2UgU291cmNlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVGhlIHVucmVnaXN0ZXJlZCB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZShzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciBzb3VyY2VDb2RlID0gc291cmNlLmdldENvZGUoKTtcbiAgdmFyIGRlc3RpbmF0aW9uQ29kZSA9IGRlc3RpbmF0aW9uLmdldENvZGUoKTtcbiAgdmFyIHRyYW5zZm9ybSA9IHRyYW5zZm9ybXNbc291cmNlQ29kZV1bZGVzdGluYXRpb25Db2RlXTtcbiAgZGVsZXRlIHRyYW5zZm9ybXNbc291cmNlQ29kZV1bZGVzdGluYXRpb25Db2RlXTtcblxuICBpZiAoaXNFbXB0eSh0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdKSkge1xuICAgIGRlbGV0ZSB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybTtcbn1cbi8qKlxuICogR2V0IGEgdHJhbnNmb3JtIGdpdmVuIGEgc291cmNlIGNvZGUgYW5kIGEgZGVzdGluYXRpb24gY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VDb2RlIFRoZSBjb2RlIGZvciB0aGUgc291cmNlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzdGluYXRpb25Db2RlIFRoZSBjb2RlIGZvciB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb258dW5kZWZpbmVkfSBUaGUgdHJhbnNmb3JtIGZ1bmN0aW9uIChpZiBmb3VuZCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldChzb3VyY2VDb2RlLCBkZXN0aW5hdGlvbkNvZGUpIHtcbiAgdmFyIHRyYW5zZm9ybTtcblxuICBpZiAoc291cmNlQ29kZSBpbiB0cmFuc2Zvcm1zICYmIGRlc3RpbmF0aW9uQ29kZSBpbiB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdKSB7XG4gICAgdHJhbnNmb3JtID0gdHJhbnNmb3Jtc1tzb3VyY2VDb2RlXVtkZXN0aW5hdGlvbkNvZGVdO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvc3BoZXJlXG4gKi9cbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgeyB0b0RlZ3JlZXMsIHRvUmFkaWFucyB9IGZyb20gJy4vbWF0aC5qcyc7XG4vKipcbiAqIE9iamVjdCBsaXRlcmFsIHdpdGggb3B0aW9ucyBmb3IgdGhlIHtAbGluayBnZXRMZW5ndGh9IG9yIHtAbGluayBnZXRBcmVhfVxuICogZnVuY3Rpb25zLlxuICogQHR5cGVkZWYge09iamVjdH0gU3BoZXJlTWV0cmljT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uPSdFUFNHOjM4NTcnXVxuICogUHJvamVjdGlvbiBvZiB0aGUgIGdlb21ldHJ5LiAgQnkgZGVmYXVsdCwgdGhlIGdlb21ldHJ5IGlzIGFzc3VtZWQgdG8gYmUgaW5cbiAqIFdlYiBNZXJjYXRvci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmFkaXVzPTYzNzEwMDguOF0gU3BoZXJlIHJhZGl1cy4gIEJ5IGRlZmF1bHQsIHRoZVxuICogW21lYW4gRWFydGggcmFkaXVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FYXJ0aF9yYWRpdXMjTWVhbl9yYWRpdXMpXG4gKiBmb3IgdGhlIFdHUzg0IGVsbGlwc29pZCBpcyB1c2VkLlxuICovXG5cbi8qKlxuICogVGhlIG1lYW4gRWFydGggcmFkaXVzICgxLzMgKiAoMmEgKyBiKSkgZm9yIHRoZSBXR1M4NCBlbGxpcHNvaWQuXG4gKiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FYXJ0aF9yYWRpdXMjTWVhbl9yYWRpdXNcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBERUZBVUxUX1JBRElVUyA9IDYzNzEwMDguODtcbi8qKlxuICogR2V0IHRoZSBncmVhdCBjaXJjbGUgZGlzdGFuY2UgKGluIG1ldGVycykgYmV0d2VlbiB0d28gZ2VvZ3JhcGhpYyBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IGMxIFN0YXJ0aW5nIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge0FycmF5fSBjMiBFbmRpbmcgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3JhZGl1cyBUaGUgc3BoZXJlIHJhZGl1cyB0byB1c2UuICBEZWZhdWx0cyB0byB0aGUgRWFydGgnc1xuICogICAgIG1lYW4gcmFkaXVzIHVzaW5nIHRoZSBXR1M4NCBlbGxpcHNvaWQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBncmVhdCBjaXJjbGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnRzIChpbiBtZXRlcnMpLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0YW5jZShjMSwgYzIsIG9wdF9yYWRpdXMpIHtcbiAgdmFyIHJhZGl1cyA9IG9wdF9yYWRpdXMgfHwgREVGQVVMVF9SQURJVVM7XG4gIHZhciBsYXQxID0gdG9SYWRpYW5zKGMxWzFdKTtcbiAgdmFyIGxhdDIgPSB0b1JhZGlhbnMoYzJbMV0pO1xuICB2YXIgZGVsdGFMYXRCeTIgPSAobGF0MiAtIGxhdDEpIC8gMjtcbiAgdmFyIGRlbHRhTG9uQnkyID0gdG9SYWRpYW5zKGMyWzBdIC0gYzFbMF0pIC8gMjtcbiAgdmFyIGEgPSBNYXRoLnNpbihkZWx0YUxhdEJ5MikgKiBNYXRoLnNpbihkZWx0YUxhdEJ5MikgKyBNYXRoLnNpbihkZWx0YUxvbkJ5MikgKiBNYXRoLnNpbihkZWx0YUxvbkJ5MikgKiBNYXRoLmNvcyhsYXQxKSAqIE1hdGguY29zKGxhdDIpO1xuICByZXR1cm4gMiAqIHJhZGl1cyAqIE1hdGguYXRhbjIoTWF0aC5zcXJ0KGEpLCBNYXRoLnNxcnQoMSAtIGEpKTtcbn1cbi8qKlxuICogR2V0IHRoZSBjdW11bGF0aXZlIGdyZWF0IGNpcmNsZSBsZW5ndGggb2YgbGluZXN0cmluZyBjb29yZGluYXRlcyAoZ2VvZ3JhcGhpYykuXG4gKiBAcGFyYW0ge0FycmF5fSBjb29yZGluYXRlcyBMaW5lc3RyaW5nIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHJhZGl1cyBUaGUgc3BoZXJlIHJhZGl1cyB0byB1c2UuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBsZW5ndGggKGluIG1ldGVycykuXG4gKi9cblxuZnVuY3Rpb24gZ2V0TGVuZ3RoSW50ZXJuYWwoY29vcmRpbmF0ZXMsIHJhZGl1cykge1xuICB2YXIgbGVuZ3RoID0gMDtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBjb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaSAtIDE7ICsraSkge1xuICAgIGxlbmd0aCArPSBnZXREaXN0YW5jZShjb29yZGluYXRlc1tpXSwgY29vcmRpbmF0ZXNbaSArIDFdLCByYWRpdXMpO1xuICB9XG5cbiAgcmV0dXJuIGxlbmd0aDtcbn1cbi8qKlxuICogR2V0IHRoZSBzcGhlcmljYWwgbGVuZ3RoIG9mIGEgZ2VvbWV0cnkuICBUaGlzIGxlbmd0aCBpcyB0aGUgc3VtIG9mIHRoZVxuICogZ3JlYXQgY2lyY2xlIGRpc3RhbmNlcyBiZXR3ZWVuIGNvb3JkaW5hdGVzLiAgRm9yIHBvbHlnb25zLCB0aGUgbGVuZ3RoIGlzXG4gKiB0aGUgc3VtIG9mIGFsbCByaW5ncy4gIEZvciBwb2ludHMsIHRoZSBsZW5ndGggaXMgemVyby4gIEZvciBtdWx0aS1wYXJ0XG4gKiBnZW9tZXRyaWVzLCB0aGUgbGVuZ3RoIGlzIHRoZSBzdW0gb2YgdGhlIGxlbmd0aCBvZiBlYWNoIHBhcnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBBIGdlb21ldHJ5LlxuICogQHBhcmFtIHtTcGhlcmVNZXRyaWNPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucyBmb3IgdGhlXG4gKiBsZW5ndGggY2FsY3VsYXRpb24uICBCeSBkZWZhdWx0LCBnZW9tZXRyaWVzIGFyZSBhc3N1bWVkIHRvIGJlIGluICdFUFNHOjM4NTcnLlxuICogWW91IGNhbiBjaGFuZ2UgdGhpcyBieSBwcm92aWRpbmcgYSBgcHJvamVjdGlvbmAgb3B0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgc3BoZXJpY2FsIGxlbmd0aCAoaW4gbWV0ZXJzKS5cbiAqIEBhcGlcbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMZW5ndGgoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gIHZhciByYWRpdXMgPSBvcHRpb25zLnJhZGl1cyB8fCBERUZBVUxUX1JBRElVUztcbiAgdmFyIHByb2plY3Rpb24gPSBvcHRpb25zLnByb2plY3Rpb24gfHwgJ0VQU0c6Mzg1Nyc7XG4gIHZhciB0eXBlID0gZ2VvbWV0cnkuZ2V0VHlwZSgpO1xuXG4gIGlmICh0eXBlICE9PSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTikge1xuICAgIGdlb21ldHJ5ID0gZ2VvbWV0cnkuY2xvbmUoKS50cmFuc2Zvcm0ocHJvamVjdGlvbiwgJ0VQU0c6NDMyNicpO1xuICB9XG5cbiAgdmFyIGxlbmd0aCA9IDA7XG4gIHZhciBjb29yZGluYXRlcywgY29vcmRzLCBpLCBpaSwgaiwgamo7XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9JTlQ6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ6XG4gICAgICB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkc6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORUFSX1JJTkc6XG4gICAgICB7XG4gICAgICAgIGNvb3JkaW5hdGVzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkuZ2V0Q29vcmRpbmF0ZXMoKTtcbiAgICAgICAgbGVuZ3RoID0gZ2V0TGVuZ3RoSW50ZXJuYWwoY29vcmRpbmF0ZXMsIHJhZGl1cyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkc6XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9MWUdPTjpcbiAgICAgIHtcbiAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGxlbmd0aCArPSBnZXRMZW5ndGhJbnRlcm5hbChjb29yZGluYXRlc1tpXSwgcmFkaXVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTjpcbiAgICAgIHtcbiAgICAgICAgY29vcmRpbmF0ZXMgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGNvb3JkcyA9IGNvb3JkaW5hdGVzW2ldO1xuXG4gICAgICAgICAgZm9yIChqID0gMCwgamogPSBjb29yZHMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgICAgbGVuZ3RoICs9IGdldExlbmd0aEludGVybmFsKGNvb3Jkc1tqXSwgcmFkaXVzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT046XG4gICAgICB7XG4gICAgICAgIHZhciBnZW9tZXRyaWVzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldEdlb21ldHJpZXMoKTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGxlbmd0aCArPSBnZXRMZW5ndGgoZ2VvbWV0cmllc1tpXSwgb3B0X29wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBkZWZhdWx0OlxuICAgICAge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGdlb21ldHJ5IHR5cGU6ICcgKyB0eXBlKTtcbiAgICAgIH1cbiAgfVxuXG4gIHJldHVybiBsZW5ndGg7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIHNwaGVyaWNhbCBhcmVhIGZvciBhIGxpc3Qgb2YgY29vcmRpbmF0ZXMuXG4gKlxuICogW1JlZmVyZW5jZV0oaHR0cHM6Ly90cnMtbmV3LmpwbC5uYXNhLmdvdi9oYW5kbGUvMjAxNC80MDQwOSlcbiAqIFJvYmVydC4gRy4gQ2hhbWJlcmxhaW4gYW5kIFdpbGxpYW0gSC4gRHVxdWV0dGUsIFwiU29tZSBBbGdvcml0aG1zIGZvclxuICogUG9seWdvbnMgb24gYSBTcGhlcmVcIiwgSlBMIFB1YmxpY2F0aW9uIDA3LTAzLCBKZXQgUHJvcHVsc2lvblxuICogTGFib3JhdG9yeSwgUGFzYWRlbmEsIENBLCBKdW5lIDIwMDdcbiAqXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gY29vcmRpbmF0ZXMgTGlzdCBvZiBjb29yZGluYXRlcyBvZiBhIGxpbmVhclxuICogcmluZy4gSWYgdGhlIHJpbmcgaXMgb3JpZW50ZWQgY2xvY2t3aXNlLCB0aGUgYXJlYSB3aWxsIGJlIHBvc2l0aXZlLFxuICogb3RoZXJ3aXNlIGl0IHdpbGwgYmUgbmVnYXRpdmUuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIFRoZSBzcGhlcmUgcmFkaXVzLlxuICogQHJldHVybiB7bnVtYmVyfSBBcmVhIChpbiBzcXVhcmUgbWV0ZXJzKS5cbiAqL1xuXG5mdW5jdGlvbiBnZXRBcmVhSW50ZXJuYWwoY29vcmRpbmF0ZXMsIHJhZGl1cykge1xuICB2YXIgYXJlYSA9IDA7XG4gIHZhciBsZW4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gIHZhciB4MSA9IGNvb3JkaW5hdGVzW2xlbiAtIDFdWzBdO1xuICB2YXIgeTEgPSBjb29yZGluYXRlc1tsZW4gLSAxXVsxXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIHgyID0gY29vcmRpbmF0ZXNbaV1bMF07XG4gICAgdmFyIHkyID0gY29vcmRpbmF0ZXNbaV1bMV07XG4gICAgYXJlYSArPSB0b1JhZGlhbnMoeDIgLSB4MSkgKiAoMiArIE1hdGguc2luKHRvUmFkaWFucyh5MSkpICsgTWF0aC5zaW4odG9SYWRpYW5zKHkyKSkpO1xuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiBhcmVhICogcmFkaXVzICogcmFkaXVzIC8gMi4wO1xufVxuLyoqXG4gKiBHZXQgdGhlIHNwaGVyaWNhbCBhcmVhIG9mIGEgZ2VvbWV0cnkuICBUaGlzIGlzIHRoZSBhcmVhIChpbiBtZXRlcnMpIGFzc3VtaW5nXG4gKiB0aGF0IHBvbHlnb24gZWRnZXMgYXJlIHNlZ21lbnRzIG9mIGdyZWF0IGNpcmNsZXMgb24gYSBzcGhlcmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBBIGdlb21ldHJ5LlxuICogQHBhcmFtIHtTcGhlcmVNZXRyaWNPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIGFyZWFcbiAqICAgICBjYWxjdWxhdGlvbi4gIEJ5IGRlZmF1bHQsIGdlb21ldHJpZXMgYXJlIGFzc3VtZWQgdG8gYmUgaW4gJ0VQU0c6Mzg1NycuXG4gKiAgICAgWW91IGNhbiBjaGFuZ2UgdGhpcyBieSBwcm92aWRpbmcgYSBgcHJvamVjdGlvbmAgb3B0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBUaGUgc3BoZXJpY2FsIGFyZWEgKGluIHNxdWFyZSBtZXRlcnMpLlxuICogQGFwaVxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFyZWEoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gIHZhciByYWRpdXMgPSBvcHRpb25zLnJhZGl1cyB8fCBERUZBVUxUX1JBRElVUztcbiAgdmFyIHByb2plY3Rpb24gPSBvcHRpb25zLnByb2plY3Rpb24gfHwgJ0VQU0c6Mzg1Nyc7XG4gIHZhciB0eXBlID0gZ2VvbWV0cnkuZ2V0VHlwZSgpO1xuXG4gIGlmICh0eXBlICE9PSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTikge1xuICAgIGdlb21ldHJ5ID0gZ2VvbWV0cnkuY2xvbmUoKS50cmFuc2Zvcm0ocHJvamVjdGlvbiwgJ0VQU0c6NDMyNicpO1xuICB9XG5cbiAgdmFyIGFyZWEgPSAwO1xuICB2YXIgY29vcmRpbmF0ZXMsIGNvb3JkcywgaSwgaWksIGosIGpqO1xuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgR2VvbWV0cnlUeXBlLlBPSU5UOlxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UOlxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HOlxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HOlxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLkxJTkVBUl9SSU5HOlxuICAgICAge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLlBPTFlHT046XG4gICAgICB7XG4gICAgICAgIGNvb3JkaW5hdGVzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpO1xuICAgICAgICBhcmVhID0gTWF0aC5hYnMoZ2V0QXJlYUludGVybmFsKGNvb3JkaW5hdGVzWzBdLCByYWRpdXMpKTtcblxuICAgICAgICBmb3IgKGkgPSAxLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgICBhcmVhIC09IE1hdGguYWJzKGdldEFyZWFJbnRlcm5hbChjb29yZGluYXRlc1tpXSwgcmFkaXVzKSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT046XG4gICAgICB7XG4gICAgICAgIGNvb3JkaW5hdGVzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkuZ2V0Q29vcmRpbmF0ZXMoKTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgICBjb29yZHMgPSBjb29yZGluYXRlc1tpXTtcbiAgICAgICAgICBhcmVhICs9IE1hdGguYWJzKGdldEFyZWFJbnRlcm5hbChjb29yZHNbMF0sIHJhZGl1cykpO1xuXG4gICAgICAgICAgZm9yIChqID0gMSwgamogPSBjb29yZHMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgICAgYXJlYSAtPSBNYXRoLmFicyhnZXRBcmVhSW50ZXJuYWwoY29vcmRzW2pdLCByYWRpdXMpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT046XG4gICAgICB7XG4gICAgICAgIHZhciBnZW9tZXRyaWVzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5LmdldEdlb21ldHJpZXMoKTtcblxuICAgICAgICBmb3IgKGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGFyZWEgKz0gZ2V0QXJlYShnZW9tZXRyaWVzW2ldLCBvcHRfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgZ2VvbWV0cnkgdHlwZTogJyArIHR5cGUpO1xuICAgICAgfVxuICB9XG5cbiAgcmV0dXJuIGFyZWE7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGNvb3JkaW5hdGUgYXQgdGhlIGdpdmVuIGRpc3RhbmNlIGFuZCBiZWFyaW5nIGZyb20gYGMxYC5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjMSBUaGUgb3JpZ2luIHBvaW50IChgW2xvbiwgbGF0XWAgaW4gZGVncmVlcykuXG4gKiBAcGFyYW0ge251bWJlcn0gZGlzdGFuY2UgVGhlIGdyZWF0LWNpcmNsZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBvcmlnaW5cbiAqICAgICBwb2ludCBhbmQgdGhlIHRhcmdldCBwb2ludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiZWFyaW5nIFRoZSBiZWFyaW5nIChpbiByYWRpYW5zKS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3JhZGl1cyBUaGUgc3BoZXJlIHJhZGl1cyB0byB1c2UuICBEZWZhdWx0cyB0byB0aGUgRWFydGgnc1xuICogICAgIG1lYW4gcmFkaXVzIHVzaW5nIHRoZSBXR1M4NCBlbGxpcHNvaWQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVGhlIHRhcmdldCBwb2ludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gb2Zmc2V0KGMxLCBkaXN0YW5jZSwgYmVhcmluZywgb3B0X3JhZGl1cykge1xuICB2YXIgcmFkaXVzID0gb3B0X3JhZGl1cyB8fCBERUZBVUxUX1JBRElVUztcbiAgdmFyIGxhdDEgPSB0b1JhZGlhbnMoYzFbMV0pO1xuICB2YXIgbG9uMSA9IHRvUmFkaWFucyhjMVswXSk7XG4gIHZhciBkQnlSID0gZGlzdGFuY2UgLyByYWRpdXM7XG4gIHZhciBsYXQgPSBNYXRoLmFzaW4oTWF0aC5zaW4obGF0MSkgKiBNYXRoLmNvcyhkQnlSKSArIE1hdGguY29zKGxhdDEpICogTWF0aC5zaW4oZEJ5UikgKiBNYXRoLmNvcyhiZWFyaW5nKSk7XG4gIHZhciBsb24gPSBsb24xICsgTWF0aC5hdGFuMihNYXRoLnNpbihiZWFyaW5nKSAqIE1hdGguc2luKGRCeVIpICogTWF0aC5jb3MobGF0MSksIE1hdGguY29zKGRCeVIpIC0gTWF0aC5zaW4obGF0MSkgKiBNYXRoLnNpbihsYXQpKTtcbiAgcmV0dXJuIFt0b0RlZ3JlZXMobG9uKSwgdG9EZWdyZWVzKGxhdCldO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qXG4gKi9cblxuLyoqXG4gKiBUaGUgb2wvcHJvaiBtb2R1bGUgc3RvcmVzOlxuICogKiBhIGxpc3Qgb2Yge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259XG4gKiBvYmplY3RzLCBvbmUgZm9yIGVhY2ggcHJvamVjdGlvbiBzdXBwb3J0ZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gKiAqIGEgbGlzdCBvZiB0cmFuc2Zvcm0gZnVuY3Rpb25zIG5lZWRlZCB0byBjb252ZXJ0IGNvb3JkaW5hdGVzIGluIG9uZSBwcm9qZWN0aW9uXG4gKiBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIHN0YXRpYyBmdW5jdGlvbnMgYXJlIHRoZSBtZXRob2RzIHVzZWQgdG8gbWFpbnRhaW4gdGhlc2UuXG4gKiBFYWNoIHRyYW5zZm9ybSBmdW5jdGlvbiBjYW4gaGFuZGxlIG5vdCBvbmx5IHNpbXBsZSBjb29yZGluYXRlIHBhaXJzLCBidXQgYWxzb1xuICogbGFyZ2UgYXJyYXlzIG9mIGNvb3JkaW5hdGVzIHN1Y2ggYXMgdmVjdG9yIGdlb21ldHJpZXMuXG4gKlxuICogV2hlbiBsb2FkZWQsIHRoZSBsaWJyYXJ5IGFkZHMgcHJvamVjdGlvbiBvYmplY3RzIGZvciBFUFNHOjQzMjYgKFdHUzg0XG4gKiBnZW9ncmFwaGljIGNvb3JkaW5hdGVzKSBhbmQgRVBTRzozODU3IChXZWIgb3IgU3BoZXJpY2FsIE1lcmNhdG9yLCBhcyB1c2VkXG4gKiBmb3IgZXhhbXBsZSBieSBCaW5nIE1hcHMgb3IgT3BlblN0cmVldE1hcCksIHRvZ2V0aGVyIHdpdGggdGhlIHJlbGV2YW50XG4gKiB0cmFuc2Zvcm0gZnVuY3Rpb25zLlxuICpcbiAqIEFkZGl0aW9uYWwgdHJhbnNmb3JtcyBtYXkgYmUgYWRkZWQgYnkgdXNpbmcgdGhlIGh0dHA6Ly9wcm9qNGpzLm9yZy9cbiAqIGxpYnJhcnkgKHZlcnNpb24gMi4yIG9yIGxhdGVyKS4gWW91IGNhbiB1c2UgdGhlIGZ1bGwgYnVpbGQgc3VwcGxpZWQgYnlcbiAqIFByb2o0anMsIG9yIGNyZWF0ZSBhIGN1c3RvbSBidWlsZCB0byBzdXBwb3J0IHRob3NlIHByb2plY3Rpb25zIHlvdSBuZWVkOyBzZWVcbiAqIHRoZSBQcm9qNGpzIHdlYnNpdGUgZm9yIGhvdyB0byBkbyB0aGlzLiBZb3UgYWxzbyBuZWVkIHRoZSBQcm9qNGpzIGRlZmluaXRpb25zXG4gKiBmb3IgdGhlIHJlcXVpcmVkIHByb2plY3Rpb25zLiBUaGVzZSBkZWZpbml0aW9ucyBjYW4gYmUgb2J0YWluZWQgZnJvbVxuICogaHR0cHM6Ly9lcHNnLmlvLywgYW5kIGFyZSBhIEpTIGZ1bmN0aW9uLCBzbyBjYW4gYmUgbG9hZGVkIGluIGEgc2NyaXB0XG4gKiB0YWcgKGFzIGluIHRoZSBleGFtcGxlcykgb3IgcGFzdGVkIGludG8geW91ciBhcHBsaWNhdGlvbi5cbiAqXG4gKiBBZnRlciBhbGwgcmVxdWlyZWQgcHJvamVjdGlvbiBkZWZpbml0aW9ucyBhcmUgYWRkZWQgdG8gcHJvajQncyByZWdpc3RyeSAoYnlcbiAqIHVzaW5nIGBwcm9qNC5kZWZzKClgKSwgc2ltcGx5IGNhbGwgYHJlZ2lzdGVyKHByb2o0KWAgZnJvbSB0aGUgYG9sL3Byb2ovcHJvajRgXG4gKiBwYWNrYWdlLiBFeGlzdGluZyB0cmFuc2Zvcm1zIGFyZSBub3QgY2hhbmdlZCBieSB0aGlzIGZ1bmN0aW9uLiBTZWVcbiAqIGV4YW1wbGVzL3dtcy1pbWFnZS1jdXN0b20tcHJvaiBmb3IgYW4gZXhhbXBsZSBvZiB0aGlzLlxuICpcbiAqIEFkZGl0aW9uYWwgcHJvamVjdGlvbiBkZWZpbml0aW9ucyBjYW4gYmUgcmVnaXN0ZXJlZCB3aXRoIGBwcm9qNC5kZWZzKClgIGFueVxuICogdGltZS4gSnVzdCBtYWtlIHN1cmUgdG8gY2FsbCBgcmVnaXN0ZXIocHJvajQpYCBhZ2FpbjsgZm9yIGV4YW1wbGUsIHdpdGggdXNlci1zdXBwbGllZCBkYXRhIHdoZXJlIHlvdSBkb24ndFxuICoga25vdyBpbiBhZHZhbmNlIHdoYXQgcHJvamVjdGlvbnMgYXJlIG5lZWRlZCwgeW91IGNhbiBpbml0aWFsbHkgbG9hZCBtaW5pbWFsXG4gKiBzdXBwb3J0IGFuZCB0aGVuIGxvYWQgd2hpY2hldmVyIGFyZSByZXF1ZXN0ZWQuXG4gKlxuICogTm90ZSB0aGF0IFByb2o0anMgZG9lcyBub3Qgc3VwcG9ydCBwcm9qZWN0aW9uIGV4dGVudHMuIElmIHlvdSB3YW50IHRvIGFkZFxuICogb25lIGZvciBjcmVhdGluZyBkZWZhdWx0IHRpbGUgZ3JpZHMsIHlvdSBjYW4gYWRkIGl0IGFmdGVyIHRoZSBQcm9qZWN0aW9uXG4gKiBvYmplY3QgaGFzIGJlZW4gY3JlYXRlZCB3aXRoIGBzZXRFeHRlbnRgLCBmb3IgZXhhbXBsZSxcbiAqIGBnZXQoJ0VQU0c6MTIzNCcpLnNldEV4dGVudChleHRlbnQpYC5cbiAqXG4gKiBJbiBhZGRpdGlvbiB0byBQcm9qNGpzIHN1cHBvcnQsIGFueSB0cmFuc2Zvcm0gZnVuY3Rpb25zIGNhbiBiZSBhZGRlZCB3aXRoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+YWRkQ29vcmRpbmF0ZVRyYW5zZm9ybXN9LiBUbyB1c2UgdGhpcywgeW91IG11c3QgZmlyc3QgY3JlYXRlXG4gKiBhIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9ufSBvYmplY3QgZm9yIHRoZSBuZXcgcHJvamVjdGlvbiBhbmQgYWRkIGl0IHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvan5hZGRQcm9qZWN0aW9ufS4gWW91IGNhbiB0aGVuIGFkZCB0aGUgZm9yd2FyZCBhbmQgaW52ZXJzZVxuICogZnVuY3Rpb25zIHdpdGgge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmFkZENvb3JkaW5hdGVUcmFuc2Zvcm1zfS4gU2VlXG4gKiBleGFtcGxlcy93bXMtY3VzdG9tLXByb2ogZm9yIGFuIGV4YW1wbGUgb2YgdGhpcy5cbiAqXG4gKiBOb3RlIHRoYXQgaWYgbm8gdHJhbnNmb3JtcyBhcmUgbmVlZGVkIGFuZCB5b3Ugb25seSBuZWVkIHRvIGRlZmluZSB0aGVcbiAqIHByb2plY3Rpb24sIGp1c3QgYWRkIGEge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259IHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvan5hZGRQcm9qZWN0aW9ufS4gU2VlIGV4YW1wbGVzL3dtcy1uby1wcm9qIGZvciBhbiBleGFtcGxlIG9mXG4gKiB0aGlzLlxuICovXG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL3Byb2ovUHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgVW5pdHMsIHsgTUVURVJTX1BFUl9VTklUIH0gZnJvbSAnLi9wcm9qL1VuaXRzLmpzJztcbmltcG9ydCB7IFBST0pFQ1RJT05TIGFzIEVQU0czODU3X1BST0pFQ1RJT05TLCBmcm9tRVBTRzQzMjYsIHRvRVBTRzQzMjYgfSBmcm9tICcuL3Byb2ovZXBzZzM4NTcuanMnO1xuaW1wb3J0IHsgUFJPSkVDVElPTlMgYXMgRVBTRzQzMjZfUFJPSkVDVElPTlMgfSBmcm9tICcuL3Byb2ovZXBzZzQzMjYuanMnO1xuaW1wb3J0IHsgYWRkIGFzIGFkZFByb2osIGNsZWFyIGFzIGNsZWFyUHJvaiwgZ2V0IGFzIGdldFByb2ogfSBmcm9tICcuL3Byb2ovcHJvamVjdGlvbnMuanMnO1xuaW1wb3J0IHsgYWRkIGFzIGFkZFRyYW5zZm9ybUZ1bmMsIGNsZWFyIGFzIGNsZWFyVHJhbnNmb3JtRnVuY3MsIGdldCBhcyBnZXRUcmFuc2Zvcm1GdW5jIH0gZnJvbSAnLi9wcm9qL3RyYW5zZm9ybXMuanMnO1xuaW1wb3J0IHsgYXBwbHlUcmFuc2Zvcm0sIGdldFdpZHRoIH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY2xhbXAsIG1vZHVsbyB9IGZyb20gJy4vbWF0aC5qcyc7XG5pbXBvcnQgeyBnZXREaXN0YW5jZSB9IGZyb20gJy4vc3BoZXJlLmpzJztcbmltcG9ydCB7IGdldFdvcmxkc0F3YXkgfSBmcm9tICcuL2Nvb3JkaW5hdGUuanMnO1xuLyoqXG4gKiBBIHByb2plY3Rpb24gYXMge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259LCBTUlMgaWRlbnRpZmllclxuICogc3RyaW5nIG9yIHVuZGVmaW5lZC5cbiAqIEB0eXBlZGVmIHtQcm9qZWN0aW9ufHN0cmluZ3x1bmRlZmluZWR9IFByb2plY3Rpb25MaWtlXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBBIHRyYW5zZm9ybSBmdW5jdGlvbiBhY2NlcHRzIGFuIGFycmF5IG9mIGlucHV0IGNvb3JkaW5hdGUgdmFsdWVzLCBhbiBvcHRpb25hbFxuICogb3V0cHV0IGFycmF5LCBhbmQgYW4gb3B0aW9uYWwgZGltZW5zaW9uIChkZWZhdWx0IHNob3VsZCBiZSAyKS4gIFRoZSBmdW5jdGlvblxuICogdHJhbnNmb3JtcyB0aGUgaW5wdXQgY29vcmRpbmF0ZSB2YWx1ZXMsIHBvcHVsYXRlcyB0aGUgb3V0cHV0IGFycmF5LCBhbmRcbiAqIHJldHVybnMgdGhlIG91dHB1dCBhcnJheS5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oQXJyYXk8bnVtYmVyPiwgQXJyYXk8bnVtYmVyPj0sIG51bWJlcj0pOiBBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1GdW5jdGlvblxuICogQGFwaVxuICovXG5cbmV4cG9ydCB7IE1FVEVSU19QRVJfVU5JVCB9O1xuZXhwb3J0IHsgUHJvamVjdGlvbiB9O1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0IGNvb3JkaW5hdGUgYXJyYXkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPdXRwdXQgY29vcmRpbmF0ZSBhcnJheSAobmV3IGFycmF5LCBzYW1lIGNvb3JkaW5hdGVcbiAqICAgICB2YWx1ZXMpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZVRyYW5zZm9ybShpbnB1dCwgb3B0X291dHB1dCwgb3B0X2RpbWVuc2lvbikge1xuICB2YXIgb3V0cHV0O1xuXG4gIGlmIChvcHRfb3V0cHV0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBpbnB1dC5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBvcHRfb3V0cHV0W2ldID0gaW5wdXRbaV07XG4gICAgfVxuXG4gICAgb3V0cHV0ID0gb3B0X291dHB1dDtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBpbnB1dC5zbGljZSgpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBJbnB1dCBjb29yZGluYXRlIGFycmF5LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X291dHB1dCBPdXRwdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9kaW1lbnNpb24gRGltZW5zaW9uLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gSW5wdXQgY29vcmRpbmF0ZSBhcnJheSAoc2FtZSBhcnJheSBhcyBpbnB1dCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aXR5VHJhbnNmb3JtKGlucHV0LCBvcHRfb3V0cHV0LCBvcHRfZGltZW5zaW9uKSB7XG4gIGlmIChvcHRfb3V0cHV0ICE9PSB1bmRlZmluZWQgJiYgaW5wdXQgIT09IG9wdF9vdXRwdXQpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBpbnB1dC5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBvcHRfb3V0cHV0W2ldID0gaW5wdXRbaV07XG4gICAgfVxuXG4gICAgaW5wdXQgPSBvcHRfb3V0cHV0O1xuICB9XG5cbiAgcmV0dXJuIGlucHV0O1xufVxuLyoqXG4gKiBBZGQgYSBQcm9qZWN0aW9uIG9iamVjdCB0byB0aGUgbGlzdCBvZiBzdXBwb3J0ZWQgcHJvamVjdGlvbnMgdGhhdCBjYW4gYmVcbiAqIGxvb2tlZCB1cCBieSB0aGVpciBjb2RlLlxuICpcbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gcHJvamVjdGlvbiBQcm9qZWN0aW9uIGluc3RhbmNlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRQcm9qZWN0aW9uKHByb2plY3Rpb24pIHtcbiAgYWRkUHJvaihwcm9qZWN0aW9uLmdldENvZGUoKSwgcHJvamVjdGlvbik7XG4gIGFkZFRyYW5zZm9ybUZ1bmMocHJvamVjdGlvbiwgcHJvamVjdGlvbiwgY2xvbmVUcmFuc2Zvcm0pO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PFByb2plY3Rpb24+fSBwcm9qZWN0aW9ucyBQcm9qZWN0aW9ucy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkUHJvamVjdGlvbnMocHJvamVjdGlvbnMpIHtcbiAgcHJvamVjdGlvbnMuZm9yRWFjaChhZGRQcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogRmV0Y2hlcyBhIFByb2plY3Rpb24gb2JqZWN0IGZvciB0aGUgY29kZSBzcGVjaWZpZWQuXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gcHJvamVjdGlvbkxpa2UgRWl0aGVyIGEgY29kZSBzdHJpbmcgd2hpY2ggaXNcbiAqICAgICBhIGNvbWJpbmF0aW9uIG9mIGF1dGhvcml0eSBhbmQgaWRlbnRpZmllciBzdWNoIGFzIFwiRVBTRzo0MzI2XCIsIG9yIGFuXG4gKiAgICAgZXhpc3RpbmcgcHJvamVjdGlvbiBvYmplY3QsIG9yIHVuZGVmaW5lZC5cbiAqIEByZXR1cm4ge1Byb2plY3Rpb259IFByb2plY3Rpb24gb2JqZWN0LCBvciBudWxsIGlmIG5vdCBpbiBsaXN0LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXQocHJvamVjdGlvbkxpa2UpIHtcbiAgcmV0dXJuIHR5cGVvZiBwcm9qZWN0aW9uTGlrZSA9PT0gJ3N0cmluZycgPyBnZXRQcm9qKFxuICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgcHJvamVjdGlvbkxpa2UpIDpcbiAgLyoqIEB0eXBlIHtQcm9qZWN0aW9ufSAqL1xuICBwcm9qZWN0aW9uTGlrZSB8fCBudWxsO1xufVxuLyoqXG4gKiBHZXQgdGhlIHJlc29sdXRpb24gb2YgdGhlIHBvaW50IGluIGRlZ3JlZXMgb3IgZGlzdGFuY2UgdW5pdHMuXG4gKiBGb3IgcHJvamVjdGlvbnMgd2l0aCBkZWdyZWVzIGFzIHRoZSB1bml0IHRoaXMgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZVxuICogcHJvdmlkZWQgcmVzb2x1dGlvbi4gRm9yIG90aGVyIHByb2plY3Rpb25zIHRoZSBwb2ludCByZXNvbHV0aW9uIGlzXG4gKiBieSBkZWZhdWx0IGVzdGltYXRlZCBieSB0cmFuc2Zvcm1pbmcgdGhlICdwb2ludCcgcGl4ZWwgdG8gRVBTRzo0MzI2LFxuICogbWVhc3VyaW5nIGl0cyB3aWR0aCBhbmQgaGVpZ2h0IG9uIHRoZSBub3JtYWwgc3BoZXJlLFxuICogYW5kIHRha2luZyB0aGUgYXZlcmFnZSBvZiB0aGUgd2lkdGggYW5kIGhlaWdodC5cbiAqIEEgY3VzdG9tIGZ1bmN0aW9uIGNhbiBiZSBwcm92aWRlZCBmb3IgYSBzcGVjaWZpYyBwcm9qZWN0aW9uLCBlaXRoZXJcbiAqIGJ5IHNldHRpbmcgdGhlIGBnZXRQb2ludFJlc29sdXRpb25gIG9wdGlvbiBpbiB0aGVcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9uflByb2plY3Rpb259IGNvbnN0cnVjdG9yIG9yIGJ5IHVzaW5nXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn5Qcm9qZWN0aW9uI3NldEdldFBvaW50UmVzb2x1dGlvbn0gdG8gY2hhbmdlIGFuIGV4aXN0aW5nXG4gKiBwcm9qZWN0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHByb2plY3Rpb24gVGhlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBOb21pbmFsIHJlc29sdXRpb24gaW4gcHJvamVjdGlvbiB1bml0cy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHBvaW50IFBvaW50IHRvIGZpbmQgYWRqdXN0ZWQgcmVzb2x1dGlvbiBhdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1VuaXRzLmpzXCIpLmRlZmF1bHQ9fSBvcHRfdW5pdHMgVW5pdHMgdG8gZ2V0IHRoZSBwb2ludCByZXNvbHV0aW9uIGluLlxuICogRGVmYXVsdCBpcyB0aGUgcHJvamVjdGlvbidzIHVuaXRzLlxuICogQHJldHVybiB7bnVtYmVyfSBQb2ludCByZXNvbHV0aW9uLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb2ludFJlc29sdXRpb24ocHJvamVjdGlvbiwgcmVzb2x1dGlvbiwgcG9pbnQsIG9wdF91bml0cykge1xuICBwcm9qZWN0aW9uID0gZ2V0KHByb2plY3Rpb24pO1xuICB2YXIgcG9pbnRSZXNvbHV0aW9uO1xuICB2YXIgZ2V0dGVyID0gcHJvamVjdGlvbi5nZXRQb2ludFJlc29sdXRpb25GdW5jKCk7XG5cbiAgaWYgKGdldHRlcikge1xuICAgIHBvaW50UmVzb2x1dGlvbiA9IGdldHRlcihyZXNvbHV0aW9uLCBwb2ludCk7XG5cbiAgICBpZiAob3B0X3VuaXRzICYmIG9wdF91bml0cyAhPT0gcHJvamVjdGlvbi5nZXRVbml0cygpKSB7XG4gICAgICB2YXIgbWV0ZXJzUGVyVW5pdCA9IHByb2plY3Rpb24uZ2V0TWV0ZXJzUGVyVW5pdCgpO1xuXG4gICAgICBpZiAobWV0ZXJzUGVyVW5pdCkge1xuICAgICAgICBwb2ludFJlc29sdXRpb24gPSBwb2ludFJlc29sdXRpb24gKiBtZXRlcnNQZXJVbml0IC8gTUVURVJTX1BFUl9VTklUW29wdF91bml0c107XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciB1bml0cyA9IHByb2plY3Rpb24uZ2V0VW5pdHMoKTtcblxuICAgIGlmICh1bml0cyA9PSBVbml0cy5ERUdSRUVTICYmICFvcHRfdW5pdHMgfHwgb3B0X3VuaXRzID09IFVuaXRzLkRFR1JFRVMpIHtcbiAgICAgIHBvaW50UmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVzdGltYXRlIHBvaW50IHJlc29sdXRpb24gYnkgdHJhbnNmb3JtaW5nIHRoZSBjZW50ZXIgcGl4ZWwgdG8gRVBTRzo0MzI2LFxuICAgICAgLy8gbWVhc3VyaW5nIGl0cyB3aWR0aCBhbmQgaGVpZ2h0IG9uIHRoZSBub3JtYWwgc3BoZXJlLCBhbmQgdGFraW5nIHRoZVxuICAgICAgLy8gYXZlcmFnZSBvZiB0aGUgd2lkdGggYW5kIGhlaWdodC5cbiAgICAgIHZhciB0b0VQU0c0MzI2XzEgPSBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMocHJvamVjdGlvbiwgZ2V0KCdFUFNHOjQzMjYnKSk7XG5cbiAgICAgIGlmICh0b0VQU0c0MzI2XzEgPT09IGlkZW50aXR5VHJhbnNmb3JtICYmIHVuaXRzICE9PSBVbml0cy5ERUdSRUVTKSB7XG4gICAgICAgIC8vIG5vIHRyYW5zZm9ybSBpcyBhdmFpbGFibGVcbiAgICAgICAgcG9pbnRSZXNvbHV0aW9uID0gcmVzb2x1dGlvbiAqIHByb2plY3Rpb24uZ2V0TWV0ZXJzUGVyVW5pdCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHZlcnRpY2VzID0gW3BvaW50WzBdIC0gcmVzb2x1dGlvbiAvIDIsIHBvaW50WzFdLCBwb2ludFswXSArIHJlc29sdXRpb24gLyAyLCBwb2ludFsxXSwgcG9pbnRbMF0sIHBvaW50WzFdIC0gcmVzb2x1dGlvbiAvIDIsIHBvaW50WzBdLCBwb2ludFsxXSArIHJlc29sdXRpb24gLyAyXTtcbiAgICAgICAgdmVydGljZXMgPSB0b0VQU0c0MzI2XzEodmVydGljZXMsIHZlcnRpY2VzLCAyKTtcbiAgICAgICAgdmFyIHdpZHRoID0gZ2V0RGlzdGFuY2UodmVydGljZXMuc2xpY2UoMCwgMiksIHZlcnRpY2VzLnNsaWNlKDIsIDQpKTtcbiAgICAgICAgdmFyIGhlaWdodCA9IGdldERpc3RhbmNlKHZlcnRpY2VzLnNsaWNlKDQsIDYpLCB2ZXJ0aWNlcy5zbGljZSg2LCA4KSk7XG4gICAgICAgIHBvaW50UmVzb2x1dGlvbiA9ICh3aWR0aCArIGhlaWdodCkgLyAyO1xuICAgICAgfVxuXG4gICAgICB2YXIgbWV0ZXJzUGVyVW5pdCA9IG9wdF91bml0cyA/IE1FVEVSU19QRVJfVU5JVFtvcHRfdW5pdHNdIDogcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG5cbiAgICAgIGlmIChtZXRlcnNQZXJVbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcG9pbnRSZXNvbHV0aW9uIC89IG1ldGVyc1BlclVuaXQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBvaW50UmVzb2x1dGlvbjtcbn1cbi8qKlxuICogUmVnaXN0ZXJzIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9ucyB0aGF0IGRvbid0IGFsdGVyIGNvb3JkaW5hdGVzLiBUaG9zZSBhbGxvd1xuICogdG8gdHJhbnNmb3JtIGJldHdlZW4gcHJvamVjdGlvbnMgd2l0aCBlcXVhbCBtZWFuaW5nLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8UHJvamVjdGlvbj59IHByb2plY3Rpb25zIFByb2plY3Rpb25zLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRFcXVpdmFsZW50UHJvamVjdGlvbnMocHJvamVjdGlvbnMpIHtcbiAgYWRkUHJvamVjdGlvbnMocHJvamVjdGlvbnMpO1xuICBwcm9qZWN0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICBwcm9qZWN0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkZXN0aW5hdGlvbikge1xuICAgICAgaWYgKHNvdXJjZSAhPT0gZGVzdGluYXRpb24pIHtcbiAgICAgICAgYWRkVHJhbnNmb3JtRnVuYyhzb3VyY2UsIGRlc3RpbmF0aW9uLCBjbG9uZVRyYW5zZm9ybSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb25zIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgaW4gYW55IHByb2plY3Rpb25cbiAqIGluIHByb2plY3Rpb24xIHRvIGFueSBwcm9qZWN0aW9uIGluIHByb2plY3Rpb24yLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8UHJvamVjdGlvbj59IHByb2plY3Rpb25zMSBQcm9qZWN0aW9ucyB3aXRoIGVxdWFsXG4gKiAgICAgbWVhbmluZy5cbiAqIEBwYXJhbSB7QXJyYXk8UHJvamVjdGlvbj59IHByb2plY3Rpb25zMiBQcm9qZWN0aW9ucyB3aXRoIGVxdWFsXG4gKiAgICAgbWVhbmluZy5cbiAqIEBwYXJhbSB7VHJhbnNmb3JtRnVuY3Rpb259IGZvcndhcmRUcmFuc2Zvcm0gVHJhbnNmb3JtYXRpb24gZnJvbSBhbnlcbiAqICAgcHJvamVjdGlvbiBpbiBwcm9qZWN0aW9uMSB0byBhbnkgcHJvamVjdGlvbiBpbiBwcm9qZWN0aW9uMi5cbiAqIEBwYXJhbSB7VHJhbnNmb3JtRnVuY3Rpb259IGludmVyc2VUcmFuc2Zvcm0gVHJhbnNmb3JtIGZyb20gYW55IHByb2plY3Rpb25cbiAqICAgaW4gcHJvamVjdGlvbjIgdG8gYW55IHByb2plY3Rpb24gaW4gcHJvamVjdGlvbjEuLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRFcXVpdmFsZW50VHJhbnNmb3Jtcyhwcm9qZWN0aW9uczEsIHByb2plY3Rpb25zMiwgZm9yd2FyZFRyYW5zZm9ybSwgaW52ZXJzZVRyYW5zZm9ybSkge1xuICBwcm9qZWN0aW9uczEuZm9yRWFjaChmdW5jdGlvbiAocHJvamVjdGlvbjEpIHtcbiAgICBwcm9qZWN0aW9uczIuZm9yRWFjaChmdW5jdGlvbiAocHJvamVjdGlvbjIpIHtcbiAgICAgIGFkZFRyYW5zZm9ybUZ1bmMocHJvamVjdGlvbjEsIHByb2plY3Rpb24yLCBmb3J3YXJkVHJhbnNmb3JtKTtcbiAgICAgIGFkZFRyYW5zZm9ybUZ1bmMocHJvamVjdGlvbjIsIHByb2plY3Rpb24xLCBpbnZlcnNlVHJhbnNmb3JtKTtcbiAgICB9KTtcbiAgfSk7XG59XG4vKipcbiAqIENsZWFyIGFsbCBjYWNoZWQgcHJvamVjdGlvbnMgYW5kIHRyYW5zZm9ybXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQWxsUHJvamVjdGlvbnMoKSB7XG4gIGNsZWFyUHJvaigpO1xuICBjbGVhclRyYW5zZm9ybUZ1bmNzKCk7XG59XG4vKipcbiAqIEBwYXJhbSB7UHJvamVjdGlvbnxzdHJpbmd8dW5kZWZpbmVkfSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVmYXVsdENvZGUgRGVmYXVsdCBjb2RlLlxuICogQHJldHVybiB7UHJvamVjdGlvbn0gUHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUHJvamVjdGlvbihwcm9qZWN0aW9uLCBkZWZhdWx0Q29kZSkge1xuICBpZiAoIXByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gZ2V0KGRlZmF1bHRDb2RlKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgcHJvamVjdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZ2V0KHByb2plY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge1Byb2plY3Rpb259ICovXG4gICAgICBwcm9qZWN0aW9uXG4gICAgKTtcbiAgfVxufVxuLyoqXG4gKiBDcmVhdGVzIGEge0BsaW5rIG1vZHVsZTpvbC9wcm9qflRyYW5zZm9ybUZ1bmN0aW9ufSBmcm9tIGEgc2ltcGxlIDJEIGNvb3JkaW5hdGUgdHJhbnNmb3JtXG4gKiBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRUcmFuc2Zvcm0gQ29vcmRpbmF0ZVxuICogICAgIHRyYW5zZm9ybS5cbiAqIEByZXR1cm4ge1RyYW5zZm9ybUZ1bmN0aW9ufSBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRyYW5zZm9ybUZyb21Db29yZGluYXRlVHJhbnNmb3JtKGNvb3JkVHJhbnNmb3JtKSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBpbnB1dCBJbnB1dC5cbiAgICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dC5cbiAgICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9kaW1lbnNpb24gRGltZW5zaW9uLlxuICAgICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE91dHB1dC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoaW5wdXQsIG9wdF9vdXRwdXQsIG9wdF9kaW1lbnNpb24pIHtcbiAgICAgIHZhciBsZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgICB2YXIgZGltZW5zaW9uID0gb3B0X2RpbWVuc2lvbiAhPT0gdW5kZWZpbmVkID8gb3B0X2RpbWVuc2lvbiA6IDI7XG4gICAgICB2YXIgb3V0cHV0ID0gb3B0X291dHB1dCAhPT0gdW5kZWZpbmVkID8gb3B0X291dHB1dCA6IG5ldyBBcnJheShsZW5ndGgpO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBkaW1lbnNpb24pIHtcbiAgICAgICAgdmFyIHBvaW50ID0gY29vcmRUcmFuc2Zvcm0oW2lucHV0W2ldLCBpbnB1dFtpICsgMV1dKTtcbiAgICAgICAgb3V0cHV0W2ldID0gcG9pbnRbMF07XG4gICAgICAgIG91dHB1dFtpICsgMV0gPSBwb2ludFsxXTtcblxuICAgICAgICBmb3IgKHZhciBqID0gZGltZW5zaW9uIC0gMTsgaiA+PSAyOyAtLWopIHtcbiAgICAgICAgICBvdXRwdXRbaSArIGpdID0gaW5wdXRbaSArIGpdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfVxuICApO1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgY29vcmRpbmF0ZSB0cmFuc2Zvcm0gZnVuY3Rpb25zIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgYmV0d2VlbiB0aGVcbiAqIHNvdXJjZSBwcm9qZWN0aW9uIGFuZCB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIFRoZSBmb3J3YXJkIGFuZCBpbnZlcnNlIGZ1bmN0aW9ucyBjb252ZXJ0IGNvb3JkaW5hdGUgcGFpcnM7IHRoaXMgZnVuY3Rpb25cbiAqIGNvbnZlcnRzIHRoZXNlIGludG8gdGhlIGZ1bmN0aW9ucyB1c2VkIGludGVybmFsbHkgd2hpY2ggYWxzbyBoYW5kbGVcbiAqIGV4dGVudHMgYW5kIGNvb3JkaW5hdGUgYXJyYXlzLlxuICpcbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RpbmF0aW9uIERlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGZvcndhcmQgVGhlIGZvcndhcmQgdHJhbnNmb3JtXG4gKiAgICAgZnVuY3Rpb24gKHRoYXQgaXMsIGZyb20gdGhlIHNvdXJjZSBwcm9qZWN0aW9uIHRvIHRoZSBkZXN0aW5hdGlvblxuICogICAgIHByb2plY3Rpb24pIHRoYXQgdGFrZXMgYSB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0gYXMgYXJndW1lbnQgYW5kIHJldHVybnNcbiAqICAgICB0aGUgdHJhbnNmb3JtZWQge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGV9LlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBpbnZlcnNlIFRoZSBpbnZlcnNlIHRyYW5zZm9ybVxuICogICAgIGZ1bmN0aW9uICh0aGF0IGlzLCBmcm9tIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uIHRvIHRoZSBzb3VyY2VcbiAqICAgICBwcm9qZWN0aW9uKSB0aGF0IHRha2VzIGEge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGV9IGFzIGFyZ3VtZW50IGFuZCByZXR1cm5zXG4gKiAgICAgdGhlIHRyYW5zZm9ybWVkIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlfS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkQ29vcmRpbmF0ZVRyYW5zZm9ybXMoc291cmNlLCBkZXN0aW5hdGlvbiwgZm9yd2FyZCwgaW52ZXJzZSkge1xuICB2YXIgc291cmNlUHJvaiA9IGdldChzb3VyY2UpO1xuICB2YXIgZGVzdFByb2ogPSBnZXQoZGVzdGluYXRpb24pO1xuICBhZGRUcmFuc2Zvcm1GdW5jKHNvdXJjZVByb2osIGRlc3RQcm9qLCBjcmVhdGVUcmFuc2Zvcm1Gcm9tQ29vcmRpbmF0ZVRyYW5zZm9ybShmb3J3YXJkKSk7XG4gIGFkZFRyYW5zZm9ybUZ1bmMoZGVzdFByb2osIHNvdXJjZVByb2osIGNyZWF0ZVRyYW5zZm9ybUZyb21Db29yZGluYXRlVHJhbnNmb3JtKGludmVyc2UpKTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhIGNvb3JkaW5hdGUgZnJvbSBsb25naXR1ZGUvbGF0aXR1ZGUgdG8gYSBkaWZmZXJlbnQgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZSBhcyBsb25naXR1ZGUgYW5kIGxhdGl0dWRlLCBpLmUuXG4gKiAgICAgYW4gYXJyYXkgd2l0aCBsb25naXR1ZGUgYXMgMXN0IGFuZCBsYXRpdHVkZSBhcyAybmQgZWxlbWVudC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2U9fSBvcHRfcHJvamVjdGlvbiBUYXJnZXQgcHJvamVjdGlvbi4gVGhlXG4gKiAgICAgZGVmYXVsdCBpcyBXZWIgTWVyY2F0b3IsIGkuZS4gJ0VQU0c6Mzg1NycuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZSBwcm9qZWN0ZWQgdG8gdGhlIHRhcmdldCBwcm9qZWN0aW9uLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tTG9uTGF0KGNvb3JkaW5hdGUsIG9wdF9wcm9qZWN0aW9uKSB7XG4gIHJldHVybiB0cmFuc2Zvcm0oY29vcmRpbmF0ZSwgJ0VQU0c6NDMyNicsIG9wdF9wcm9qZWN0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRfcHJvamVjdGlvbiA6ICdFUFNHOjM4NTcnKTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhIGNvb3JkaW5hdGUgdG8gbG9uZ2l0dWRlL2xhdGl0dWRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBQcm9qZWN0ZWQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2U9fSBvcHRfcHJvamVjdGlvbiBQcm9qZWN0aW9uIG9mIHRoZSBjb29yZGluYXRlLlxuICogICAgIFRoZSBkZWZhdWx0IGlzIFdlYiBNZXJjYXRvciwgaS5lLiAnRVBTRzozODU3Jy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlIGFzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUsIGkuZS4gYW4gYXJyYXlcbiAqICAgICB3aXRoIGxvbmdpdHVkZSBhcyAxc3QgYW5kIGxhdGl0dWRlIGFzIDJuZCBlbGVtZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b0xvbkxhdChjb29yZGluYXRlLCBvcHRfcHJvamVjdGlvbikge1xuICB2YXIgbG9uTGF0ID0gdHJhbnNmb3JtKGNvb3JkaW5hdGUsIG9wdF9wcm9qZWN0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRfcHJvamVjdGlvbiA6ICdFUFNHOjM4NTcnLCAnRVBTRzo0MzI2Jyk7XG4gIHZhciBsb24gPSBsb25MYXRbMF07XG5cbiAgaWYgKGxvbiA8IC0xODAgfHwgbG9uID4gMTgwKSB7XG4gICAgbG9uTGF0WzBdID0gbW9kdWxvKGxvbiArIDE4MCwgMzYwKSAtIDE4MDtcbiAgfVxuXG4gIHJldHVybiBsb25MYXQ7XG59XG4vKipcbiAqIENoZWNrcyBpZiB0d28gcHJvamVjdGlvbnMgYXJlIHRoZSBzYW1lLCB0aGF0IGlzIGV2ZXJ5IGNvb3JkaW5hdGUgaW4gb25lXG4gKiBwcm9qZWN0aW9uIGRvZXMgcmVwcmVzZW50IHRoZSBzYW1lIGdlb2dyYXBoaWMgcG9pbnQgYXMgdGhlIHNhbWUgY29vcmRpbmF0ZSBpblxuICogdGhlIG90aGVyIHByb2plY3Rpb24uXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBwcm9qZWN0aW9uMSBQcm9qZWN0aW9uIDEuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHByb2plY3Rpb24yIFByb2plY3Rpb24gMi5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEVxdWl2YWxlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWl2YWxlbnQocHJvamVjdGlvbjEsIHByb2plY3Rpb24yKSB7XG4gIGlmIChwcm9qZWN0aW9uMSA9PT0gcHJvamVjdGlvbjIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBlcXVhbFVuaXRzID0gcHJvamVjdGlvbjEuZ2V0VW5pdHMoKSA9PT0gcHJvamVjdGlvbjIuZ2V0VW5pdHMoKTtcblxuICBpZiAocHJvamVjdGlvbjEuZ2V0Q29kZSgpID09PSBwcm9qZWN0aW9uMi5nZXRDb2RlKCkpIHtcbiAgICByZXR1cm4gZXF1YWxVbml0cztcbiAgfSBlbHNlIHtcbiAgICB2YXIgdHJhbnNmb3JtRnVuYyA9IGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyhwcm9qZWN0aW9uMSwgcHJvamVjdGlvbjIpO1xuICAgIHJldHVybiB0cmFuc2Zvcm1GdW5jID09PSBjbG9uZVRyYW5zZm9ybSAmJiBlcXVhbFVuaXRzO1xuICB9XG59XG4vKipcbiAqIFNlYXJjaGVzIGluIHRoZSBsaXN0IG9mIHRyYW5zZm9ybSBmdW5jdGlvbnMgZm9yIHRoZSBmdW5jdGlvbiBmb3IgY29udmVydGluZ1xuICogY29vcmRpbmF0ZXMgZnJvbSB0aGUgc291cmNlIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBzb3VyY2VQcm9qZWN0aW9uIFNvdXJjZSBQcm9qZWN0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gZGVzdGluYXRpb25Qcm9qZWN0aW9uIERlc3RpbmF0aW9uIFByb2plY3Rpb25cbiAqICAgICBvYmplY3QuXG4gKiBAcmV0dXJuIHtUcmFuc2Zvcm1GdW5jdGlvbn0gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMoc291cmNlUHJvamVjdGlvbiwgZGVzdGluYXRpb25Qcm9qZWN0aW9uKSB7XG4gIHZhciBzb3VyY2VDb2RlID0gc291cmNlUHJvamVjdGlvbi5nZXRDb2RlKCk7XG4gIHZhciBkZXN0aW5hdGlvbkNvZGUgPSBkZXN0aW5hdGlvblByb2plY3Rpb24uZ2V0Q29kZSgpO1xuICB2YXIgdHJhbnNmb3JtRnVuYyA9IGdldFRyYW5zZm9ybUZ1bmMoc291cmNlQ29kZSwgZGVzdGluYXRpb25Db2RlKTtcblxuICBpZiAoIXRyYW5zZm9ybUZ1bmMpIHtcbiAgICB0cmFuc2Zvcm1GdW5jID0gaWRlbnRpdHlUcmFuc2Zvcm07XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtRnVuYztcbn1cbi8qKlxuICogR2l2ZW4gdGhlIHByb2plY3Rpb24tbGlrZSBvYmplY3RzLCBzZWFyY2hlcyBmb3IgYSB0cmFuc2Zvcm1hdGlvblxuICogZnVuY3Rpb24gdG8gY29udmVydCBhIGNvb3JkaW5hdGVzIGFycmF5IGZyb20gdGhlIHNvdXJjZSBwcm9qZWN0aW9uIHRvIHRoZVxuICogZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBzb3VyY2UgU291cmNlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24uXG4gKiBAcmV0dXJuIHtUcmFuc2Zvcm1GdW5jdGlvbn0gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2Zvcm0oc291cmNlLCBkZXN0aW5hdGlvbikge1xuICB2YXIgc291cmNlUHJvamVjdGlvbiA9IGdldChzb3VyY2UpO1xuICB2YXIgZGVzdGluYXRpb25Qcm9qZWN0aW9uID0gZ2V0KGRlc3RpbmF0aW9uKTtcbiAgcmV0dXJuIGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyhzb3VyY2VQcm9qZWN0aW9uLCBkZXN0aW5hdGlvblByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgY29vcmRpbmF0ZSBmcm9tIHNvdXJjZSBwcm9qZWN0aW9uIHRvIGRlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKiBUaGlzIHJldHVybnMgYSBuZXcgY29vcmRpbmF0ZSAoYW5kIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwpLlxuICpcbiAqIFNlZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+dHJhbnNmb3JtRXh0ZW50fSBmb3IgZXh0ZW50IHRyYW5zZm9ybWF0aW9uLlxuICogU2VlIHRoZSB0cmFuc2Zvcm0gbWV0aG9kIG9mIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9HZW9tZXRyeX5HZW9tZXRyeX0gYW5kIGl0c1xuICogc3ViY2xhc3NlcyBmb3IgZ2VvbWV0cnkgdHJhbnNmb3Jtcy5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBzb3VyY2UgU291cmNlIHByb2plY3Rpb24tbGlrZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RpbmF0aW9uIERlc3RpbmF0aW9uIHByb2plY3Rpb24tbGlrZS5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm0oY29vcmRpbmF0ZSwgc291cmNlLCBkZXN0aW5hdGlvbikge1xuICB2YXIgdHJhbnNmb3JtRnVuYyA9IGdldFRyYW5zZm9ybShzb3VyY2UsIGRlc3RpbmF0aW9uKTtcbiAgcmV0dXJuIHRyYW5zZm9ybUZ1bmMoY29vcmRpbmF0ZSwgdW5kZWZpbmVkLCBjb29yZGluYXRlLmxlbmd0aCk7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgYW4gZXh0ZW50IGZyb20gc291cmNlIHByb2plY3Rpb24gdG8gZGVzdGluYXRpb24gcHJvamVjdGlvbi4gIFRoaXNcbiAqIHJldHVybnMgYSBuZXcgZXh0ZW50IChhbmQgZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCkuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBUaGUgZXh0ZW50IHRvIHRyYW5zZm9ybS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UgcHJvamVjdGlvbi1saWtlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi1saWtlLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3RvcHMgTnVtYmVyIG9mIHN0b3BzIHBlciBzaWRlIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm0uXG4gKiBCeSBkZWZhdWx0IG9ubHkgdGhlIGNvcm5lcnMgYXJlIHVzZWQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFRoZSB0cmFuc2Zvcm1lZCBleHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybUV4dGVudChleHRlbnQsIHNvdXJjZSwgZGVzdGluYXRpb24sIG9wdF9zdG9wcykge1xuICB2YXIgdHJhbnNmb3JtRnVuYyA9IGdldFRyYW5zZm9ybShzb3VyY2UsIGRlc3RpbmF0aW9uKTtcbiAgcmV0dXJuIGFwcGx5VHJhbnNmb3JtKGV4dGVudCwgdHJhbnNmb3JtRnVuYywgdW5kZWZpbmVkLCBvcHRfc3RvcHMpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIHRoZSBnaXZlbiBwb2ludCB0byB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBwb2ludCBQb2ludC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gc291cmNlUHJvamVjdGlvbiBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gZGVzdGluYXRpb25Qcm9qZWN0aW9uIERlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gUG9pbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVdpdGhQcm9qZWN0aW9ucyhwb2ludCwgc291cmNlUHJvamVjdGlvbiwgZGVzdGluYXRpb25Qcm9qZWN0aW9uKSB7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHNvdXJjZVByb2plY3Rpb24sIGRlc3RpbmF0aW9uUHJvamVjdGlvbik7XG4gIHJldHVybiB0cmFuc2Zvcm1GdW5jKHBvaW50KTtcbn1cbi8qKlxuICogQHR5cGUgez9Qcm9qZWN0aW9ufVxuICovXG5cbnZhciB1c2VyUHJvamVjdGlvbiA9IG51bGw7XG4vKipcbiAqIFNldCB0aGUgcHJvamVjdGlvbiBmb3IgY29vcmRpbmF0ZXMgc3VwcGxpZWQgZnJvbSBhbmQgcmV0dXJuZWQgYnkgQVBJIG1ldGhvZHMuXG4gKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2YgdGhlIHN0YWJsZSBBUEkuICBTdXBwb3J0IGZvciB1c2VyXG4gKiBwcm9qZWN0aW9ucyBpcyBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGQgYmUgY29uc2lkZXJlZCBleHBlcmltZW50YWwuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uIFRoZSB1c2VyIHByb2plY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNldFVzZXJQcm9qZWN0aW9uKHByb2plY3Rpb24pIHtcbiAgdXNlclByb2plY3Rpb24gPSBnZXQocHJvamVjdGlvbik7XG59XG4vKipcbiAqIENsZWFyIHRoZSB1c2VyIHByb2plY3Rpb24gaWYgc2V0LiAgTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGlzIG5vdCB5ZXQgYSBwYXJ0IG9mXG4gKiB0aGUgc3RhYmxlIEFQSS4gIFN1cHBvcnQgZm9yIHVzZXIgcHJvamVjdGlvbnMgaXMgbm90IHlldCBjb21wbGV0ZSBhbmQgc2hvdWxkXG4gKiBiZSBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJVc2VyUHJvamVjdGlvbigpIHtcbiAgdXNlclByb2plY3Rpb24gPSBudWxsO1xufVxuLyoqXG4gKiBHZXQgdGhlIHByb2plY3Rpb24gZm9yIGNvb3JkaW5hdGVzIHN1cHBsaWVkIGZyb20gYW5kIHJldHVybmVkIGJ5IEFQSSBtZXRob2RzLlxuICogTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGlzIG5vdCB5ZXQgYSBwYXJ0IG9mIHRoZSBzdGFibGUgQVBJLiAgU3VwcG9ydCBmb3IgdXNlclxuICogcHJvamVjdGlvbnMgaXMgbm90IHlldCBjb21wbGV0ZSBhbmQgc2hvdWxkIGJlIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsLlxuICogQHJldHVybnMgez9Qcm9qZWN0aW9ufSBUaGUgdXNlciBwcm9qZWN0aW9uIChvciBudWxsIGlmIG5vdCBzZXQpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRVc2VyUHJvamVjdGlvbigpIHtcbiAgcmV0dXJuIHVzZXJQcm9qZWN0aW9uO1xufVxuLyoqXG4gKiBVc2UgZ2VvZ3JhcGhpYyBjb29yZGluYXRlcyAoV0dTLTg0IGRhdHVtKSBpbiBBUEkgbWV0aG9kcy4gIE5vdGUgdGhhdCB0aGlzXG4gKiBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2YgdGhlIHN0YWJsZSBBUEkuICBTdXBwb3J0IGZvciB1c2VyIHByb2plY3Rpb25zIGlzXG4gKiBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGQgYmUgY29uc2lkZXJlZCBleHBlcmltZW50YWwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHVzZUdlb2dyYXBoaWMoKSB7XG4gIHNldFVzZXJQcm9qZWN0aW9uKCdFUFNHOjQzMjYnKTtcbn1cbi8qKlxuICogUmV0dXJuIGEgY29vcmRpbmF0ZSB0cmFuc2Zvcm1lZCBpbnRvIHRoZSB1c2VyIHByb2plY3Rpb24uICBJZiBubyB1c2VyIHByb2plY3Rpb25cbiAqIGlzIHNldCwgdGhlIG9yaWdpbmFsIGNvb3JkaW5hdGUgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNvb3JkaW5hdGUgSW5wdXQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZVByb2plY3Rpb24gVGhlIGlucHV0IGNvb3JkaW5hdGUgcHJvamVjdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBUaGUgaW5wdXQgY29vcmRpbmF0ZSBpbiB0aGUgdXNlciBwcm9qZWN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1VzZXJDb29yZGluYXRlKGNvb3JkaW5hdGUsIHNvdXJjZVByb2plY3Rpb24pIHtcbiAgaWYgKCF1c2VyUHJvamVjdGlvbikge1xuICAgIHJldHVybiBjb29yZGluYXRlO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybShjb29yZGluYXRlLCBzb3VyY2VQcm9qZWN0aW9uLCB1c2VyUHJvamVjdGlvbik7XG59XG4vKipcbiAqIFJldHVybiBhIGNvb3JkaW5hdGUgdHJhbnNmb3JtZWQgZnJvbSB0aGUgdXNlciBwcm9qZWN0aW9uLiAgSWYgbm8gdXNlciBwcm9qZWN0aW9uXG4gKiBpcyBzZXQsIHRoZSBvcmlnaW5hbCBjb29yZGluYXRlIGlzIHJldHVybmVkLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBjb29yZGluYXRlIElucHV0IGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0UHJvamVjdGlvbiBUaGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheTxudW1iZXI+fSBUaGUgaW5wdXQgY29vcmRpbmF0ZSB0cmFuc2Zvcm1lZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVVzZXJDb29yZGluYXRlKGNvb3JkaW5hdGUsIGRlc3RQcm9qZWN0aW9uKSB7XG4gIGlmICghdXNlclByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gY29vcmRpbmF0ZTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm0oY29vcmRpbmF0ZSwgdXNlclByb2plY3Rpb24sIGRlc3RQcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogUmV0dXJuIGFuIGV4dGVudCB0cmFuc2Zvcm1lZCBpbnRvIHRoZSB1c2VyIHByb2plY3Rpb24uICBJZiBubyB1c2VyIHByb2plY3Rpb25cbiAqIGlzIHNldCwgdGhlIG9yaWdpbmFsIGV4dGVudCBpcyByZXR1cm5lZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgSW5wdXQgZXh0ZW50LlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlUHJvamVjdGlvbiBUaGUgaW5wdXQgZXh0ZW50IHByb2plY3Rpb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBUaGUgaW5wdXQgZXh0ZW50IGluIHRoZSB1c2VyIHByb2plY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvVXNlckV4dGVudChleHRlbnQsIHNvdXJjZVByb2plY3Rpb24pIHtcbiAgaWYgKCF1c2VyUHJvamVjdGlvbikge1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgc291cmNlUHJvamVjdGlvbiwgdXNlclByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBSZXR1cm4gYW4gZXh0ZW50IHRyYW5zZm9ybWVkIGZyb20gdGhlIHVzZXIgcHJvamVjdGlvbi4gIElmIG5vIHVzZXIgcHJvamVjdGlvblxuICogaXMgc2V0LCB0aGUgb3JpZ2luYWwgZXh0ZW50IGlzIHJldHVybmVkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBJbnB1dCBleHRlbnQuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0UHJvamVjdGlvbiBUaGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFRoZSBpbnB1dCBleHRlbnQgdHJhbnNmb3JtZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Vc2VyRXh0ZW50KGV4dGVudCwgZGVzdFByb2plY3Rpb24pIHtcbiAgaWYgKCF1c2VyUHJvamVjdGlvbikge1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgdXNlclByb2plY3Rpb24sIGRlc3RQcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIHNhZmUgY29vcmRpbmF0ZSB0cmFuc2Zvcm0gZnVuY3Rpb24gZnJvbSBhIGNvb3JkaW5hdGUgdHJhbnNmb3JtIGZ1bmN0aW9uLlxuICogXCJTYWZlXCIgbWVhbnMgdGhhdCBpdCBjYW4gaGFuZGxlIHdyYXBwaW5nIG9mIHgtY29vcmRpbmF0ZXMgZm9yIGdsb2JhbCBwcm9qZWN0aW9ucyxcbiAqIGFuZCB0aGF0IGNvb3JkaW5hdGVzIGV4Y2VlZGluZyB0aGUgc291cmNlIHByb2plY3Rpb24gdmFsaWRpdHkgZXh0ZW50J3MgcmFuZ2Ugd2lsbCBiZVxuICogY2xhbXBlZCB0byB0aGUgdmFsaWRpdHkgcmFuZ2UuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHNvdXJjZVByb2ogU291cmNlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IGRlc3RQcm9qIERlc3RpbmF0aW9uIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHRyYW5zZm9ybSBUcmFuc2Zvcm0gZnVuY3Rpb24gKHNvdXJjZSB0byBkZXN0aWF0aW9uKS5cbiAqIEByZXR1cm4ge2Z1bmN0aW9uKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFNhZmUgdHJhbnNmb3JtIGZ1bmN0aW9uIChzb3VyY2UgdG8gZGVzdGlhdGlvbikuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNhZmVDb29yZGluYXRlVHJhbnNmb3JtKHNvdXJjZVByb2osIGRlc3RQcm9qLCB0cmFuc2Zvcm0pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChjb29yZCkge1xuICAgIHZhciBzb3VyY2VYID0gY29vcmRbMF07XG4gICAgdmFyIHNvdXJjZVkgPSBjb29yZFsxXTtcbiAgICB2YXIgdHJhbnNmb3JtZWQsIHdvcmxkc0F3YXk7XG5cbiAgICBpZiAoc291cmNlUHJvai5jYW5XcmFwWCgpKSB7XG4gICAgICB2YXIgc291cmNlRXh0ZW50ID0gc291cmNlUHJvai5nZXRFeHRlbnQoKTtcbiAgICAgIHZhciBzb3VyY2VFeHRlbnRXaWR0aCA9IGdldFdpZHRoKHNvdXJjZUV4dGVudCk7XG4gICAgICB3b3JsZHNBd2F5ID0gZ2V0V29ybGRzQXdheShjb29yZCwgc291cmNlUHJvaiwgc291cmNlRXh0ZW50V2lkdGgpO1xuXG4gICAgICBpZiAod29ybGRzQXdheSkge1xuICAgICAgICAvLyBNb3ZlIHggdG8gdGhlIHJlYWwgd29ybGRcbiAgICAgICAgc291cmNlWCA9IHNvdXJjZVggLSB3b3JsZHNBd2F5ICogc291cmNlRXh0ZW50V2lkdGg7XG4gICAgICB9XG5cbiAgICAgIHNvdXJjZVggPSBjbGFtcChzb3VyY2VYLCBzb3VyY2VFeHRlbnRbMF0sIHNvdXJjZUV4dGVudFsyXSk7XG4gICAgICBzb3VyY2VZID0gY2xhbXAoc291cmNlWSwgc291cmNlRXh0ZW50WzFdLCBzb3VyY2VFeHRlbnRbM10pO1xuICAgICAgdHJhbnNmb3JtZWQgPSB0cmFuc2Zvcm0oW3NvdXJjZVgsIHNvdXJjZVldKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJhbnNmb3JtZWQgPSB0cmFuc2Zvcm0oY29vcmQpO1xuICAgIH1cblxuICAgIGlmICh3b3JsZHNBd2F5ICYmIGRlc3RQcm9qLmNhbldyYXBYKCkpIHtcbiAgICAgIC8vIE1vdmUgdHJhbnNmb3JtZWQgY29vcmRpbmF0ZSBiYWNrIHRvIHRoZSBvZmZzZXQgd29ybGRcbiAgICAgIHRyYW5zZm9ybWVkWzBdICs9IHdvcmxkc0F3YXkgKiBnZXRXaWR0aChkZXN0UHJvai5nZXRFeHRlbnQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyYW5zZm9ybWVkO1xuICB9O1xufVxuLyoqXG4gKiBBZGQgdHJhbnNmb3JtcyB0byBhbmQgZnJvbSBFUFNHOjQzMjYgYW5kIEVQU0c6Mzg1Ny4gIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkXG4gKiBieSB3aGVuIHRoaXMgbW9kdWxlIGlzIGV4ZWN1dGVkIGFuZCBzaG91bGQgb25seSBuZWVkIHRvIGJlIGNhbGxlZCBhZ2FpbiBhZnRlclxuICogYGNsZWFyQWxsUHJvamVjdGlvbnMoKWAgaXMgY2FsbGVkIChlLmcuIGluIHRlc3RzKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkQ29tbW9uKCkge1xuICAvLyBBZGQgdHJhbnNmb3JtYXRpb25zIHRoYXQgZG9uJ3QgYWx0ZXIgY29vcmRpbmF0ZXMgdG8gY29udmVydCB3aXRoaW4gc2V0IG9mXG4gIC8vIHByb2plY3Rpb25zIHdpdGggZXF1YWwgbWVhbmluZy5cbiAgYWRkRXF1aXZhbGVudFByb2plY3Rpb25zKEVQU0czODU3X1BST0pFQ1RJT05TKTtcbiAgYWRkRXF1aXZhbGVudFByb2plY3Rpb25zKEVQU0c0MzI2X1BST0pFQ1RJT05TKTsgLy8gQWRkIHRyYW5zZm9ybWF0aW9ucyB0byBjb252ZXJ0IEVQU0c6NDMyNiBsaWtlIGNvb3JkaW5hdGVzIHRvIEVQU0c6Mzg1NyBsaWtlXG4gIC8vIGNvb3JkaW5hdGVzIGFuZCBiYWNrLlxuXG4gIGFkZEVxdWl2YWxlbnRUcmFuc2Zvcm1zKEVQU0c0MzI2X1BST0pFQ1RJT05TLCBFUFNHMzg1N19QUk9KRUNUSU9OUywgZnJvbUVQU0c0MzI2LCB0b0VQU0c0MzI2KTtcbn1cbmFkZENvbW1vbigpOyIsIi8qKlxuICogQG1vZHVsZSBvbC9jZW50ZXJjb25zdHJhaW50XG4gKi9cbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi9tYXRoLmpzJztcbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKChpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWQpLCBudW1iZXIsIGltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplLCBib29sZWFuPSwgQXJyYXk8bnVtYmVyPj0pOiAoaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkKX0gVHlwZVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9ubHlDZW50ZXIgSWYgdHJ1ZSwgdGhlIGNvbnN0cmFpbnQgd2lsbCBvbmx5IGFwcGx5IHRvIHRoZSB2aWV3IGNlbnRlci5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gc21vb3RoIElmIHRydWUsIHRoZSB2aWV3IHdpbGwgYmUgYWJsZSB0byBnbyBzbGlnaHRseSBvdXQgb2YgdGhlIGdpdmVuIGV4dGVudFxuICogKG9ubHkgZHVyaW5nIGludGVyYWN0aW9uIGFuZCBhbmltYXRpb24pLlxuICogQHJldHVybiB7VHlwZX0gVGhlIGNvbnN0cmFpbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUV4dGVudChleHRlbnQsIG9ubHlDZW50ZXIsIHNtb290aCkge1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBjZW50ZXIgQ2VudGVyLlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBWaWV3cG9ydCBzaXplOyB1bnVzZWQgaWYgYG9ubHlDZW50ZXJgIHdhcyBzcGVjaWZpZWQuXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2lzTW92aW5nIFRydWUgaWYgYW4gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIGluIHByb2dyZXNzLlxuICAgICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9jZW50ZXJTaGlmdCBTaGlmdCBiZXR3ZWVuIG1hcCBjZW50ZXIgYW5kIHZpZXdwb3J0IGNlbnRlci5cbiAgICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IENlbnRlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoY2VudGVyLCByZXNvbHV0aW9uLCBzaXplLCBvcHRfaXNNb3ZpbmcsIG9wdF9jZW50ZXJTaGlmdCkge1xuICAgICAgaWYgKGNlbnRlcikge1xuICAgICAgICB2YXIgdmlld1dpZHRoID0gb25seUNlbnRlciA/IDAgOiBzaXplWzBdICogcmVzb2x1dGlvbjtcbiAgICAgICAgdmFyIHZpZXdIZWlnaHQgPSBvbmx5Q2VudGVyID8gMCA6IHNpemVbMV0gKiByZXNvbHV0aW9uO1xuICAgICAgICB2YXIgc2hpZnRYID0gb3B0X2NlbnRlclNoaWZ0ID8gb3B0X2NlbnRlclNoaWZ0WzBdIDogMDtcbiAgICAgICAgdmFyIHNoaWZ0WSA9IG9wdF9jZW50ZXJTaGlmdCA/IG9wdF9jZW50ZXJTaGlmdFsxXSA6IDA7XG4gICAgICAgIHZhciBtaW5YID0gZXh0ZW50WzBdICsgdmlld1dpZHRoIC8gMiArIHNoaWZ0WDtcbiAgICAgICAgdmFyIG1heFggPSBleHRlbnRbMl0gLSB2aWV3V2lkdGggLyAyICsgc2hpZnRYO1xuICAgICAgICB2YXIgbWluWSA9IGV4dGVudFsxXSArIHZpZXdIZWlnaHQgLyAyICsgc2hpZnRZO1xuICAgICAgICB2YXIgbWF4WSA9IGV4dGVudFszXSAtIHZpZXdIZWlnaHQgLyAyICsgc2hpZnRZOyAvLyBub3RlOiB3aGVuIHpvb21pbmcgb3V0IG9mIGJvdW5kcywgbWluIGFuZCBtYXggdmFsdWVzIGZvciB4IGFuZCB5IG1heVxuICAgICAgICAvLyBlbmQgdXAgaW52ZXJ0ZWQgKG1pbiA+IG1heCk7IHRoaXMgaGFzIHRvIGJlIGFjY291bnRlZCBmb3JcblxuICAgICAgICBpZiAobWluWCA+IG1heFgpIHtcbiAgICAgICAgICBtaW5YID0gKG1heFggKyBtaW5YKSAvIDI7XG4gICAgICAgICAgbWF4WCA9IG1pblg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWluWSA+IG1heFkpIHtcbiAgICAgICAgICBtaW5ZID0gKG1heFkgKyBtaW5ZKSAvIDI7XG4gICAgICAgICAgbWF4WSA9IG1pblk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgeCA9IGNsYW1wKGNlbnRlclswXSwgbWluWCwgbWF4WCk7XG4gICAgICAgIHZhciB5ID0gY2xhbXAoY2VudGVyWzFdLCBtaW5ZLCBtYXhZKTtcbiAgICAgICAgdmFyIHJhdGlvID0gMzAgKiByZXNvbHV0aW9uOyAvLyBkdXJpbmcgYW4gaW50ZXJhY3Rpb24sIGFsbG93IHNvbWUgb3ZlcnNjcm9sbFxuXG4gICAgICAgIGlmIChvcHRfaXNNb3ZpbmcgJiYgc21vb3RoKSB7XG4gICAgICAgICAgeCArPSAtcmF0aW8gKiBNYXRoLmxvZygxICsgTWF0aC5tYXgoMCwgbWluWCAtIGNlbnRlclswXSkgLyByYXRpbykgKyByYXRpbyAqIE1hdGgubG9nKDEgKyBNYXRoLm1heCgwLCBjZW50ZXJbMF0gLSBtYXhYKSAvIHJhdGlvKTtcbiAgICAgICAgICB5ICs9IC1yYXRpbyAqIE1hdGgubG9nKDEgKyBNYXRoLm1heCgwLCBtaW5ZIC0gY2VudGVyWzFdKSAvIHJhdGlvKSArIHJhdGlvICogTWF0aC5sb2coMSArIE1hdGgubWF4KDAsIGNlbnRlclsxXSAtIG1heFkpIC8gcmF0aW8pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFt4LCB5XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gY2VudGVyIENlbnRlci5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gQ2VudGVyLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub25lKGNlbnRlcikge1xuICByZXR1cm4gY2VudGVyO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9yZXNvbHV0aW9uY29uc3RyYWludFxuICovXG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gJy4vbWF0aC5qcyc7XG5pbXBvcnQgeyBnZXRIZWlnaHQsIGdldFdpZHRoIH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgbGluZWFyRmluZE5lYXJlc3QgfSBmcm9tICcuL2FycmF5LmpzJztcbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKChudW1iZXJ8dW5kZWZpbmVkKSwgbnVtYmVyLCBpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZSwgYm9vbGVhbj0pOiAobnVtYmVyfHVuZGVmaW5lZCl9IFR5cGVcbiAqL1xuXG4vKipcbiAqIFJldHVybnMgYSBtb2RpZmllZCByZXNvbHV0aW9uIHRha2luZyBpbnRvIGFjY291bnQgdGhlIHZpZXdwb3J0IHNpemUgYW5kIG1heGltdW1cbiAqIGFsbG93ZWQgZXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvblxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heEV4dGVudCBNYXhpbXVtIGFsbG93ZWQgZXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gdmlld3BvcnRTaXplIFZpZXdwb3J0IHNpemUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHNob3dGdWxsRXh0ZW50IFdoZXRoZXIgdG8gc2hvdyB0aGUgZnVsbCBleHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IENhcHBlZCByZXNvbHV0aW9uLlxuICovXG5cbmZ1bmN0aW9uIGdldFZpZXdwb3J0Q2xhbXBlZFJlc29sdXRpb24ocmVzb2x1dGlvbiwgbWF4RXh0ZW50LCB2aWV3cG9ydFNpemUsIHNob3dGdWxsRXh0ZW50KSB7XG4gIHZhciB4UmVzb2x1dGlvbiA9IGdldFdpZHRoKG1heEV4dGVudCkgLyB2aWV3cG9ydFNpemVbMF07XG4gIHZhciB5UmVzb2x1dGlvbiA9IGdldEhlaWdodChtYXhFeHRlbnQpIC8gdmlld3BvcnRTaXplWzFdO1xuXG4gIGlmIChzaG93RnVsbEV4dGVudCkge1xuICAgIHJldHVybiBNYXRoLm1pbihyZXNvbHV0aW9uLCBNYXRoLm1heCh4UmVzb2x1dGlvbiwgeVJlc29sdXRpb24pKTtcbiAgfVxuXG4gIHJldHVybiBNYXRoLm1pbihyZXNvbHV0aW9uLCBNYXRoLm1pbih4UmVzb2x1dGlvbiwgeVJlc29sdXRpb24pKTtcbn1cbi8qKlxuICogUmV0dXJucyBhIG1vZGlmaWVkIHJlc29sdXRpb24gdG8gYmUgYmV0d2VlbiBtYXhSZXNvbHV0aW9uIGFuZCBtaW5SZXNvbHV0aW9uIHdoaWxlXG4gKiBzdGlsbCBhbGxvd2luZyB0aGUgdmFsdWUgdG8gYmUgc2xpZ2h0bHkgb3V0IG9mIGJvdW5kcy5cbiAqIE5vdGU6IHRoZSBjb21wdXRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgbG9nYXJpdGhtIGZ1bmN0aW9uIChsbik6XG4gKiAgLSBhdCAxLCBsbih4KSBpcyAwXG4gKiAgLSBhYm92ZSAxLCBsbih4KSBrZWVwcyBpbmNyZWFzaW5nIGJ1dCBhdCBhIG11Y2ggc2xvd2VyIHBhY2UgdGhhbiB4XG4gKiBUaGUgZmluYWwgcmVzdWx0IGlzIGNsYW1wZWQgdG8gcHJldmVudCBnZXR0aW5nIHRvbyBmYXIgYXdheSBmcm9tIGJvdW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4UmVzb2x1dGlvbiBNYXggcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5SZXNvbHV0aW9uIE1pbiByZXNvbHV0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBTbW9vdGhlZCByZXNvbHV0aW9uLlxuICovXG5cblxuZnVuY3Rpb24gZ2V0U21vb3RoQ2xhbXBlZFJlc29sdXRpb24ocmVzb2x1dGlvbiwgbWF4UmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbikge1xuICB2YXIgcmVzdWx0ID0gTWF0aC5taW4ocmVzb2x1dGlvbiwgbWF4UmVzb2x1dGlvbik7XG4gIHZhciByYXRpbyA9IDUwO1xuICByZXN1bHQgKj0gTWF0aC5sb2coMSArIHJhdGlvICogTWF0aC5tYXgoMCwgcmVzb2x1dGlvbiAvIG1heFJlc29sdXRpb24gLSAxKSkgLyByYXRpbyArIDE7XG5cbiAgaWYgKG1pblJlc29sdXRpb24pIHtcbiAgICByZXN1bHQgPSBNYXRoLm1heChyZXN1bHQsIG1pblJlc29sdXRpb24pO1xuICAgIHJlc3VsdCAvPSBNYXRoLmxvZygxICsgcmF0aW8gKiBNYXRoLm1heCgwLCBtaW5SZXNvbHV0aW9uIC8gcmVzb2x1dGlvbiAtIDEpKSAvIHJhdGlvICsgMTtcbiAgfVxuXG4gIHJldHVybiBjbGFtcChyZXN1bHQsIG1pblJlc29sdXRpb24gLyAyLCBtYXhSZXNvbHV0aW9uICogMik7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gcmVzb2x1dGlvbnMgUmVzb2x1dGlvbnMuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc21vb3RoIElmIHRydWUsIHRoZSB2aWV3IHdpbGwgYmUgYWJsZSB0byBzbGlnaHRseSBleGNlZWQgcmVzb2x1dGlvbiBsaW1pdHMuIERlZmF1bHQ6IHRydWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9tYXhFeHRlbnQgTWF4aW11bSBhbGxvd2VkIGV4dGVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaG93RnVsbEV4dGVudCBJZiB0cnVlLCBhbGxvd3MgdXMgdG8gc2hvdyB0aGUgZnVsbCBleHRlbnQuIERlZmF1bHQ6IGZhbHNlLlxuICogQHJldHVybiB7VHlwZX0gWm9vbSBmdW5jdGlvbi5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTbmFwVG9SZXNvbHV0aW9ucyhyZXNvbHV0aW9ucywgb3B0X3Ntb290aCwgb3B0X21heEV4dGVudCwgb3B0X3Nob3dGdWxsRXh0ZW50KSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpcmVjdGlvbiBEaXJlY3Rpb24uXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBWaWV3cG9ydCBzaXplLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9pc01vdmluZyBUcnVlIGlmIGFuIGludGVyYWN0aW9uIG9yIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBSZXNvbHV0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChyZXNvbHV0aW9uLCBkaXJlY3Rpb24sIHNpemUsIG9wdF9pc01vdmluZykge1xuICAgICAgaWYgKHJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgbWF4UmVzb2x1dGlvbiA9IHJlc29sdXRpb25zWzBdO1xuICAgICAgICB2YXIgbWluUmVzb2x1dGlvbiA9IHJlc29sdXRpb25zW3Jlc29sdXRpb25zLmxlbmd0aCAtIDFdO1xuICAgICAgICB2YXIgY2FwcGVkTWF4UmVzID0gb3B0X21heEV4dGVudCA/IGdldFZpZXdwb3J0Q2xhbXBlZFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgb3B0X21heEV4dGVudCwgc2l6ZSwgb3B0X3Nob3dGdWxsRXh0ZW50KSA6IG1heFJlc29sdXRpb247IC8vIGR1cmluZyBpbnRlcmFjdGluZyBvciBhbmltYXRpbmcsIGFsbG93IGludGVybWVkaWFyeSB2YWx1ZXNcblxuICAgICAgICBpZiAob3B0X2lzTW92aW5nKSB7XG4gICAgICAgICAgdmFyIHNtb290aCA9IG9wdF9zbW9vdGggIT09IHVuZGVmaW5lZCA/IG9wdF9zbW9vdGggOiB0cnVlO1xuXG4gICAgICAgICAgaWYgKCFzbW9vdGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjbGFtcChyZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uLCBjYXBwZWRNYXhSZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBnZXRTbW9vdGhDbGFtcGVkUmVzb2x1dGlvbihyZXNvbHV0aW9uLCBjYXBwZWRNYXhSZXMsIG1pblJlc29sdXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNhcHBlZCA9IE1hdGgubWluKGNhcHBlZE1heFJlcywgcmVzb2x1dGlvbik7XG4gICAgICAgIHZhciB6ID0gTWF0aC5mbG9vcihsaW5lYXJGaW5kTmVhcmVzdChyZXNvbHV0aW9ucywgY2FwcGVkLCBkaXJlY3Rpb24pKTtcblxuICAgICAgICBpZiAocmVzb2x1dGlvbnNbel0gPiBjYXBwZWRNYXhSZXMgJiYgeiA8IHJlc29sdXRpb25zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICByZXR1cm4gcmVzb2x1dGlvbnNbeiArIDFdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc29sdXRpb25zW3pdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3dlciBQb3dlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhSZXNvbHV0aW9uIE1heGltdW0gcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X21pblJlc29sdXRpb24gTWluaW11bSByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3Ntb290aCBJZiB0cnVlLCB0aGUgdmlldyB3aWxsIGJlIGFibGUgdG8gc2xpZ2h0bHkgZXhjZWVkIHJlc29sdXRpb24gbGltaXRzLiBEZWZhdWx0OiB0cnVlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfbWF4RXh0ZW50IE1heGltdW0gYWxsb3dlZCBleHRlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2hvd0Z1bGxFeHRlbnQgSWYgdHJ1ZSwgYWxsb3dzIHVzIHRvIHNob3cgdGhlIGZ1bGwgZXh0ZW50LiBEZWZhdWx0OiBmYWxzZS5cbiAqIEByZXR1cm4ge1R5cGV9IFpvb20gZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNuYXBUb1Bvd2VyKHBvd2VyLCBtYXhSZXNvbHV0aW9uLCBvcHRfbWluUmVzb2x1dGlvbiwgb3B0X3Ntb290aCwgb3B0X21heEV4dGVudCwgb3B0X3Nob3dGdWxsRXh0ZW50KSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpcmVjdGlvbiBEaXJlY3Rpb24uXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBWaWV3cG9ydCBzaXplLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9pc01vdmluZyBUcnVlIGlmIGFuIGludGVyYWN0aW9uIG9yIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBSZXNvbHV0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChyZXNvbHV0aW9uLCBkaXJlY3Rpb24sIHNpemUsIG9wdF9pc01vdmluZykge1xuICAgICAgaWYgKHJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgY2FwcGVkTWF4UmVzID0gb3B0X21heEV4dGVudCA/IGdldFZpZXdwb3J0Q2xhbXBlZFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgb3B0X21heEV4dGVudCwgc2l6ZSwgb3B0X3Nob3dGdWxsRXh0ZW50KSA6IG1heFJlc29sdXRpb247XG4gICAgICAgIHZhciBtaW5SZXNvbHV0aW9uID0gb3B0X21pblJlc29sdXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9taW5SZXNvbHV0aW9uIDogMDsgLy8gZHVyaW5nIGludGVyYWN0aW5nIG9yIGFuaW1hdGluZywgYWxsb3cgaW50ZXJtZWRpYXJ5IHZhbHVlc1xuXG4gICAgICAgIGlmIChvcHRfaXNNb3ZpbmcpIHtcbiAgICAgICAgICB2YXIgc21vb3RoID0gb3B0X3Ntb290aCAhPT0gdW5kZWZpbmVkID8gb3B0X3Ntb290aCA6IHRydWU7XG5cbiAgICAgICAgICBpZiAoIXNtb290aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNsYW1wKHJlc29sdXRpb24sIG1pblJlc29sdXRpb24sIGNhcHBlZE1heFJlcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGdldFNtb290aENsYW1wZWRSZXNvbHV0aW9uKHJlc29sdXRpb24sIGNhcHBlZE1heFJlcywgbWluUmVzb2x1dGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdG9sZXJhbmNlID0gMWUtOTtcbiAgICAgICAgdmFyIG1pblpvb21MZXZlbCA9IE1hdGguY2VpbChNYXRoLmxvZyhtYXhSZXNvbHV0aW9uIC8gY2FwcGVkTWF4UmVzKSAvIE1hdGgubG9nKHBvd2VyKSAtIHRvbGVyYW5jZSk7XG4gICAgICAgIHZhciBvZmZzZXQgPSAtZGlyZWN0aW9uICogKDAuNSAtIHRvbGVyYW5jZSkgKyAwLjU7XG4gICAgICAgIHZhciBjYXBwZWQgPSBNYXRoLm1pbihjYXBwZWRNYXhSZXMsIHJlc29sdXRpb24pO1xuICAgICAgICB2YXIgY2FwcGVkWm9vbUxldmVsID0gTWF0aC5mbG9vcihNYXRoLmxvZyhtYXhSZXNvbHV0aW9uIC8gY2FwcGVkKSAvIE1hdGgubG9nKHBvd2VyKSArIG9mZnNldCk7XG4gICAgICAgIHZhciB6b29tTGV2ZWwgPSBNYXRoLm1heChtaW5ab29tTGV2ZWwsIGNhcHBlZFpvb21MZXZlbCk7XG4gICAgICAgIHZhciBuZXdSZXNvbHV0aW9uID0gbWF4UmVzb2x1dGlvbiAvIE1hdGgucG93KHBvd2VyLCB6b29tTGV2ZWwpO1xuICAgICAgICByZXR1cm4gY2xhbXAobmV3UmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgY2FwcGVkTWF4UmVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4UmVzb2x1dGlvbiBNYXggcmVzb2x1dGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5SZXNvbHV0aW9uIE1pbiByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3Ntb290aCBJZiB0cnVlLCB0aGUgdmlldyB3aWxsIGJlIGFibGUgdG8gc2xpZ2h0bHkgZXhjZWVkIHJlc29sdXRpb24gbGltaXRzLiBEZWZhdWx0OiB0cnVlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfbWF4RXh0ZW50IE1heGltdW0gYWxsb3dlZCBleHRlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfc2hvd0Z1bGxFeHRlbnQgSWYgdHJ1ZSwgYWxsb3dzIHVzIHRvIHNob3cgdGhlIGZ1bGwgZXh0ZW50LiBEZWZhdWx0OiBmYWxzZS5cbiAqIEByZXR1cm4ge1R5cGV9IFpvb20gZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1pbk1heFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgb3B0X3Ntb290aCwgb3B0X21heEV4dGVudCwgb3B0X3Nob3dGdWxsRXh0ZW50KSB7XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGRpcmVjdGlvbiBEaXJlY3Rpb24uXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBWaWV3cG9ydCBzaXplLlxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9pc01vdmluZyBUcnVlIGlmIGFuIGludGVyYWN0aW9uIG9yIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcy5cbiAgICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBSZXNvbHV0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChyZXNvbHV0aW9uLCBkaXJlY3Rpb24sIHNpemUsIG9wdF9pc01vdmluZykge1xuICAgICAgaWYgKHJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgY2FwcGVkTWF4UmVzID0gb3B0X21heEV4dGVudCA/IGdldFZpZXdwb3J0Q2xhbXBlZFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgb3B0X21heEV4dGVudCwgc2l6ZSwgb3B0X3Nob3dGdWxsRXh0ZW50KSA6IG1heFJlc29sdXRpb247XG4gICAgICAgIHZhciBzbW9vdGggPSBvcHRfc21vb3RoICE9PSB1bmRlZmluZWQgPyBvcHRfc21vb3RoIDogdHJ1ZTtcblxuICAgICAgICBpZiAoIXNtb290aCB8fCAhb3B0X2lzTW92aW5nKSB7XG4gICAgICAgICAgcmV0dXJuIGNsYW1wKHJlc29sdXRpb24sIG1pblJlc29sdXRpb24sIGNhcHBlZE1heFJlcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZ2V0U21vb3RoQ2xhbXBlZFJlc29sdXRpb24ocmVzb2x1dGlvbiwgY2FwcGVkTWF4UmVzLCBtaW5SZXNvbHV0aW9uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICApO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9yb3RhdGlvbmNvbnN0cmFpbnRcbiAqL1xuaW1wb3J0IHsgdG9SYWRpYW5zIH0gZnJvbSAnLi9tYXRoLmpzJztcbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKChudW1iZXJ8dW5kZWZpbmVkKSwgYm9vbGVhbj0pOiAobnVtYmVyfHVuZGVmaW5lZCl9IFR5cGVcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gcm90YXRpb24gUm90YXRpb24uXG4gKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBSb3RhdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGlzYWJsZShyb3RhdGlvbikge1xuICBpZiAocm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAwO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJvdGF0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub25lKHJvdGF0aW9uKSB7XG4gIGlmIChyb3RhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJvdGF0aW9uO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG4gTi5cbiAqIEByZXR1cm4ge1R5cGV9IFJvdGF0aW9uIGNvbnN0cmFpbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNuYXBUb04obikge1xuICB2YXIgdGhldGEgPSAyICogTWF0aC5QSSAvIG47XG4gIHJldHVybiAoXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfaXNNb3ZpbmcgVHJ1ZSBpZiBhbiBpbnRlcmFjdGlvbiBvciBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3MuXG4gICAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUm90YXRpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gKHJvdGF0aW9uLCBvcHRfaXNNb3ZpbmcpIHtcbiAgICAgIGlmIChvcHRfaXNNb3ZpbmcpIHtcbiAgICAgICAgcmV0dXJuIHJvdGF0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByb3RhdGlvbiA9IE1hdGguZmxvb3Iocm90YXRpb24gLyB0aGV0YSArIDAuNSkgKiB0aGV0YTtcbiAgICAgICAgcmV0dXJuIHJvdGF0aW9uO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3RvbGVyYW5jZSBUb2xlcmFuY2UuXG4gKiBAcmV0dXJuIHtUeXBlfSBSb3RhdGlvbiBjb25zdHJhaW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTbmFwVG9aZXJvKG9wdF90b2xlcmFuY2UpIHtcbiAgdmFyIHRvbGVyYW5jZSA9IG9wdF90b2xlcmFuY2UgfHwgdG9SYWRpYW5zKDUpO1xuICByZXR1cm4gKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gcm90YXRpb24gUm90YXRpb24uXG4gICAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2lzTW92aW5nIFRydWUgaWYgYW4gaW50ZXJhY3Rpb24gb3IgYW5pbWF0aW9uIGlzIGluIHByb2dyZXNzLlxuICAgICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJvdGF0aW9uLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChyb3RhdGlvbiwgb3B0X2lzTW92aW5nKSB7XG4gICAgICBpZiAob3B0X2lzTW92aW5nKSB7XG4gICAgICAgIHJldHVybiByb3RhdGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKHJvdGF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKE1hdGguYWJzKHJvdGF0aW9uKSA8PSB0b2xlcmFuY2UpIHtcbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gcm90YXRpb247XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuICApO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9lYXNpbmdcbiAqL1xuXG4vKipcbiAqIFN0YXJ0IHNsb3cgYW5kIHNwZWVkIHVwLlxuICogQHBhcmFtIHtudW1iZXJ9IHQgSW5wdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQHJldHVybiB7bnVtYmVyfSBPdXRwdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQGFwaVxuICovXG5leHBvcnQgZnVuY3Rpb24gZWFzZUluKHQpIHtcbiAgcmV0dXJuIE1hdGgucG93KHQsIDMpO1xufVxuLyoqXG4gKiBTdGFydCBmYXN0IGFuZCBzbG93IGRvd24uXG4gKiBAcGFyYW0ge251bWJlcn0gdCBJbnB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE91dHB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVhc2VPdXQodCkge1xuICByZXR1cm4gMSAtIGVhc2VJbigxIC0gdCk7XG59XG4vKipcbiAqIFN0YXJ0IHNsb3csIHNwZWVkIHVwLCBhbmQgdGhlbiBzbG93IGRvd24gYWdhaW4uXG4gKiBAcGFyYW0ge251bWJlcn0gdCBJbnB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE91dHB1dCBiZXR3ZWVuIDAgYW5kIDEuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGluQW5kT3V0KHQpIHtcbiAgcmV0dXJuIDMgKiB0ICogdCAtIDIgKiB0ICogdCAqIHQ7XG59XG4vKipcbiAqIE1haW50YWluIGEgY29uc3RhbnQgc3BlZWQgb3ZlciB0aW1lLlxuICogQHBhcmFtIHtudW1iZXJ9IHQgSW5wdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQHJldHVybiB7bnVtYmVyfSBPdXRwdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXIodCkge1xuICByZXR1cm4gdDtcbn1cbi8qKlxuICogU3RhcnQgc2xvdywgc3BlZWQgdXAsIGFuZCBhdCB0aGUgdmVyeSBlbmQgc2xvdyBkb3duIGFnYWluLiAgVGhpcyBoYXMgdGhlXG4gKiBzYW1lIGdlbmVyYWwgYmVoYXZpb3IgYXMge0BsaW5rIG1vZHVsZTpvbC9lYXNpbmd+aW5BbmRPdXR9LCBidXQgdGhlIGZpbmFsXG4gKiBzbG93ZG93biBpcyBkZWxheWVkLlxuICogQHBhcmFtIHtudW1iZXJ9IHQgSW5wdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQHJldHVybiB7bnVtYmVyfSBPdXRwdXQgYmV0d2VlbiAwIGFuZCAxLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB1cEFuZERvd24odCkge1xuICBpZiAodCA8IDAuNSkge1xuICAgIHJldHVybiBpbkFuZE91dCgyICogdCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDEgLSBpbkFuZE91dCgyICogKHQgLSAwLjUpKTtcbiAgfVxufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL0dlb21ldHJ5TGF5b3V0XG4gKi9cblxuLyoqXG4gKiBUaGUgY29vcmRpbmF0ZSBsYXlvdXQgZm9yIGdlb21ldHJpZXMsIGluZGljYXRpbmcgd2hldGhlciBhIDNyZCBvciA0dGggeiAoJ1onKVxuICogb3IgbWVhc3VyZSAoJ00nKSBjb29yZGluYXRlIGlzIGF2YWlsYWJsZS4gU3VwcG9ydGVkIHZhbHVlcyBhcmUgYCdYWSdgLFxuICogYCdYWVonYCwgYCdYWU0nYCwgYCdYWVpNJ2AuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFhZOiAnWFknLFxuICBYWVo6ICdYWVonLFxuICBYWU06ICdYWU0nLFxuICBYWVpNOiAnWFlaTSdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC90cmFuc2Zvcm1cbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtMkQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCB0cmFuc2Zvcm0sIG9wdF9kZXN0KSB7XG4gIHZhciBkZXN0ID0gb3B0X2Rlc3QgPyBvcHRfZGVzdCA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IG9mZnNldDsgaiA8IGVuZDsgaiArPSBzdHJpZGUpIHtcbiAgICB2YXIgeCA9IGZsYXRDb29yZGluYXRlc1tqXTtcbiAgICB2YXIgeSA9IGZsYXRDb29yZGluYXRlc1tqICsgMV07XG4gICAgZGVzdFtpKytdID0gdHJhbnNmb3JtWzBdICogeCArIHRyYW5zZm9ybVsyXSAqIHkgKyB0cmFuc2Zvcm1bNF07XG4gICAgZGVzdFtpKytdID0gdHJhbnNmb3JtWzFdICogeCArIHRyYW5zZm9ybVszXSAqIHkgKyB0cmFuc2Zvcm1bNV07XG4gIH1cblxuICBpZiAob3B0X2Rlc3QgJiYgZGVzdC5sZW5ndGggIT0gaSkge1xuICAgIGRlc3QubGVuZ3RoID0gaTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlIEFuZ2xlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBhbmNob3IgUm90YXRpb24gYW5jaG9yIHBvaW50LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2Rlc3QgRGVzdGluYXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1lZCBjb29yZGluYXRlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgYW5nbGUsIGFuY2hvciwgb3B0X2Rlc3QpIHtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogW107XG4gIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSk7XG4gIHZhciBzaW4gPSBNYXRoLnNpbihhbmdsZSk7XG4gIHZhciBhbmNob3JYID0gYW5jaG9yWzBdO1xuICB2YXIgYW5jaG9yWSA9IGFuY2hvclsxXTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAodmFyIGogPSBvZmZzZXQ7IGogPCBlbmQ7IGogKz0gc3RyaWRlKSB7XG4gICAgdmFyIGRlbHRhWCA9IGZsYXRDb29yZGluYXRlc1tqXSAtIGFuY2hvclg7XG4gICAgdmFyIGRlbHRhWSA9IGZsYXRDb29yZGluYXRlc1tqICsgMV0gLSBhbmNob3JZO1xuICAgIGRlc3RbaSsrXSA9IGFuY2hvclggKyBkZWx0YVggKiBjb3MgLSBkZWx0YVkgKiBzaW47XG4gICAgZGVzdFtpKytdID0gYW5jaG9yWSArIGRlbHRhWCAqIHNpbiArIGRlbHRhWSAqIGNvcztcblxuICAgIGZvciAodmFyIGsgPSBqICsgMjsgayA8IGogKyBzdHJpZGU7ICsraykge1xuICAgICAgZGVzdFtpKytdID0gZmxhdENvb3JkaW5hdGVzW2tdO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRfZGVzdCAmJiBkZXN0Lmxlbmd0aCAhPSBpKSB7XG4gICAgZGVzdC5sZW5ndGggPSBpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59XG4vKipcbiAqIFNjYWxlIHRoZSBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3ggU2NhbGUgZmFjdG9yIGluIHRoZSB4LWRpcmVjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzeSBTY2FsZSBmYWN0b3IgaW4gdGhlIHktZGlyZWN0aW9uLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBhbmNob3IgU2NhbGUgYW5jaG9yIHBvaW50LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2Rlc3QgRGVzdGluYXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1lZCBjb29yZGluYXRlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2NhbGUoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzeCwgc3ksIGFuY2hvciwgb3B0X2Rlc3QpIHtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogW107XG4gIHZhciBhbmNob3JYID0gYW5jaG9yWzBdO1xuICB2YXIgYW5jaG9yWSA9IGFuY2hvclsxXTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAodmFyIGogPSBvZmZzZXQ7IGogPCBlbmQ7IGogKz0gc3RyaWRlKSB7XG4gICAgdmFyIGRlbHRhWCA9IGZsYXRDb29yZGluYXRlc1tqXSAtIGFuY2hvclg7XG4gICAgdmFyIGRlbHRhWSA9IGZsYXRDb29yZGluYXRlc1tqICsgMV0gLSBhbmNob3JZO1xuICAgIGRlc3RbaSsrXSA9IGFuY2hvclggKyBzeCAqIGRlbHRhWDtcbiAgICBkZXN0W2krK10gPSBhbmNob3JZICsgc3kgKiBkZWx0YVk7XG5cbiAgICBmb3IgKHZhciBrID0gaiArIDI7IGsgPCBqICsgc3RyaWRlOyArK2spIHtcbiAgICAgIGRlc3RbaSsrXSA9IGZsYXRDb29yZGluYXRlc1trXTtcbiAgICB9XG4gIH1cblxuICBpZiAob3B0X2Rlc3QgJiYgZGVzdC5sZW5ndGggIT0gaSkge1xuICAgIGRlc3QubGVuZ3RoID0gaTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhWCBEZWx0YSBYLlxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhWSBEZWx0YSBZLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2Rlc3QgRGVzdGluYXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1lZCBjb29yZGluYXRlcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNsYXRlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZGVsdGFYLCBkZWx0YVksIG9wdF9kZXN0KSB7XG4gIHZhciBkZXN0ID0gb3B0X2Rlc3QgPyBvcHRfZGVzdCA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IG9mZnNldDsgaiA8IGVuZDsgaiArPSBzdHJpZGUpIHtcbiAgICBkZXN0W2krK10gPSBmbGF0Q29vcmRpbmF0ZXNbal0gKyBkZWx0YVg7XG4gICAgZGVzdFtpKytdID0gZmxhdENvb3JkaW5hdGVzW2ogKyAxXSArIGRlbHRhWTtcblxuICAgIGZvciAodmFyIGsgPSBqICsgMjsgayA8IGogKyBzdHJpZGU7ICsraykge1xuICAgICAgZGVzdFtpKytdID0gZmxhdENvb3JkaW5hdGVzW2tdO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcHRfZGVzdCAmJiBkZXN0Lmxlbmd0aCAhPSBpKSB7XG4gICAgZGVzdC5sZW5ndGggPSBpO1xuICB9XG5cbiAgcmV0dXJuIGRlc3Q7XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL0dlb21ldHJ5XG4gKi9cblxuXG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuLi9PYmplY3QuanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4uL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSB9IGZyb20gJy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbXB0eSwgY3JlYXRlT3JVcGRhdGVFbXB0eSwgZ2V0SGVpZ2h0LCByZXR1cm5PclVwZGF0ZSB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBnZXQgYXMgZ2V0UHJvamVjdGlvbiwgZ2V0VHJhbnNmb3JtIH0gZnJvbSAnLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBtZW1vaXplT25lIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IHRyYW5zZm9ybTJEIH0gZnJvbSAnLi9mbGF0L3RyYW5zZm9ybS5qcyc7XG4vKipcbiAqIEB0eXBlIHtpbXBvcnQoXCIuLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfVxuICovXG5cbnZhciB0bXBUcmFuc2Zvcm0gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogQmFzZSBjbGFzcyBmb3IgdmVjdG9yIGdlb21ldHJpZXMuXG4gKlxuICogVG8gZ2V0IG5vdGlmaWVkIG9mIGNoYW5nZXMgdG8gdGhlIGdlb21ldHJ5LCByZWdpc3RlciBhIGxpc3RlbmVyIGZvciB0aGVcbiAqIGdlbmVyaWMgYGNoYW5nZWAgZXZlbnQgb24geW91ciBnZW9tZXRyeSBpbnN0YW5jZS5cbiAqXG4gKiBAYWJzdHJhY3RcbiAqIEBhcGlcbiAqL1xuXG52YXIgR2VvbWV0cnkgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoR2VvbWV0cnksIF9zdXBlcik7XG5cbiAgZnVuY3Rpb24gR2VvbWV0cnkoKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5leHRlbnRfID0gY3JlYXRlRW1wdHkoKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5leHRlbnRSZXZpc2lvbl8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc2ltcGxpZmllZEdlb21ldHJ5UmV2aXNpb24gPSAwO1xuICAgIC8qKlxuICAgICAqIEdldCBhIHRyYW5zZm9ybWVkIGFuZCBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGdlb21ldHJ5LlxuICAgICAqIEBhYnN0cmFjdFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSByZXZpc2lvbiBUaGUgZ2VvbWV0cnkgcmV2aXNpb24uXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSBbb3B0X3RyYW5zZm9ybV0gT3B0aW9uYWwgdHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgICAqIEByZXR1cm4ge0dlb21ldHJ5fSBTaW1wbGlmaWVkIGdlb21ldHJ5LlxuICAgICAqL1xuXG4gICAgX3RoaXMuc2ltcGxpZnlUcmFuc2Zvcm1lZEludGVybmFsID0gbWVtb2l6ZU9uZShmdW5jdGlvbiAocmV2aXNpb24sIHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0pIHtcbiAgICAgIGlmICghb3B0X3RyYW5zZm9ybSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTaW1wbGlmaWVkR2VvbWV0cnkoc3F1YXJlZFRvbGVyYW5jZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjbG9uZSA9IHRoaXMuY2xvbmUoKTtcbiAgICAgIGNsb25lLmFwcGx5VHJhbnNmb3JtKG9wdF90cmFuc2Zvcm0pO1xuICAgICAgcmV0dXJuIGNsb25lLmdldFNpbXBsaWZpZWRHZW9tZXRyeShzcXVhcmVkVG9sZXJhbmNlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIHRyYW5zZm9ybWVkIGFuZCBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gW29wdF90cmFuc2Zvcm1dIE9wdGlvbmFsIHRyYW5zZm9ybSBmdW5jdGlvbi5cbiAgICogQHJldHVybiB7R2VvbWV0cnl9IFNpbXBsaWZpZWQgZ2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLnNpbXBsaWZ5VHJhbnNmb3JtZWQgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3RyYW5zZm9ybSkge1xuICAgIHJldHVybiB0aGlzLnNpbXBsaWZ5VHJhbnNmb3JtZWRJbnRlcm5hbCh0aGlzLmdldFJldmlzaW9uKCksIHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0pO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7IUdlb21ldHJ5fSBDbG9uZS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLmNvbnRhaW5zWFkgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHZhciBjb29yZCA9IHRoaXMuZ2V0Q2xvc2VzdFBvaW50KFt4LCB5XSk7XG4gICAgcmV0dXJuIGNvb3JkWzBdID09PSB4ICYmIGNvb3JkWzFdID09PSB5O1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBjbG9zZXN0IHBvaW50IG9mIHRoZSBnZW9tZXRyeSB0byB0aGUgcGFzc2VkIHBvaW50IGFzXG4gICAqIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlIGNvb3JkaW5hdGV9LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcG9pbnQgUG9pbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2Nsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENsb3Nlc3QgcG9pbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0Q2xvc2VzdFBvaW50ID0gZnVuY3Rpb24gKHBvaW50LCBvcHRfY2xvc2VzdFBvaW50KSB7XG4gICAgdmFyIGNsb3Nlc3RQb2ludCA9IG9wdF9jbG9zZXN0UG9pbnQgPyBvcHRfY2xvc2VzdFBvaW50IDogW05hTiwgTmFOXTtcbiAgICB0aGlzLmNsb3Nlc3RQb2ludFhZKHBvaW50WzBdLCBwb2ludFsxXSwgY2xvc2VzdFBvaW50LCBJbmZpbml0eSk7XG4gICAgcmV0dXJuIGNsb3Nlc3RQb2ludDtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGdlb21ldHJ5IGluY2x1ZGVzIHRoZSBzcGVjaWZpZWQgY29vcmRpbmF0ZS4gSWYgdGhlXG4gICAqIGNvb3JkaW5hdGUgaXMgb24gdGhlIGJvdW5kYXJ5IG9mIHRoZSBnZW9tZXRyeSwgcmV0dXJucyBmYWxzZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgY29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5pbnRlcnNlY3RzQ29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGFpbnNYWShjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuY29tcHV0ZUV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZW50IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKG9wdF9leHRlbnQpIHtcbiAgICBpZiAodGhpcy5leHRlbnRSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB2YXIgZXh0ZW50ID0gdGhpcy5jb21wdXRlRXh0ZW50KHRoaXMuZXh0ZW50Xyk7XG5cbiAgICAgIGlmIChpc05hTihleHRlbnRbMF0pIHx8IGlzTmFOKGV4dGVudFsxXSkpIHtcbiAgICAgICAgY3JlYXRlT3JVcGRhdGVFbXB0eShleHRlbnQpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmV4dGVudFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0dXJuT3JVcGRhdGUodGhpcy5leHRlbnRfLCBvcHRfZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFJvdGF0ZSB0aGUgZ2VvbWV0cnkgYXJvdW5kIGEgZ2l2ZW4gY29vcmRpbmF0ZS4gVGhpcyBtb2RpZmllcyB0aGUgZ2VvbWV0cnlcbiAgICogY29vcmRpbmF0ZXMgaW4gcGxhY2UuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgUm90YXRpb24gYW5nbGUgaW4gcmFkaWFucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGFuY2hvciBUaGUgcm90YXRpb24gY2VudGVyLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLnJvdGF0ZSA9IGZ1bmN0aW9uIChhbmdsZSwgYW5jaG9yKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNjYWxlIHRoZSBnZW9tZXRyeSAod2l0aCBhbiBvcHRpb25hbCBvcmlnaW4pLiAgVGhpcyBtb2RpZmllcyB0aGUgZ2VvbWV0cnlcbiAgICogY29vcmRpbmF0ZXMgaW4gcGxhY2UuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3ggVGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB4LWRpcmVjdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3kgVGhlIHNjYWxpbmcgZmFjdG9yIGluIHRoZSB5LWRpcmVjdGlvbiAoZGVmYXVsdHMgdG8gc3gpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIHNjYWxlIG9yaWdpbiAoZGVmYXVsdHMgdG8gdGhlIGNlbnRlclxuICAgKiAgICAgb2YgdGhlIGdlb21ldHJ5IGV4dGVudCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuc2NhbGUgPSBmdW5jdGlvbiAoc3gsIG9wdF9zeSwgb3B0X2FuY2hvcikge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhpcyBnZW9tZXRyeS4gIEZvciBsaW5lc3RyaW5ncywgdGhpcyB1c2VzXG4gICAqIHRoZSBbRG91Z2xhcyBQZXVja2VyXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9SYW1lci1Eb3VnbGFzLVBldWNrZXJfYWxnb3JpdGhtKVxuICAgKiBhbGdvcml0aG0uICBGb3IgcG9seWdvbnMsIGEgcXVhbnRpemF0aW9uLWJhc2VkXG4gICAqIHNpbXBsaWZpY2F0aW9uIGlzIHVzZWQgdG8gcHJlc2VydmUgdG9wb2xvZ3kuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVGhlIHRvbGVyYW5jZSBkaXN0YW5jZSBmb3Igc2ltcGxpZmljYXRpb24uXG4gICAqIEByZXR1cm4ge0dlb21ldHJ5fSBBIG5ldywgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoZSBvcmlnaW5hbCBnZW9tZXRyeS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5zaW1wbGlmeSA9IGZ1bmN0aW9uICh0b2xlcmFuY2UpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTaW1wbGlmaWVkR2VvbWV0cnkodG9sZXJhbmNlICogdG9sZXJhbmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGlzIGdlb21ldHJ5IHVzaW5nIHRoZSBEb3VnbGFzIFBldWNrZXJcbiAgICogYWxnb3JpdGhtLlxuICAgKiBTZWUgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUmFtZXItRG91Z2xhcy1QZXVja2VyX2FsZ29yaXRobS5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtHZW9tZXRyeX0gU2ltcGxpZmllZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5ID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICovXG5cblxuICBHZW9tZXRyeS5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFwcGx5IGEgdHJhbnNmb3JtIGZ1bmN0aW9uIHRvIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIFRoZSBnZW9tZXRyeSBpcyBtb2RpZmllZCBpbiBwbGFjZS5cbiAgICogSWYgeW91IGRvIG5vdCB3YW50IHRoZSBnZW9tZXRyeSBtb2RpZmllZCBpbiBwbGFjZSwgZmlyc3QgYGNsb25lKClgIGl0IGFuZFxuICAgKiB0aGVuIHVzZSB0aGlzIGZ1bmN0aW9uIG9uIHRoZSBjbG9uZS5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgKiBDYWxsZWQgd2l0aCBhIGZsYXQgYXJyYXkgb2YgZ2VvbWV0cnkgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLmFwcGx5VHJhbnNmb3JtID0gZnVuY3Rpb24gKHRyYW5zZm9ybUZuKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS5pbnRlcnNlY3RzRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogVHJhbnNsYXRlIHRoZSBnZW9tZXRyeS4gIFRoaXMgbW9kaWZpZXMgdGhlIGdlb21ldHJ5IGNvb3JkaW5hdGVzIGluIHBsYWNlLiAgSWZcbiAgICogaW5zdGVhZCB5b3Ugd2FudCBhIG5ldyBnZW9tZXRyeSwgZmlyc3QgYGNsb25lKClgIHRoaXMgZ2VvbWV0cnkuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGFYIERlbHRhIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVkgRGVsdGEgWS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5LnByb3RvdHlwZS50cmFuc2xhdGUgPSBmdW5jdGlvbiAoZGVsdGFYLCBkZWx0YVkpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogVHJhbnNmb3JtIGVhY2ggY29vcmRpbmF0ZSBvZiB0aGUgZ2VvbWV0cnkgZnJvbSBvbmUgY29vcmRpbmF0ZSByZWZlcmVuY2VcbiAgICogc3lzdGVtIHRvIGFub3RoZXIuIFRoZSBnZW9tZXRyeSBpcyBtb2RpZmllZCBpbiBwbGFjZS5cbiAgICogRm9yIGV4YW1wbGUsIGEgbGluZSB3aWxsIGJlIHRyYW5zZm9ybWVkIHRvIGEgbGluZSBhbmQgYSBjaXJjbGUgdG8gYSBjaXJjbGUuXG4gICAqIElmIHlvdSBkbyBub3Qgd2FudCB0aGUgZ2VvbWV0cnkgbW9kaWZpZWQgaW4gcGxhY2UsIGZpcnN0IGBjbG9uZSgpYCBpdCBhbmRcbiAgICogdGhlbiB1c2UgdGhpcyBmdW5jdGlvbiBvbiB0aGUgY2xvbmUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gc291cmNlIFRoZSBjdXJyZW50IHByb2plY3Rpb24uICBDYW4gYmUgYVxuICAgKiAgICAgc3RyaW5nIGlkZW50aWZpZXIgb3IgYSB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn5Qcm9qZWN0aW9ufSBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gVGhlIGRlc2lyZWQgcHJvamVjdGlvbi4gIENhbiBiZSBhXG4gICAqICAgICBzdHJpbmcgaWRlbnRpZmllciBvciBhIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9uflByb2plY3Rpb259IG9iamVjdC5cbiAgICogQHJldHVybiB7R2VvbWV0cnl9IFRoaXMgZ2VvbWV0cnkuICBOb3RlIHRoYXQgb3JpZ2luYWwgZ2VvbWV0cnkgaXNcbiAgICogICAgIG1vZGlmaWVkIGluIHBsYWNlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnkucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIChzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICB2YXIgc291cmNlUHJvaiA9IGdldFByb2plY3Rpb24oc291cmNlKTtcbiAgICB2YXIgdHJhbnNmb3JtRm4gPSBzb3VyY2VQcm9qLmdldFVuaXRzKCkgPT0gVW5pdHMuVElMRV9QSVhFTFMgPyBmdW5jdGlvbiAoaW5Db29yZGluYXRlcywgb3V0Q29vcmRpbmF0ZXMsIHN0cmlkZSkge1xuICAgICAgdmFyIHBpeGVsRXh0ZW50ID0gc291cmNlUHJvai5nZXRFeHRlbnQoKTtcbiAgICAgIHZhciBwcm9qZWN0ZWRFeHRlbnQgPSBzb3VyY2VQcm9qLmdldFdvcmxkRXh0ZW50KCk7XG4gICAgICB2YXIgc2NhbGUgPSBnZXRIZWlnaHQocHJvamVjdGVkRXh0ZW50KSAvIGdldEhlaWdodChwaXhlbEV4dGVudCk7XG4gICAgICBjb21wb3NlVHJhbnNmb3JtKHRtcFRyYW5zZm9ybSwgcHJvamVjdGVkRXh0ZW50WzBdLCBwcm9qZWN0ZWRFeHRlbnRbM10sIHNjYWxlLCAtc2NhbGUsIDAsIDAsIDApO1xuICAgICAgdHJhbnNmb3JtMkQoaW5Db29yZGluYXRlcywgMCwgaW5Db29yZGluYXRlcy5sZW5ndGgsIHN0cmlkZSwgdG1wVHJhbnNmb3JtLCBvdXRDb29yZGluYXRlcyk7XG4gICAgICByZXR1cm4gZ2V0VHJhbnNmb3JtKHNvdXJjZVByb2osIGRlc3RpbmF0aW9uKShpbkNvb3JkaW5hdGVzLCBvdXRDb29yZGluYXRlcywgc3RyaWRlKTtcbiAgICB9IDogZ2V0VHJhbnNmb3JtKHNvdXJjZVByb2osIGRlc3RpbmF0aW9uKTtcbiAgICB0aGlzLmFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybUZuKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICByZXR1cm4gR2VvbWV0cnk7XG59KEJhc2VPYmplY3QpO1xuXG5leHBvcnQgZGVmYXVsdCBHZW9tZXRyeTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vU2ltcGxlR2VvbWV0cnlcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeSBmcm9tICcuL0dlb21ldHJ5LmpzJztcbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVPclVwZGF0ZUZyb21GbGF0Q29vcmRpbmF0ZXMsIGdldENlbnRlciB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyByb3RhdGUsIHNjYWxlLCB0cmFuc2Zvcm0yRCwgdHJhbnNsYXRlIH0gZnJvbSAnLi9mbGF0L3RyYW5zZm9ybS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlczsgZG8gbm90IGluc3RhbnRpYXRlXG4gKiBpbiBhcHBzLCBhcyBjYW5ub3QgYmUgcmVuZGVyZWQuXG4gKlxuICogQGFic3RyYWN0XG4gKiBAYXBpXG4gKi9cblxudmFyIFNpbXBsZUdlb21ldHJ5ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFNpbXBsZUdlb21ldHJ5LCBfc3VwZXIpO1xuXG4gIGZ1bmN0aW9uIFNpbXBsZUdlb21ldHJ5KCkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmxheW91dCA9IEdlb21ldHJ5TGF5b3V0LlhZO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RyaWRlID0gMjtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBudWxsO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmNvbXB1dGVFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtBcnJheTwqPn0gQ29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBmaXJzdCBjb29yZGluYXRlIG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBGaXJzdCBjb29yZGluYXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldEZpcnN0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2UoMCwgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBjb29yZGluYXRlcy5cbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0RmxhdENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZsYXRDb29yZGluYXRlcztcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGFzdCBjb29yZGluYXRlIG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBMYXN0IHBvaW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldExhc3RDb29yZGluYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSh0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggLSB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9HZW9tZXRyeUxheW91dCBsYXlvdXR9IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0fSBMYXlvdXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUuZ2V0TGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxheW91dDtcbiAgfTtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNpbXBsaWZpZWQgdmVyc2lvbiBvZiB0aGlzIGdlb21ldHJ5IHVzaW5nIHRoZSBEb3VnbGFzIFBldWNrZXIgYWxnb3JpdGhtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7U2ltcGxlR2VvbWV0cnl9IFNpbXBsaWZpZWQgZ2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeSA9IGZ1bmN0aW9uIChzcXVhcmVkVG9sZXJhbmNlKSB7XG4gICAgaWYgKHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5UmV2aXNpb24gIT09IHRoaXMuZ2V0UmV2aXNpb24oKSkge1xuICAgICAgdGhpcy5zaW1wbGlmaWVkR2VvbWV0cnlNYXhNaW5TcXVhcmVkVG9sZXJhbmNlID0gMDtcbiAgICAgIHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5UmV2aXNpb24gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfSAvLyBJZiBzcXVhcmVkVG9sZXJhbmNlIGlzIG5lZ2F0aXZlIG9yIGlmIHdlIGtub3cgdGhhdCBzaW1wbGlmaWNhdGlvbiB3aWxsIG5vdFxuICAgIC8vIGhhdmUgYW55IGVmZmVjdCB0aGVuIGp1c3QgcmV0dXJuIHRoaXMuXG5cblxuICAgIGlmIChzcXVhcmVkVG9sZXJhbmNlIDwgMCB8fCB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UgIT09IDAgJiYgc3F1YXJlZFRvbGVyYW5jZSA8PSB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHZhciBzaW1wbGlmaWVkR2VvbWV0cnkgPSB0aGlzLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsKHNxdWFyZWRUb2xlcmFuY2UpO1xuICAgIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gc2ltcGxpZmllZEdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuXG4gICAgaWYgKHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoIDwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc2ltcGxpZmllZEdlb21ldHJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTaW1wbGlmaWNhdGlvbiBkaWQgbm90IGFjdHVhbGx5IHJlbW92ZSBhbnkgY29vcmRpbmF0ZXMuICBXZSBub3cga25vd1xuICAgICAgLy8gdGhhdCBhbnkgY2FsbHMgdG8gZ2V0U2ltcGxpZmllZEdlb21ldHJ5IHdpdGggYSBzcXVhcmVkVG9sZXJhbmNlIGxlc3NcbiAgICAgIC8vIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGN1cnJlbnQgc3F1YXJlZFRvbGVyYW5jZSB3aWxsIGFsc28gbm90IGhhdmUgYW55XG4gICAgICAvLyBlZmZlY3QuICBUaGlzIGFsbG93cyB1cyB0byBzaG9ydCBjaXJjdWl0IHNpbXBsaWZpY2F0aW9uIChzYXZpbmcgQ1BVXG4gICAgICAvLyBjeWNsZXMpIGFuZCBwcmV2ZW50cyB0aGUgY2FjaGUgb2Ygc2ltcGxpZmllZCBnZW9tZXRyaWVzIGZyb20gZmlsbGluZ1xuICAgICAgLy8gdXAgd2l0aCB1c2VsZXNzIGlkZW50aWNhbCBjb3BpZXMgb2YgdGhpcyBnZW9tZXRyeSAoc2F2aW5nIG1lbW9yeSkuXG4gICAgICB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UgPSBzcXVhcmVkVG9sZXJhbmNlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge1NpbXBsZUdlb21ldHJ5fSBTaW1wbGlmaWVkIGdlb21ldHJ5LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gU3RyaWRlLlxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS5nZXRTdHJpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RyaWRlO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHR9IGxheW91dCBMYXlvdXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLnNldEZsYXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChsYXlvdXQsIGZsYXRDb29yZGluYXRlcykge1xuICAgIHRoaXMuc3RyaWRlID0gZ2V0U3RyaWRlRm9yTGF5b3V0KGxheW91dCk7XG4gICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBmbGF0Q29vcmRpbmF0ZXM7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHshQXJyYXk8Kj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS5zZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9IGxheW91dCBMYXlvdXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbmVzdGluZyBOZXN0aW5nLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLnNldExheW91dCA9IGZ1bmN0aW9uIChsYXlvdXQsIGNvb3JkaW5hdGVzLCBuZXN0aW5nKSB7XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdmFyIHN0cmlkZTtcblxuICAgIGlmIChsYXlvdXQpIHtcbiAgICAgIHN0cmlkZSA9IGdldFN0cmlkZUZvckxheW91dChsYXlvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5lc3Rpbmc7ICsraSkge1xuICAgICAgICBpZiAoY29vcmRpbmF0ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5sYXlvdXQgPSBHZW9tZXRyeUxheW91dC5YWTtcbiAgICAgICAgICB0aGlzLnN0cmlkZSA9IDI7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvb3JkaW5hdGVzID1cbiAgICAgICAgICAvKiogQHR5cGUge0FycmF5fSAqL1xuICAgICAgICAgIGNvb3JkaW5hdGVzWzBdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0cmlkZSA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICAgIGxheW91dCA9IGdldExheW91dEZvclN0cmlkZShzdHJpZGUpO1xuICAgIH1cblxuICAgIHRoaXMubGF5b3V0ID0gbGF5b3V0O1xuICAgIHRoaXMuc3RyaWRlID0gc3RyaWRlO1xuICB9O1xuICAvKipcbiAgICogQXBwbHkgYSB0cmFuc2Zvcm0gZnVuY3Rpb24gdG8gdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBnZW9tZXRyeS5cbiAgICogVGhlIGdlb21ldHJ5IGlzIG1vZGlmaWVkIGluIHBsYWNlLlxuICAgKiBJZiB5b3UgZG8gbm90IHdhbnQgdGhlIGdlb21ldHJ5IG1vZGlmaWVkIGluIHBsYWNlLCBmaXJzdCBgY2xvbmUoKWAgaXQgYW5kXG4gICAqIHRoZW4gdXNlIHRoaXMgZnVuY3Rpb24gb24gdGhlIGNsb25lLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb259IHRyYW5zZm9ybUZuIFRyYW5zZm9ybSBmdW5jdGlvbi5cbiAgICogQ2FsbGVkIHdpdGggYSBmbGF0IGFycmF5IG9mIGdlb21ldHJ5IGNvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLmFwcGx5VHJhbnNmb3JtID0gZnVuY3Rpb24gKHRyYW5zZm9ybUZuKSB7XG4gICAgaWYgKHRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0cmFuc2Zvcm1Gbih0aGlzLmZsYXRDb29yZGluYXRlcywgdGhpcy5mbGF0Q29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJvdGF0ZSB0aGUgZ2VvbWV0cnkgYXJvdW5kIGEgZ2l2ZW4gY29vcmRpbmF0ZS4gVGhpcyBtb2RpZmllcyB0aGUgZ2VvbWV0cnlcbiAgICogY29vcmRpbmF0ZXMgaW4gcGxhY2UuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbmdsZSBSb3RhdGlvbiBhbmdsZSBpbiBjb3VudGVyLWNsb2Nrd2lzZSByYWRpYW5zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYW5jaG9yIFRoZSByb3RhdGlvbiBjZW50ZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTaW1wbGVHZW9tZXRyeS5wcm90b3R5cGUucm90YXRlID0gZnVuY3Rpb24gKGFuZ2xlLCBhbmNob3IpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcblxuICAgIGlmIChmbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHZhciBzdHJpZGUgPSB0aGlzLmdldFN0cmlkZSgpO1xuICAgICAgcm90YXRlKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCBhbmdsZSwgYW5jaG9yLCBmbGF0Q29vcmRpbmF0ZXMpO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2NhbGUgdGhlIGdlb21ldHJ5ICh3aXRoIGFuIG9wdGlvbmFsIG9yaWdpbikuICBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeVxuICAgKiBjb29yZGluYXRlcyBpbiBwbGFjZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN4IFRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeC1kaXJlY3Rpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3N5IFRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeS1kaXJlY3Rpb24gKGRlZmF1bHRzIHRvIHN4KS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBzY2FsZSBvcmlnaW4gKGRlZmF1bHRzIHRvIHRoZSBjZW50ZXJcbiAgICogICAgIG9mIHRoZSBnZW9tZXRyeSBleHRlbnQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU2ltcGxlR2VvbWV0cnkucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKHN4LCBvcHRfc3ksIG9wdF9hbmNob3IpIHtcbiAgICB2YXIgc3kgPSBvcHRfc3k7XG5cbiAgICBpZiAoc3kgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3kgPSBzeDtcbiAgICB9XG5cbiAgICB2YXIgYW5jaG9yID0gb3B0X2FuY2hvcjtcblxuICAgIGlmICghYW5jaG9yKSB7XG4gICAgICBhbmNob3IgPSBnZXRDZW50ZXIodGhpcy5nZXRFeHRlbnQoKSk7XG4gICAgfVxuXG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG5cbiAgICBpZiAoZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB2YXIgc3RyaWRlID0gdGhpcy5nZXRTdHJpZGUoKTtcbiAgICAgIHNjYWxlKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCBzeCwgc3ksIGFuY2hvciwgZmxhdENvb3JkaW5hdGVzKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFRyYW5zbGF0ZSB0aGUgZ2VvbWV0cnkuICBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeSBjb29yZGluYXRlcyBpbiBwbGFjZS4gIElmXG4gICAqIGluc3RlYWQgeW91IHdhbnQgYSBuZXcgZ2VvbWV0cnksIGZpcnN0IGBjbG9uZSgpYCB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGFYIERlbHRhIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVkgRGVsdGEgWS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNpbXBsZUdlb21ldHJ5LnByb3RvdHlwZS50cmFuc2xhdGUgPSBmdW5jdGlvbiAoZGVsdGFYLCBkZWx0YVkpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcblxuICAgIGlmIChmbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHZhciBzdHJpZGUgPSB0aGlzLmdldFN0cmlkZSgpO1xuICAgICAgdHJhbnNsYXRlKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCBkZWx0YVgsIGRlbHRhWSwgZmxhdENvb3JkaW5hdGVzKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gU2ltcGxlR2VvbWV0cnk7XG59KEdlb21ldHJ5KTtcbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHR9IGxheW91dCBMYXlvdXQuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRMYXlvdXRGb3JTdHJpZGUoc3RyaWRlKSB7XG4gIHZhciBsYXlvdXQ7XG5cbiAgaWYgKHN0cmlkZSA9PSAyKSB7XG4gICAgbGF5b3V0ID0gR2VvbWV0cnlMYXlvdXQuWFk7XG4gIH0gZWxzZSBpZiAoc3RyaWRlID09IDMpIHtcbiAgICBsYXlvdXQgPSBHZW9tZXRyeUxheW91dC5YWVo7XG4gIH0gZWxzZSBpZiAoc3RyaWRlID09IDQpIHtcbiAgICBsYXlvdXQgPSBHZW9tZXRyeUxheW91dC5YWVpNO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdH0gKi9cbiAgICBsYXlvdXRcbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHR9IGxheW91dCBMYXlvdXQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFN0cmlkZS5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdHJpZGVGb3JMYXlvdXQobGF5b3V0KSB7XG4gIHZhciBzdHJpZGU7XG5cbiAgaWYgKGxheW91dCA9PSBHZW9tZXRyeUxheW91dC5YWSkge1xuICAgIHN0cmlkZSA9IDI7XG4gIH0gZWxzZSBpZiAobGF5b3V0ID09IEdlb21ldHJ5TGF5b3V0LlhZWiB8fCBsYXlvdXQgPT0gR2VvbWV0cnlMYXlvdXQuWFlNKSB7XG4gICAgc3RyaWRlID0gMztcbiAgfSBlbHNlIGlmIChsYXlvdXQgPT0gR2VvbWV0cnlMYXlvdXQuWFlaTSkge1xuICAgIHN0cmlkZSA9IDQ7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIHN0cmlkZVxuICApO1xufVxuLyoqXG4gKiBAcGFyYW0ge1NpbXBsZUdlb21ldHJ5fSBzaW1wbGVHZW9tZXRyeSBTaW1wbGUgZ2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZGVzdCBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRyYW5zZm9ybWVkIGZsYXQgY29vcmRpbmF0ZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybUdlb20yRChzaW1wbGVHZW9tZXRyeSwgdHJhbnNmb3JtLCBvcHRfZGVzdCkge1xuICB2YXIgZmxhdENvb3JkaW5hdGVzID0gc2ltcGxlR2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG5cbiAgaWYgKCFmbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3RyaWRlID0gc2ltcGxlR2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgcmV0dXJuIHRyYW5zZm9ybTJEKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCB0cmFuc2Zvcm0sIG9wdF9kZXN0KTtcbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgU2ltcGxlR2VvbWV0cnk7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9jbG9zZXN0XG4gKi9cbmltcG9ydCB7IGxlcnAsIHNxdWFyZWREaXN0YW5jZSBhcyBzcXVhcmVkRHggfSBmcm9tICcuLi8uLi9tYXRoLmpzJztcbi8qKlxuICogUmV0dXJucyB0aGUgcG9pbnQgb24gdGhlIDJEIGxpbmUgc2VnbWVudCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0MV0gdG9cbiAqIGZsYXRDb29yZGluYXRlc1tvZmZzZXQyXSB0aGF0IGlzIGNsb3Nlc3QgdG8gdGhlIHBvaW50ICh4LCB5KS4gIEV4dHJhXG4gKiBkaW1lbnNpb25zIGFyZSBsaW5lYXJseSBpbnRlcnBvbGF0ZWQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldDEgT2Zmc2V0IDEuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0MiBPZmZzZXQgMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICovXG5cbmZ1bmN0aW9uIGFzc2lnbkNsb3Nlc3QoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQxLCBvZmZzZXQyLCBzdHJpZGUsIHgsIHksIGNsb3Nlc3RQb2ludCkge1xuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0MV07XG4gIHZhciB5MSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQxICsgMV07XG4gIHZhciBkeCA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQyXSAtIHgxO1xuICB2YXIgZHkgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0MiArIDFdIC0geTE7XG4gIHZhciBvZmZzZXQ7XG5cbiAgaWYgKGR4ID09PSAwICYmIGR5ID09PSAwKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0MTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdCA9ICgoeCAtIHgxKSAqIGR4ICsgKHkgLSB5MSkgKiBkeSkgLyAoZHggKiBkeCArIGR5ICogZHkpO1xuXG4gICAgaWYgKHQgPiAxKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQyO1xuICAgIH0gZWxzZSBpZiAodCA+IDApIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgICAgY2xvc2VzdFBvaW50W2ldID0gbGVycChmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0MSArIGldLCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0MiArIGldLCB0KTtcbiAgICAgIH1cblxuICAgICAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgb2Zmc2V0ID0gb2Zmc2V0MTtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmlkZTsgKytpKSB7XG4gICAgY2xvc2VzdFBvaW50W2ldID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIGldO1xuICB9XG5cbiAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbn1cbi8qKlxuICogUmV0dXJuIHRoZSBzcXVhcmVkIG9mIHRoZSBsYXJnZXN0IGRpc3RhbmNlIGJldHdlZW4gYW55IHBhaXIgb2YgY29uc2VjdXRpdmVcbiAqIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXggTWF4IHNxdWFyZWQgZGVsdGEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1heCBzcXVhcmVkIGRlbHRhLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIG1heFNxdWFyZWREZWx0YShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIG1heCkge1xuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuXG4gIGZvciAob2Zmc2V0ICs9IHN0cmlkZTsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICAgIHZhciBzcXVhcmVkRGVsdGEgPSBzcXVhcmVkRHgoeDEsIHkxLCB4MiwgeTIpO1xuXG4gICAgaWYgKHNxdWFyZWREZWx0YSA+IG1heCkge1xuICAgICAgbWF4ID0gc3F1YXJlZERlbHRhO1xuICAgIH1cblxuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiBtYXg7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4IE1heCBzcXVhcmVkIGRlbHRhLlxuICogQHJldHVybiB7bnVtYmVyfSBNYXggc3F1YXJlZCBkZWx0YS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlNYXhTcXVhcmVkRGVsdGEoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgbWF4KSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIG1heCA9IG1heFNxdWFyZWREZWx0YShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIG1heCk7XG4gICAgb2Zmc2V0ID0gZW5kO1xuICB9XG5cbiAgcmV0dXJuIG1heDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgRW5kc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXggTWF4IHNxdWFyZWQgZGVsdGEuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1heCBzcXVhcmVkIGRlbHRhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtdWx0aUFycmF5TWF4U3F1YXJlZERlbHRhKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlLCBtYXgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG4gICAgbWF4ID0gYXJyYXlNYXhTcXVhcmVkRGVsdGEoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgbWF4KTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gbWF4O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heERlbHRhIE1heCBkZWx0YS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNSaW5nIElzIHJpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF90bXBQb2ludCBUZW1wb3JhcnkgcG9pbnQgb2JqZWN0LlxuICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2lnbkNsb3Nlc3RQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIG1heERlbHRhLCBpc1JpbmcsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlLCBvcHRfdG1wUG9pbnQpIHtcbiAgaWYgKG9mZnNldCA9PSBlbmQpIHtcbiAgICByZXR1cm4gbWluU3F1YXJlZERpc3RhbmNlO1xuICB9XG5cbiAgdmFyIGksIHNxdWFyZWREaXN0YW5jZTtcblxuICBpZiAobWF4RGVsdGEgPT09IDApIHtcbiAgICAvLyBBbGwgcG9pbnRzIGFyZSBpZGVudGljYWwsIHNvIGp1c3QgdGVzdCB0aGUgZmlyc3QgcG9pbnQuXG4gICAgc3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZER4KHgsIHksIGZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0pO1xuXG4gICAgaWYgKHNxdWFyZWREaXN0YW5jZSA8IG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHN0cmlkZTsgKytpKSB7XG4gICAgICAgIGNsb3Nlc3RQb2ludFtpXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBpXTtcbiAgICAgIH1cblxuICAgICAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbiAgICAgIHJldHVybiBzcXVhcmVkRGlzdGFuY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuICB9XG5cbiAgdmFyIHRtcFBvaW50ID0gb3B0X3RtcFBvaW50ID8gb3B0X3RtcFBvaW50IDogW05hTiwgTmFOXTtcbiAgdmFyIGluZGV4ID0gb2Zmc2V0ICsgc3RyaWRlO1xuXG4gIHdoaWxlIChpbmRleCA8IGVuZCkge1xuICAgIGFzc2lnbkNsb3Nlc3QoZmxhdENvb3JkaW5hdGVzLCBpbmRleCAtIHN0cmlkZSwgaW5kZXgsIHN0cmlkZSwgeCwgeSwgdG1wUG9pbnQpO1xuICAgIHNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREeCh4LCB5LCB0bXBQb2ludFswXSwgdG1wUG9pbnRbMV0pO1xuXG4gICAgaWYgKHNxdWFyZWREaXN0YW5jZSA8IG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgICAgbWluU3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZERpc3RhbmNlO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgICAgY2xvc2VzdFBvaW50W2ldID0gdG1wUG9pbnRbaV07XG4gICAgICB9XG5cbiAgICAgIGNsb3Nlc3RQb2ludC5sZW5ndGggPSBzdHJpZGU7XG4gICAgICBpbmRleCArPSBzdHJpZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFNraXAgYWhlYWQgbXVsdGlwbGUgcG9pbnRzLCBiZWNhdXNlIHdlIGtub3cgdGhhdCBhbGwgdGhlIHNraXBwZWRcbiAgICAgIC8vIHBvaW50cyBjYW5ub3QgYmUgYW55IGNsb3NlciB0aGFuIHRoZSBjbG9zZXN0IHBvaW50IHdlIGhhdmUgZm91bmQgc29cbiAgICAgIC8vIGZhci4gIFdlIGtub3cgdGhpcyBiZWNhdXNlIHdlIGtub3cgaG93IGNsb3NlIHRoZSBjdXJyZW50IHBvaW50IGlzLCBob3dcbiAgICAgIC8vIGNsb3NlIHRoZSBjbG9zZXN0IHBvaW50IHdlIGhhdmUgZm91bmQgc28gZmFyIGlzLCBhbmQgdGhlIG1heGltdW1cbiAgICAgIC8vIGRpc3RhbmNlIGJldHdlZW4gY29uc2VjdXRpdmUgcG9pbnRzLiAgRm9yIGV4YW1wbGUsIGlmIHdlJ3JlIGN1cnJlbnRseVxuICAgICAgLy8gYXQgZGlzdGFuY2UgMTAsIHRoZSBiZXN0IHdlJ3ZlIGZvdW5kIHNvIGZhciBpcyAzLCBhbmQgdGhhdCB0aGUgbWF4aW11bVxuICAgICAgLy8gZGlzdGFuY2UgYmV0d2VlbiBjb25zZWN1dGl2ZSBwb2ludHMgaXMgMiwgdGhlbiB3ZSdsbCBuZWVkIHRvIHNraXAgYXRcbiAgICAgIC8vIGxlYXN0ICgxMCAtIDMpIC8gMiA9PSAzIChyb3VuZGVkIGRvd24pIHBvaW50cyB0byBoYXZlIGFueSBjaGFuY2Ugb2ZcbiAgICAgIC8vIGZpbmRpbmcgYSBjbG9zZXIgcG9pbnQuICBXZSB1c2UgTWF0aC5tYXgoLi4uLCAxKSB0byBlbnN1cmUgdGhhdCB3ZVxuICAgICAgLy8gYWx3YXlzIGFkdmFuY2UgYXQgbGVhc3Qgb25lIHBvaW50LCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wLlxuICAgICAgaW5kZXggKz0gc3RyaWRlICogTWF0aC5tYXgoKE1hdGguc3FydChzcXVhcmVkRGlzdGFuY2UpIC0gTWF0aC5zcXJ0KG1pblNxdWFyZWREaXN0YW5jZSkpIC8gbWF4RGVsdGEgfCAwLCAxKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNSaW5nKSB7XG4gICAgLy8gQ2hlY2sgdGhlIGNsb3Npbmcgc2VnbWVudC5cbiAgICBhc3NpZ25DbG9zZXN0KGZsYXRDb29yZGluYXRlcywgZW5kIC0gc3RyaWRlLCBvZmZzZXQsIHN0cmlkZSwgeCwgeSwgdG1wUG9pbnQpO1xuICAgIHNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREeCh4LCB5LCB0bXBQb2ludFswXSwgdG1wUG9pbnRbMV0pO1xuXG4gICAgaWYgKHNxdWFyZWREaXN0YW5jZSA8IG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgICAgbWluU3F1YXJlZERpc3RhbmNlID0gc3F1YXJlZERpc3RhbmNlO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgICAgY2xvc2VzdFBvaW50W2ldID0gdG1wUG9pbnRbaV07XG4gICAgICB9XG5cbiAgICAgIGNsb3Nlc3RQb2ludC5sZW5ndGggPSBzdHJpZGU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhEZWx0YSBNYXggZGVsdGEuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzUmluZyBJcyByaW5nLlxuICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfdG1wUG9pbnQgVGVtcG9yYXJ5IHBvaW50IG9iamVjdC5cbiAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NpZ25DbG9zZXN0QXJyYXlQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBtYXhEZWx0YSwgaXNSaW5nLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSwgb3B0X3RtcFBvaW50KSB7XG4gIHZhciB0bXBQb2ludCA9IG9wdF90bXBQb2ludCA/IG9wdF90bXBQb2ludCA6IFtOYU4sIE5hTl07XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgbWluU3F1YXJlZERpc3RhbmNlID0gYXNzaWduQ2xvc2VzdFBvaW50KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbWF4RGVsdGEsIGlzUmluZywgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UsIHRtcFBvaW50KTtcbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICByZXR1cm4gbWluU3F1YXJlZERpc3RhbmNlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heERlbHRhIE1heCBkZWx0YS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaXNSaW5nIElzIHJpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF90bXBQb2ludCBUZW1wb3JhcnkgcG9pbnQgb2JqZWN0LlxuICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFzc2lnbkNsb3Nlc3RNdWx0aUFycmF5UG9pbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIG1heERlbHRhLCBpc1JpbmcsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlLCBvcHRfdG1wUG9pbnQpIHtcbiAgdmFyIHRtcFBvaW50ID0gb3B0X3RtcFBvaW50ID8gb3B0X3RtcFBvaW50IDogW05hTiwgTmFOXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcbiAgICBtaW5TcXVhcmVkRGlzdGFuY2UgPSBhc3NpZ25DbG9zZXN0QXJyYXlQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBtYXhEZWx0YSwgaXNSaW5nLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSwgdG1wUG9pbnQpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9kZWZsYXRlXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZsYXRlQ29vcmRpbmF0ZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgY29vcmRpbmF0ZSwgc3RyaWRlKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGUubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGZsYXRDb29yZGluYXRlc1tvZmZzZXQrK10gPSBjb29yZGluYXRlW2ldO1xuICB9XG5cbiAgcmV0dXJuIG9mZnNldDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZsYXRlQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGNvb3JkaW5hdGVzLCBzdHJpZGUpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBjb29yZGluYXRlID0gY29vcmRpbmF0ZXNbaV07XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmlkZTsgKytqKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0KytdID0gY29vcmRpbmF0ZVtqXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSBjb29yZGluYXRlc3MgQ29vcmRpbmF0ZXNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfZW5kcyBFbmRzLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRW5kcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmbGF0ZUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGNvb3JkaW5hdGVzcywgc3RyaWRlLCBvcHRfZW5kcykge1xuICB2YXIgZW5kcyA9IG9wdF9lbmRzID8gb3B0X2VuZHMgOiBbXTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAodmFyIGogPSAwLCBqaiA9IGNvb3JkaW5hdGVzcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgdmFyIGVuZCA9IGRlZmxhdGVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgY29vcmRpbmF0ZXNzW2pdLCBzdHJpZGUpO1xuICAgIGVuZHNbaSsrXSA9IGVuZDtcbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICBlbmRzLmxlbmd0aCA9IGk7XG4gIHJldHVybiBlbmRzO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+Pn0gY29vcmRpbmF0ZXNzcyBDb29yZGluYXRlc3NzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+PX0gb3B0X2VuZHNzIEVuZHNzLlxuICogQHJldHVybiB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IEVuZHNzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZsYXRlTXVsdGlDb29yZGluYXRlc0FycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBjb29yZGluYXRlc3NzLCBzdHJpZGUsIG9wdF9lbmRzcykge1xuICB2YXIgZW5kc3MgPSBvcHRfZW5kc3MgPyBvcHRfZW5kc3MgOiBbXTtcbiAgdmFyIGkgPSAwO1xuXG4gIGZvciAodmFyIGogPSAwLCBqaiA9IGNvb3JkaW5hdGVzc3MubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgIHZhciBlbmRzID0gZGVmbGF0ZUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGNvb3JkaW5hdGVzc3Nbal0sIHN0cmlkZSwgZW5kc3NbaV0pO1xuICAgIGVuZHNzW2krK10gPSBlbmRzO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIGVuZHNzLmxlbmd0aCA9IGk7XG4gIHJldHVybiBlbmRzcztcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3NpbXBsaWZ5XG4gKi9cbi8vIEJhc2VkIG9uIHNpbXBsaWZ5LWpzIGh0dHBzOi8vZ2l0aHViLmNvbS9tb3VybmVyL3NpbXBsaWZ5LWpzXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTIsIFZsYWRpbWlyIEFnYWZvbmtpblxuLy8gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbi8vIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuLy9cbi8vICAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbi8vICAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4vL1xuLy8gICAgMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHRcbi8vICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGVcbi8vICAgICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4vL1xuLy8gVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCJcbi8vIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbi8vIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4vLyBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFXG4vLyBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SXG4vLyBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRlxuLy8gU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTXG4vLyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTlxuLy8gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSlcbi8vIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFXG4vLyBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbmltcG9ydCB7IHNxdWFyZWREaXN0YW5jZSwgc3F1YXJlZFNlZ21lbnREaXN0YW5jZSB9IGZyb20gJy4uLy4uL21hdGguanMnO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGhpZ2hRdWFsaXR5IEhpZ2hlc3QgcXVhbGl0eS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9zaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzIFNpbXBsaWZpZWQgZmxhdFxuICogICAgIGNvb3JkaW5hdGVzLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gU2ltcGxpZmllZCBsaW5lIHN0cmluZy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2ltcGxpZnlMaW5lU3RyaW5nKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgaGlnaFF1YWxpdHksIG9wdF9zaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzKSB7XG4gIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gb3B0X3NpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgIT09IHVuZGVmaW5lZCA/IG9wdF9zaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzIDogW107XG5cbiAgaWYgKCFoaWdoUXVhbGl0eSkge1xuICAgIGVuZCA9IHJhZGlhbERpc3RhbmNlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgMCk7XG4gICAgZmxhdENvb3JkaW5hdGVzID0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcztcbiAgICBvZmZzZXQgPSAwO1xuICAgIHN0cmlkZSA9IDI7XG4gIH1cblxuICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRvdWdsYXNQZXVja2VyKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgMCk7XG4gIHJldHVybiBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEByZXR1cm4ge251bWJlcn0gU2ltcGxpZmllZCBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRvdWdsYXNQZXVja2VyKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCkge1xuICB2YXIgbiA9IChlbmQgLSBvZmZzZXQpIC8gc3RyaWRlO1xuXG4gIGlmIChuIDwgMykge1xuICAgIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICAgIH1cblxuICAgIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xuICB9XG4gIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cblxuXG4gIHZhciBtYXJrZXJzID0gbmV3IEFycmF5KG4pO1xuICBtYXJrZXJzWzBdID0gMTtcbiAgbWFya2Vyc1tuIC0gMV0gPSAxO1xuICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG5cbiAgdmFyIHN0YWNrID0gW29mZnNldCwgZW5kIC0gc3RyaWRlXTtcbiAgdmFyIGluZGV4ID0gMDtcblxuICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgIHZhciBsYXN0ID0gc3RhY2sucG9wKCk7XG4gICAgdmFyIGZpcnN0ID0gc3RhY2sucG9wKCk7XG4gICAgdmFyIG1heFNxdWFyZWREaXN0YW5jZSA9IDA7XG4gICAgdmFyIHgxID0gZmxhdENvb3JkaW5hdGVzW2ZpcnN0XTtcbiAgICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbZmlyc3QgKyAxXTtcbiAgICB2YXIgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbbGFzdF07XG4gICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW2xhc3QgKyAxXTtcblxuICAgIGZvciAodmFyIGkgPSBmaXJzdCArIHN0cmlkZTsgaSA8IGxhc3Q7IGkgKz0gc3RyaWRlKSB7XG4gICAgICB2YXIgeCA9IGZsYXRDb29yZGluYXRlc1tpXTtcbiAgICAgIHZhciB5ID0gZmxhdENvb3JkaW5hdGVzW2kgKyAxXTtcbiAgICAgIHZhciBzcXVhcmVkRGlzdGFuY2VfMSA9IHNxdWFyZWRTZWdtZW50RGlzdGFuY2UoeCwgeSwgeDEsIHkxLCB4MiwgeTIpO1xuXG4gICAgICBpZiAoc3F1YXJlZERpc3RhbmNlXzEgPiBtYXhTcXVhcmVkRGlzdGFuY2UpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBtYXhTcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRGlzdGFuY2VfMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF4U3F1YXJlZERpc3RhbmNlID4gc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgICAgbWFya2Vyc1soaW5kZXggLSBvZmZzZXQpIC8gc3RyaWRlXSA9IDE7XG5cbiAgICAgIGlmIChmaXJzdCArIHN0cmlkZSA8IGluZGV4KSB7XG4gICAgICAgIHN0YWNrLnB1c2goZmlyc3QsIGluZGV4KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4ICsgc3RyaWRlIDwgbGFzdCkge1xuICAgICAgICBzdGFjay5wdXNoKGluZGV4LCBsYXN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGlmIChtYXJrZXJzW2ldKSB7XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgaSAqIHN0cmlkZV07XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgaSAqIHN0cmlkZSArIDFdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEVuZHMgU2ltcGxpZmllZCBlbmRzLlxuICogQHJldHVybiB7bnVtYmVyfSBTaW1wbGlmaWVkIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG91Z2xhc1BldWNrZXJBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kcykge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICBzaW1wbGlmaWVkT2Zmc2V0ID0gZG91Z2xhc1BldWNrZXIoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0KTtcbiAgICBzaW1wbGlmaWVkRW5kcy5wdXNoKHNpbXBsaWZpZWRPZmZzZXQpO1xuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IHNpbXBsaWZpZWRFbmRzcyBTaW1wbGlmaWVkIGVuZHNzLlxuICogQHJldHVybiB7bnVtYmVyfSBTaW1wbGlmaWVkIG9mZnNldC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZG91Z2xhc1BldWNrZXJNdWx0aUFycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kc3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzID0gW107XG4gICAgc2ltcGxpZmllZE9mZnNldCA9IGRvdWdsYXNQZXVja2VyQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCwgc2ltcGxpZmllZEVuZHMpO1xuICAgIHNpbXBsaWZpZWRFbmRzcy5wdXNoKHNpbXBsaWZpZWRFbmRzKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzIFNpbXBsaWZpZWQgZmxhdFxuICogICAgIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpbXBsaWZpZWRPZmZzZXQgU2ltcGxpZmllZCBvZmZzZXQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByYWRpYWxEaXN0YW5jZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQpIHtcbiAgaWYgKGVuZCA8PSBvZmZzZXQgKyBzdHJpZGUpIHtcbiAgICAvLyB6ZXJvIG9yIG9uZSBwb2ludCwgbm8gc2ltcGxpZmljYXRpb24gcG9zc2libGUsIHNvIGNvcHkgYW5kIHJldHVyblxuICAgIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICAgIH1cblxuICAgIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xuICB9XG5cbiAgdmFyIHgxID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gIHZhciB5MSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTsgLy8gY29weSBmaXJzdCBwb2ludFxuXG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHgxO1xuICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB5MTtcbiAgdmFyIHgyID0geDE7XG4gIHZhciB5MiA9IHkxO1xuXG4gIGZvciAob2Zmc2V0ICs9IHN0cmlkZTsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB5MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTtcblxuICAgIGlmIChzcXVhcmVkRGlzdGFuY2UoeDEsIHkxLCB4MiwgeTIpID4gc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgICAgLy8gY29weSBwb2ludCBhdCBvZmZzZXRcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHgyO1xuICAgICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geTI7XG4gICAgICB4MSA9IHgyO1xuICAgICAgeTEgPSB5MjtcbiAgICB9XG4gIH1cblxuICBpZiAoeDIgIT0geDEgfHwgeTIgIT0geTEpIHtcbiAgICAvLyBjb3B5IGxhc3QgcG9pbnRcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB4MjtcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB5MjtcbiAgfVxuXG4gIHJldHVybiBzaW1wbGlmaWVkT2Zmc2V0O1xufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUuXG4gKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAqIEByZXR1cm4ge251bWJlcn0gUm91bmRlZCB2YWx1ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc25hcCh2YWx1ZSwgdG9sZXJhbmNlKSB7XG4gIHJldHVybiB0b2xlcmFuY2UgKiBNYXRoLnJvdW5kKHZhbHVlIC8gdG9sZXJhbmNlKTtcbn1cbi8qKlxuICogU2ltcGxpZmllcyBhIGxpbmUgc3RyaW5nIHVzaW5nIGFuIGFsZ29yaXRobSBkZXNpZ25lZCBieSBUaW0gU2NoYXViLlxuICogQ29vcmRpbmF0ZXMgYXJlIHNuYXBwZWQgdG8gdGhlIG5lYXJlc3QgdmFsdWUgaW4gYSB2aXJ0dWFsIGdyaWQgYW5kXG4gKiBjb25zZWN1dGl2ZSBkdXBsaWNhdGUgY29vcmRpbmF0ZXMgYXJlIGRpc2NhcmRlZC4gIFRoaXMgZWZmZWN0aXZlbHkgcHJlc2VydmVzXG4gKiB0b3BvbG9neSBhcyB0aGUgc2ltcGxpZmljYXRpb24gb2YgYW55IHN1YnNlY3Rpb24gb2YgYSBsaW5lIHN0cmluZyBpc1xuICogaW5kZXBlbmRlbnQgb2YgdGhlIHJlc3Qgb2YgdGhlIGxpbmUgc3RyaW5nLiAgVGhpcyBtZWFucyB0aGF0LCBmb3IgZXhhbXBsZXMsXG4gKiB0aGUgY29tbW9uIGVkZ2UgYmV0d2VlbiB0d28gcG9seWdvbnMgd2lsbCBiZSBzaW1wbGlmaWVkIHRvIHRoZSBzYW1lIGxpbmVcbiAqIHN0cmluZyBpbmRlcGVuZGVudGx5IGluIGJvdGggcG9seWdvbnMuICBUaGlzIGltcGxlbWVudGF0aW9uIHVzZXMgYSBzaW5nbGVcbiAqIHBhc3Mgb3ZlciB0aGUgY29vcmRpbmF0ZXMgYW5kIGVsaW1pbmF0ZXMgaW50ZXJtZWRpYXRlIGNvbGxpbmVhciBwb2ludHMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgU2ltcGxpZmllZCBmbGF0XG4gKiAgICAgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2ltcGxpZmllZE9mZnNldCBTaW1wbGlmaWVkIG9mZnNldC5cbiAqIEByZXR1cm4ge251bWJlcn0gU2ltcGxpZmllZCBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHF1YW50aXplKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgdG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0KSB7XG4gIC8vIGRvIG5vdGhpbmcgaWYgdGhlIGxpbmUgaXMgZW1wdHlcbiAgaWYgKG9mZnNldCA9PSBlbmQpIHtcbiAgICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbiAgfSAvLyBzbmFwIHRoZSBmaXJzdCBjb29yZGluYXRlIChQMSlcblxuXG4gIHZhciB4MSA9IHNuYXAoZmxhdENvb3JkaW5hdGVzW29mZnNldF0sIHRvbGVyYW5jZSk7XG4gIHZhciB5MSA9IHNuYXAoZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdLCB0b2xlcmFuY2UpO1xuICBvZmZzZXQgKz0gc3RyaWRlOyAvLyBhZGQgdGhlIGZpcnN0IGNvb3JkaW5hdGUgdG8gdGhlIG91dHB1dFxuXG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHgxO1xuICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB5MTsgLy8gZmluZCB0aGUgbmV4dCBjb29yZGluYXRlIHRoYXQgZG9lcyBub3Qgc25hcCB0byB0aGUgc2FtZSB2YWx1ZSBhcyB0aGUgZmlyc3RcbiAgLy8gY29vcmRpbmF0ZSAoUDIpXG5cbiAgdmFyIHgyLCB5MjtcblxuICBkbyB7XG4gICAgeDIgPSBzbmFwKGZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCB0b2xlcmFuY2UpO1xuICAgIHkyID0gc25hcChmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0sIHRvbGVyYW5jZSk7XG4gICAgb2Zmc2V0ICs9IHN0cmlkZTtcblxuICAgIGlmIChvZmZzZXQgPT0gZW5kKSB7XG4gICAgICAvLyBhbGwgY29vcmRpbmF0ZXMgc25hcCB0byB0aGUgc2FtZSB2YWx1ZSwgdGhlIGxpbmUgY29sbGFwc2VzIHRvIGEgcG9pbnRcbiAgICAgIC8vIHB1c2ggdGhlIGxhc3Qgc25hcHBlZCB2YWx1ZSBhbnl3YXkgdG8gZW5zdXJlIHRoYXQgdGhlIG91dHB1dCBjb250YWluc1xuICAgICAgLy8gYXQgbGVhc3QgdHdvIHBvaW50c1xuICAgICAgLy8gRklYTUUgc2hvdWxkIHdlIHJlYWxseSByZXR1cm4gYXQgbGVhc3QgdHdvIHBvaW50cyBhbnl3YXk/XG4gICAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzW3NpbXBsaWZpZWRPZmZzZXQrK10gPSB4MjtcbiAgICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHkyO1xuICAgICAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG4gICAgfVxuICB9IHdoaWxlICh4MiA9PSB4MSAmJiB5MiA9PSB5MSk7XG5cbiAgd2hpbGUgKG9mZnNldCA8IGVuZCkge1xuICAgIC8vIHNuYXAgdGhlIG5leHQgY29vcmRpbmF0ZSAoUDMpXG4gICAgdmFyIHgzID0gc25hcChmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XSwgdG9sZXJhbmNlKTtcbiAgICB2YXIgeTMgPSBzbmFwKGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXSwgdG9sZXJhbmNlKTtcbiAgICBvZmZzZXQgKz0gc3RyaWRlOyAvLyBza2lwIFAzIGlmIGl0IGlzIGVxdWFsIHRvIFAyXG5cbiAgICBpZiAoeDMgPT0geDIgJiYgeTMgPT0geTIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gLy8gY2FsY3VsYXRlIHRoZSBkZWx0YSBiZXR3ZWVuIFAxIGFuZCBQMlxuXG5cbiAgICB2YXIgZHgxID0geDIgLSB4MTtcbiAgICB2YXIgZHkxID0geTIgLSB5MTsgLy8gY2FsY3VsYXRlIHRoZSBkZWx0YSBiZXR3ZWVuIFAzIGFuZCBQMVxuXG4gICAgdmFyIGR4MiA9IHgzIC0geDE7XG4gICAgdmFyIGR5MiA9IHkzIC0geTE7IC8vIGlmIFAxLCBQMiwgYW5kIFAzIGFyZSBjb2xpbmVhciBhbmQgUDMgaXMgZnVydGhlciBmcm9tIFAxIHRoYW4gUDIgaXMgZnJvbVxuICAgIC8vIFAxIGluIHRoZSBzYW1lIGRpcmVjdGlvbiB0aGVuIFAyIGlzIG9uIHRoZSBzdHJhaWdodCBsaW5lIGJldHdlZW4gUDEgYW5kXG4gICAgLy8gUDNcblxuICAgIGlmIChkeDEgKiBkeTIgPT0gZHkxICogZHgyICYmIChkeDEgPCAwICYmIGR4MiA8IGR4MSB8fCBkeDEgPT0gZHgyIHx8IGR4MSA+IDAgJiYgZHgyID4gZHgxKSAmJiAoZHkxIDwgMCAmJiBkeTIgPCBkeTEgfHwgZHkxID09IGR5MiB8fCBkeTEgPiAwICYmIGR5MiA+IGR5MSkpIHtcbiAgICAgIC8vIGRpc2NhcmQgUDIgYW5kIHNldCBQMiA9IFAzXG4gICAgICB4MiA9IHgzO1xuICAgICAgeTIgPSB5MztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gLy8gZWl0aGVyIFAxLCBQMiwgYW5kIFAzIGFyZSBub3QgY29saW5lYXIsIG9yIHRoZXkgYXJlIGNvbGluZWFyIGJ1dCBQMyBpc1xuICAgIC8vIGJldHdlZW4gUDMgYW5kIFAxIG9yIG9uIHRoZSBvcHBvc2l0ZSBoYWxmIG9mIHRoZSBsaW5lIHRvIFAyLiAgYWRkIFAyLFxuICAgIC8vIGFuZCBjb250aW51ZSB3aXRoIFAxID0gUDIgYW5kIFAyID0gUDNcblxuXG4gICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geDI7XG4gICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geTI7XG4gICAgeDEgPSB4MjtcbiAgICB5MSA9IHkyO1xuICAgIHgyID0geDM7XG4gICAgeTIgPSB5MztcbiAgfSAvLyBhZGQgdGhlIGxhc3QgcG9pbnQgKFAyKVxuXG5cbiAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlc1tzaW1wbGlmaWVkT2Zmc2V0KytdID0geDI7XG4gIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXNbc2ltcGxpZmllZE9mZnNldCsrXSA9IHkyO1xuICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzIFNpbXBsaWZpZWQgZmxhdFxuICogICAgIGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpbXBsaWZpZWRPZmZzZXQgU2ltcGxpZmllZCBvZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHNpbXBsaWZpZWRFbmRzIFNpbXBsaWZpZWQgZW5kcy5cbiAqIEByZXR1cm4ge251bWJlcn0gU2ltcGxpZmllZCBvZmZzZXQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHF1YW50aXplQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgdG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBzaW1wbGlmaWVkT2Zmc2V0LCBzaW1wbGlmaWVkRW5kcykge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICBzaW1wbGlmaWVkT2Zmc2V0ID0gcXVhbnRpemUoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCB0b2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIHNpbXBsaWZpZWRPZmZzZXQpO1xuICAgIHNpbXBsaWZpZWRFbmRzLnB1c2goc2ltcGxpZmllZE9mZnNldCk7XG4gICAgb2Zmc2V0ID0gZW5kO1xuICB9XG5cbiAgcmV0dXJuIHNpbXBsaWZpZWRPZmZzZXQ7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEVuZHNzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyBTaW1wbGlmaWVkIGZsYXRcbiAqICAgICBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzaW1wbGlmaWVkT2Zmc2V0IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gc2ltcGxpZmllZEVuZHNzIFNpbXBsaWZpZWQgZW5kc3MuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFNpbXBsaWZpZWQgb2Zmc2V0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBxdWFudGl6ZU11bHRpQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIHRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCwgc2ltcGxpZmllZEVuZHNzKSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgIHZhciBzaW1wbGlmaWVkRW5kcyA9IFtdO1xuICAgIHNpbXBsaWZpZWRPZmZzZXQgPSBxdWFudGl6ZUFycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIHRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgc2ltcGxpZmllZE9mZnNldCwgc2ltcGxpZmllZEVuZHMpO1xuICAgIHNpbXBsaWZpZWRFbmRzcy5wdXNoKHNpbXBsaWZpZWRFbmRzKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gc2ltcGxpZmllZE9mZnNldDtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2luZmxhdGVcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT49fSBvcHRfY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBDb29yZGluYXRlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZmxhdGVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIG9wdF9jb29yZGluYXRlcykge1xuICB2YXIgY29vcmRpbmF0ZXMgPSBvcHRfY29vcmRpbmF0ZXMgIT09IHVuZGVmaW5lZCA/IG9wdF9jb29yZGluYXRlcyA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IG9mZnNldDsgaiA8IGVuZDsgaiArPSBzdHJpZGUpIHtcbiAgICBjb29yZGluYXRlc1tpKytdID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKGosIGogKyBzdHJpZGUpO1xuICB9XG5cbiAgY29vcmRpbmF0ZXMubGVuZ3RoID0gaTtcbiAgcmV0dXJuIGNvb3JkaW5hdGVzO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj19IG9wdF9jb29yZGluYXRlc3MgQ29vcmRpbmF0ZXNzLlxuICogQHJldHVybiB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IENvb3JkaW5hdGVzcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgb3B0X2Nvb3JkaW5hdGVzcykge1xuICB2YXIgY29vcmRpbmF0ZXNzID0gb3B0X2Nvb3JkaW5hdGVzcyAhPT0gdW5kZWZpbmVkID8gb3B0X2Nvb3JkaW5hdGVzcyA6IFtdO1xuICB2YXIgaSA9IDA7XG5cbiAgZm9yICh2YXIgaiA9IDAsIGpqID0gZW5kcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgdmFyIGVuZCA9IGVuZHNbal07XG4gICAgY29vcmRpbmF0ZXNzW2krK10gPSBpbmZsYXRlQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBjb29yZGluYXRlc3NbaV0pO1xuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIGNvb3JkaW5hdGVzcy5sZW5ndGggPSBpO1xuICByZXR1cm4gY29vcmRpbmF0ZXNzO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj49fSBvcHRfY29vcmRpbmF0ZXNzc1xuICogICAgIENvb3JkaW5hdGVzc3MuXG4gKiBAcmV0dXJuIHtBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj59IENvb3JkaW5hdGVzc3MuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGluZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIG9wdF9jb29yZGluYXRlc3NzKSB7XG4gIHZhciBjb29yZGluYXRlc3NzID0gb3B0X2Nvb3JkaW5hdGVzc3MgIT09IHVuZGVmaW5lZCA/IG9wdF9jb29yZGluYXRlc3NzIDogW107XG4gIHZhciBpID0gMDtcblxuICBmb3IgKHZhciBqID0gMCwgamogPSBlbmRzcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tqXTtcbiAgICBjb29yZGluYXRlc3NzW2krK10gPSBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBjb29yZGluYXRlc3NzW2ldKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICBjb29yZGluYXRlc3NzLmxlbmd0aCA9IGk7XG4gIHJldHVybiBjb29yZGluYXRlc3NzO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvYXJlYVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEByZXR1cm4ge251bWJlcn0gQXJlYS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmcoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIHZhciB0d2ljZUFyZWEgPSAwO1xuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlXTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZSArIDFdO1xuXG4gIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICB2YXIgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgdHdpY2VBcmVhICs9IHkxICogeDIgLSB4MSAqIHkyO1xuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiB0d2ljZUFyZWEgLyAyO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBBcmVhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5ncyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlKSB7XG4gIHZhciBhcmVhID0gMDtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICBhcmVhICs9IGxpbmVhclJpbmcoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKTtcbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICByZXR1cm4gYXJlYTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgRW5kc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEByZXR1cm4ge251bWJlcn0gQXJlYS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyUmluZ3NzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlKSB7XG4gIHZhciBhcmVhID0gMDtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcbiAgICBhcmVhICs9IGxpbmVhclJpbmdzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUpO1xuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBhcmVhO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9MaW5lYXJSaW5nXG4gKi9cblxuXG5pbXBvcnQgR2VvbWV0cnlMYXlvdXQgZnJvbSAnLi9HZW9tZXRyeUxheW91dC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFzc2lnbkNsb3Nlc3RQb2ludCwgbWF4U3F1YXJlZERlbHRhIH0gZnJvbSAnLi9mbGF0L2Nsb3Nlc3QuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGRvdWdsYXNQZXVja2VyIH0gZnJvbSAnLi9mbGF0L3NpbXBsaWZ5LmpzJztcbmltcG9ydCB7IGluZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9pbmZsYXRlLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmcgYXMgbGluZWFyUmluZ0FyZWEgfSBmcm9tICcuL2ZsYXQvYXJlYS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIExpbmVhciByaW5nIGdlb21ldHJ5LiBPbmx5IHVzZWQgYXMgcGFydCBvZiBwb2x5Z29uOyBjYW5ub3QgYmUgcmVuZGVyZWRcbiAqIG9uIGl0cyBvd24uXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBMaW5lYXJSaW5nID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKExpbmVhclJpbmcsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqICAgICBGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIExpbmVhclJpbmcoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWF4RGVsdGFfID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSAtMTtcblxuICAgIGlmIChvcHRfbGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBNYWtlIGEgY29tcGxldGUgY29weSBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4geyFMaW5lYXJSaW5nfSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVhclJpbmcucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgTGluZWFyUmluZyh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSgpLCB0aGlzLmxheW91dCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRYWSA9IGZ1bmN0aW9uICh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgIGlmIChtaW5TcXVhcmVkRGlzdGFuY2UgPCBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkodGhpcy5nZXRFeHRlbnQoKSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLm1heERlbHRhXyA9IE1hdGguc3FydChtYXhTcXVhcmVkRGVsdGEodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIDApKTtcbiAgICAgIHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzc2lnbkNsb3Nlc3RQb2ludCh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgdGhpcy5tYXhEZWx0YV8sIHRydWUsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgYXJlYSBvZiB0aGUgbGluZWFyIHJpbmcgb24gcHJvamVjdGVkIHBsYW5lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEgKG9uIHByb2plY3RlZCBwbGFuZSkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5nZXRBcmVhID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBsaW5lYXJSaW5nQXJlYSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBsaW5lYXIgcmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gQ29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaW5mbGF0ZUNvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzcXVhcmVkVG9sZXJhbmNlIFNxdWFyZWQgdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtMaW5lYXJSaW5nfSBTaW1wbGlmaWVkIExpbmVhclJpbmcuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5nZXRTaW1wbGlmaWVkR2VvbWV0cnlJbnRlcm5hbCA9IGZ1bmN0aW9uIChzcXVhcmVkVG9sZXJhbmNlKSB7XG4gICAgdmFyIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRvdWdsYXNQZXVja2VyKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlLCBzcXVhcmVkVG9sZXJhbmNlLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCAwKTtcbiAgICByZXR1cm4gbmV3IExpbmVhclJpbmcoc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFkpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0eXBlIG9mIHRoaXMgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vR2VvbWV0cnlUeXBlLmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5IHR5cGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBHZW9tZXRyeVR5cGUuTElORUFSX1JJTkc7XG4gIH07XG4gIC8qKlxuICAgKiBUZXN0IGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIHBhc3NlZCBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZWFyUmluZy5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBsaW5lYXIgcmluZy5cbiAgICogQHBhcmFtIHshQXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lYXJSaW5nLnByb3RvdHlwZS5zZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHRoaXMuc2V0TGF5b3V0KG9wdF9sYXlvdXQsIGNvb3JkaW5hdGVzLCAxKTtcblxuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgfVxuXG4gICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZGVmbGF0ZUNvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCBjb29yZGluYXRlcywgdGhpcy5zdHJpZGUpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuXG4gIHJldHVybiBMaW5lYXJSaW5nO1xufShTaW1wbGVHZW9tZXRyeSk7XG5cbmV4cG9ydCBkZWZhdWx0IExpbmVhclJpbmc7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL1BvaW50XG4gKi9cblxuXG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGNvbnRhaW5zWFksIGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGUgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZGVmbGF0ZUNvb3JkaW5hdGUgfSBmcm9tICcuL2ZsYXQvZGVmbGF0ZS5qcyc7XG5pbXBvcnQgeyBzcXVhcmVkRGlzdGFuY2UgYXMgc3F1YXJlZER4IH0gZnJvbSAnLi4vbWF0aC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFBvaW50IGdlb21ldHJ5LlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgUG9pbnQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUG9pbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUG9pbnQoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBNYWtlIGEgY29tcGxldGUgY29weSBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4geyFQb2ludH0gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2ludC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHBvaW50ID0gbmV3IFBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgICBwb2ludC5hcHBseVByb3BlcnRpZXModGhpcyk7XG4gICAgcmV0dXJuIHBvaW50O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIHZhciBzcXVhcmVkRGlzdGFuY2UgPSBzcXVhcmVkRHgoeCwgeSwgZmxhdENvb3JkaW5hdGVzWzBdLCBmbGF0Q29vcmRpbmF0ZXNbMV0pO1xuXG4gICAgaWYgKHNxdWFyZWREaXN0YW5jZSA8IG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgICAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmlkZTsgKytpKSB7XG4gICAgICAgIGNsb3Nlc3RQb2ludFtpXSA9IGZsYXRDb29yZGluYXRlc1tpXTtcbiAgICAgIH1cblxuICAgICAgY2xvc2VzdFBvaW50Lmxlbmd0aCA9IHN0cmlkZTtcbiAgICAgIHJldHVybiBzcXVhcmVkRGlzdGFuY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBjb29yZGluYXRlIG9mIHRoZSBwb2ludC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvaW50LnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gIXRoaXMuZmxhdENvb3JkaW5hdGVzID8gW10gOiB0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSgpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLmNvbXB1dGVFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGUodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIGV4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvaW50LnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBHZW9tZXRyeVR5cGUuUE9JTlQ7XG4gIH07XG4gIC8qKlxuICAgKiBUZXN0IGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIHBhc3NlZCBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGNvbnRhaW5zWFkoZXh0ZW50LCB0aGlzLmZsYXRDb29yZGluYXRlc1swXSwgdGhpcy5mbGF0Q29vcmRpbmF0ZXNbMV0pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHshQXJyYXk8Kj59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9pbnQucHJvdG90eXBlLnNldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KSB7XG4gICAgdGhpcy5zZXRMYXlvdXQob3B0X2xheW91dCwgY29vcmRpbmF0ZXMsIDApO1xuXG4gICAgaWYgKCF0aGlzLmZsYXRDb29yZGluYXRlcykge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICB9XG5cbiAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBkZWZsYXRlQ29vcmRpbmF0ZSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gUG9pbnQ7XG59KFNpbXBsZUdlb21ldHJ5KTtcblxuZXhwb3J0IGRlZmF1bHQgUG9pbnQ7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9jb250YWluc1xuICovXG5pbXBvcnQgeyBmb3JFYWNoQ29ybmVyIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zIGV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyUmluZ0NvbnRhaW5zRXh0ZW50KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZXh0ZW50KSB7XG4gIHZhciBvdXRzaWRlID0gZm9yRWFjaENvcm5lcihleHRlbnQsXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucyAoeCwgeSkuXG4gICAqL1xuICBmdW5jdGlvbiAoY29vcmRpbmF0ZSkge1xuICAgIHJldHVybiAhbGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdKTtcbiAgfSk7XG4gIHJldHVybiAhb3V0c2lkZTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgKHgsIHkpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHgsIHkpIHtcbiAgLy8gaHR0cDovL2dlb21hbGdvcml0aG1zLmNvbS9hMDMtX2luY2x1c2lvbi5odG1sXG4gIC8vIENvcHlyaWdodCAyMDAwIHNvZnRTdXJmZXIsIDIwMTIgRGFuIFN1bmRheVxuICAvLyBUaGlzIGNvZGUgbWF5IGJlIGZyZWVseSB1c2VkIGFuZCBtb2RpZmllZCBmb3IgYW55IHB1cnBvc2VcbiAgLy8gcHJvdmlkaW5nIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlIGlzIGluY2x1ZGVkIHdpdGggaXQuXG4gIC8vIFNvZnRTdXJmZXIgbWFrZXMgbm8gd2FycmFudHkgZm9yIHRoaXMgY29kZSwgYW5kIGNhbm5vdCBiZSBoZWxkXG4gIC8vIGxpYWJsZSBmb3IgYW55IHJlYWwgb3IgaW1hZ2luZWQgZGFtYWdlIHJlc3VsdGluZyBmcm9tIGl0cyB1c2UuXG4gIC8vIFVzZXJzIG9mIHRoaXMgY29kZSBtdXN0IHZlcmlmeSBjb3JyZWN0bmVzcyBmb3IgdGhlaXIgYXBwbGljYXRpb24uXG4gIHZhciB3biA9IDA7XG4gIHZhciB4MSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGVdO1xuICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlICsgMV07XG5cbiAgZm9yICg7IG9mZnNldCA8IGVuZDsgb2Zmc2V0ICs9IHN0cmlkZSkge1xuICAgIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgIHZhciB5MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTtcblxuICAgIGlmICh5MSA8PSB5KSB7XG4gICAgICBpZiAoeTIgPiB5ICYmICh4MiAtIHgxKSAqICh5IC0geTEpIC0gKHggLSB4MSkgKiAoeTIgLSB5MSkgPiAwKSB7XG4gICAgICAgIHduKys7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh5MiA8PSB5ICYmICh4MiAtIHgxKSAqICh5IC0geTEpIC0gKHggLSB4MSkgKiAoeTIgLSB5MSkgPCAwKSB7XG4gICAgICB3bi0tO1xuICAgIH1cblxuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiB3biAhPT0gMDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgKHgsIHkpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgeCwgeSkge1xuICBpZiAoZW5kcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoIWxpbmVhclJpbmdDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzWzBdLCBzdHJpZGUsIHgsIHkpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDEsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgaWYgKGxpbmVhclJpbmdDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgZW5kc1tpIC0gMV0sIGVuZHNbaV0sIHN0cmlkZSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgRW5kc3MuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgKHgsIHkpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc3NDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzcywgc3RyaWRlLCB4LCB5KSB7XG4gIGlmIChlbmRzcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcblxuICAgIGlmIChsaW5lYXJSaW5nc0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2ludGVyaW9ycG9pbnRcbiAqL1xuaW1wb3J0IHsgbGluZWFyUmluZ3NDb250YWluc1hZIH0gZnJvbSAnLi9jb250YWlucy5qcyc7XG5pbXBvcnQgeyBudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uIH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuLyoqXG4gKiBDYWxjdWxhdGVzIGEgcG9pbnQgdGhhdCBpcyBsaWtlbHkgdG8gbGllIGluIHRoZSBpbnRlcmlvciBvZiB0aGUgbGluZWFyIHJpbmdzLlxuICogSW5zcGlyZWQgYnkgSlRTJ3MgY29tLnZpdmlkc29sdXRpb25zLmp0cy5nZW9tLkdlb21ldHJ5I2dldEludGVyaW9yUG9pbnQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q2VudGVycyBGbGF0IGNlbnRlcnMuXG4gKiBAcGFyYW0ge251bWJlcn0gZmxhdENlbnRlcnNPZmZzZXQgRmxhdCBjZW50ZXIgb2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2Rlc3QgRGVzdGluYXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBEZXN0aW5hdGlvbiBwb2ludCBhcyBYWU0gY29vcmRpbmF0ZSwgd2hlcmUgTSBpcyB0aGVcbiAqIGxlbmd0aCBvZiB0aGUgaG9yaXpvbnRhbCBpbnRlcnNlY3Rpb24gdGhhdCB0aGUgcG9pbnQgYmVsb25ncyB0by5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJpb3JQb2ludE9mQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgZmxhdENlbnRlcnMsIGZsYXRDZW50ZXJzT2Zmc2V0LCBvcHRfZGVzdCkge1xuICB2YXIgaSwgaWksIHgsIHgxLCB4MiwgeTEsIHkyO1xuICB2YXIgeSA9IGZsYXRDZW50ZXJzW2ZsYXRDZW50ZXJzT2Zmc2V0ICsgMV07XG4gIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cblxuICB2YXIgaW50ZXJzZWN0aW9ucyA9IFtdOyAvLyBDYWxjdWxhdGUgaW50ZXJzZWN0aW9ucyB3aXRoIHRoZSBob3Jpem9udGFsIGxpbmVcblxuICBmb3IgKHZhciByID0gMCwgcnIgPSBlbmRzLmxlbmd0aDsgciA8IHJyOyArK3IpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tyXTtcbiAgICB4MSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGVdO1xuICAgIHkxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZSArIDFdO1xuXG4gICAgZm9yIChpID0gb2Zmc2V0OyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgICAgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbaV07XG4gICAgICB5MiA9IGZsYXRDb29yZGluYXRlc1tpICsgMV07XG5cbiAgICAgIGlmICh5IDw9IHkxICYmIHkyIDw9IHkgfHwgeTEgPD0geSAmJiB5IDw9IHkyKSB7XG4gICAgICAgIHggPSAoeSAtIHkxKSAvICh5MiAtIHkxKSAqICh4MiAtIHgxKSArIHgxO1xuICAgICAgICBpbnRlcnNlY3Rpb25zLnB1c2goeCk7XG4gICAgICB9XG5cbiAgICAgIHgxID0geDI7XG4gICAgICB5MSA9IHkyO1xuICAgIH1cbiAgfSAvLyBGaW5kIHRoZSBsb25nZXN0IHNlZ21lbnQgb2YgdGhlIGhvcml6b250YWwgbGluZSB0aGF0IGhhcyBpdHMgY2VudGVyIHBvaW50XG4gIC8vIGluc2lkZSB0aGUgbGluZWFyIHJpbmcuXG5cblxuICB2YXIgcG9pbnRYID0gTmFOO1xuICB2YXIgbWF4U2VnbWVudExlbmd0aCA9IC1JbmZpbml0eTtcbiAgaW50ZXJzZWN0aW9ucy5zb3J0KG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24pO1xuICB4MSA9IGludGVyc2VjdGlvbnNbMF07XG5cbiAgZm9yIChpID0gMSwgaWkgPSBpbnRlcnNlY3Rpb25zLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB4MiA9IGludGVyc2VjdGlvbnNbaV07XG4gICAgdmFyIHNlZ21lbnRMZW5ndGggPSBNYXRoLmFicyh4MiAtIHgxKTtcblxuICAgIGlmIChzZWdtZW50TGVuZ3RoID4gbWF4U2VnbWVudExlbmd0aCkge1xuICAgICAgeCA9ICh4MSArIHgyKSAvIDI7XG5cbiAgICAgIGlmIChsaW5lYXJSaW5nc0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgeCwgeSkpIHtcbiAgICAgICAgcG9pbnRYID0geDtcbiAgICAgICAgbWF4U2VnbWVudExlbmd0aCA9IHNlZ21lbnRMZW5ndGg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgeDEgPSB4MjtcbiAgfVxuXG4gIGlmIChpc05hTihwb2ludFgpKSB7XG4gICAgLy8gVGhlcmUgaXMgbm8gaG9yaXpvbnRhbCBsaW5lIHRoYXQgaGFzIGl0cyBjZW50ZXIgcG9pbnQgaW5zaWRlIHRoZSBsaW5lYXJcbiAgICAvLyByaW5nLiAgVXNlIHRoZSBjZW50ZXIgb2YgdGhlIHRoZSBsaW5lYXIgcmluZydzIGV4dGVudC5cbiAgICBwb2ludFggPSBmbGF0Q2VudGVyc1tmbGF0Q2VudGVyc09mZnNldF07XG4gIH1cblxuICBpZiAob3B0X2Rlc3QpIHtcbiAgICBvcHRfZGVzdC5wdXNoKHBvaW50WCwgeSwgbWF4U2VnbWVudExlbmd0aCk7XG4gICAgcmV0dXJuIG9wdF9kZXN0O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbcG9pbnRYLCB5LCBtYXhTZWdtZW50TGVuZ3RoXTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q2VudGVycyBGbGF0IGNlbnRlcnMuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBJbnRlcmlvciBwb2ludHMgYXMgWFlNIGNvb3JkaW5hdGVzLCB3aGVyZSBNIGlzIHRoZVxuICogbGVuZ3RoIG9mIHRoZSBob3Jpem9udGFsIGludGVyc2VjdGlvbiB0aGF0IHRoZSBwb2ludCBiZWxvbmdzIHRvLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnRlcmlvclBvaW50c09mTXVsdGlBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgZmxhdENlbnRlcnMpIHtcbiAgdmFyIGludGVyaW9yUG9pbnRzID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmRzID0gZW5kc3NbaV07XG4gICAgaW50ZXJpb3JQb2ludHMgPSBnZXRJbnRlcmlvclBvaW50T2ZBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBmbGF0Q2VudGVycywgMiAqIGksIGludGVyaW9yUG9pbnRzKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gaW50ZXJpb3JQb2ludHM7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9zZWdtZW50c1xuICovXG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBjYWxscyBgY2FsbGJhY2tgIGZvciBlYWNoIHNlZ21lbnQgb2YgdGhlIGZsYXQgY29vcmRpbmF0ZXNcbiAqIGFycmF5LiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBhIHRydXRoeSB2YWx1ZSB0aGUgZnVuY3Rpb24gcmV0dXJucyB0aGF0XG4gKiB2YWx1ZSBpbW1lZGlhdGVseS4gT3RoZXJ3aXNlIHRoZSBmdW5jdGlvbiByZXR1cm5zIGBmYWxzZWAuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUsIGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IFR9IGNhbGxiYWNrIEZ1bmN0aW9uXG4gKiAgICAgY2FsbGVkIGZvciBlYWNoIHNlZ21lbnQuXG4gKiBAcmV0dXJuIHtUfGJvb2xlYW59IFZhbHVlLlxuICogQHRlbXBsYXRlIFRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2goZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBjYWxsYmFjaykge1xuICB2YXIgcG9pbnQxID0gW2ZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV1dO1xuICB2YXIgcG9pbnQyID0gW107XG4gIHZhciByZXQ7XG5cbiAgZm9yICg7IG9mZnNldCArIHN0cmlkZSA8IGVuZDsgb2Zmc2V0ICs9IHN0cmlkZSkge1xuICAgIHBvaW50MlswXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGVdO1xuICAgIHBvaW50MlsxXSA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGUgKyAxXTtcbiAgICByZXQgPSBjYWxsYmFjayhwb2ludDEsIHBvaW50Mik7XG5cbiAgICBpZiAocmV0KSB7XG4gICAgICByZXR1cm4gcmV0O1xuICAgIH1cblxuICAgIHBvaW50MVswXSA9IHBvaW50MlswXTtcbiAgICBwb2ludDFbMV0gPSBwb2ludDJbMV07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9pbnRlcnNlY3RzZXh0ZW50XG4gKi9cbmltcG9ydCB7IGNvbnRhaW5zRXh0ZW50LCBjcmVhdGVFbXB0eSwgZXh0ZW5kRmxhdENvb3JkaW5hdGVzLCBpbnRlcnNlY3RzLCBpbnRlcnNlY3RzU2VnbWVudCB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBmb3JFYWNoIGFzIGZvckVhY2hTZWdtZW50IH0gZnJvbSAnLi9zZWdtZW50cy5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nQ29udGFpbnNFeHRlbnQsIGxpbmVhclJpbmdDb250YWluc1hZIH0gZnJvbSAnLi9jb250YWlucy5qcyc7XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHNMaW5lU3RyaW5nKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZXh0ZW50KSB7XG4gIHZhciBjb29yZGluYXRlc0V4dGVudCA9IGV4dGVuZEZsYXRDb29yZGluYXRlcyhjcmVhdGVFbXB0eSgpLCBmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xuXG4gIGlmICghaW50ZXJzZWN0cyhleHRlbnQsIGNvb3JkaW5hdGVzRXh0ZW50KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChjb250YWluc0V4dGVudChleHRlbnQsIGNvb3JkaW5hdGVzRXh0ZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVzRXh0ZW50WzBdID49IGV4dGVudFswXSAmJiBjb29yZGluYXRlc0V4dGVudFsyXSA8PSBleHRlbnRbMl0pIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChjb29yZGluYXRlc0V4dGVudFsxXSA+PSBleHRlbnRbMV0gJiYgY29vcmRpbmF0ZXNFeHRlbnRbM10gPD0gZXh0ZW50WzNdKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZm9yRWFjaFNlZ21lbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLFxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHBvaW50MSBTdGFydCBwb2ludC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHBvaW50MiBFbmQgcG9pbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgc2VnbWVudCBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QsXG4gICAqICAgICBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICovXG4gIGZ1bmN0aW9uIChwb2ludDEsIHBvaW50Mikge1xuICAgIHJldHVybiBpbnRlcnNlY3RzU2VnbWVudChleHRlbnQsIHBvaW50MSwgcG9pbnQyKTtcbiAgfSk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHNMaW5lU3RyaW5nQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgZXh0ZW50KSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGlmIChpbnRlcnNlY3RzTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1tpXSwgc3RyaWRlLCBleHRlbnQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBvZmZzZXQgPSBlbmRzW2ldO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzTGluZWFyUmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGV4dGVudCkge1xuICBpZiAoaW50ZXJzZWN0c0xpbmVTdHJpbmcoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAobGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnRbMF0sIGV4dGVudFsxXSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChsaW5lYXJSaW5nQ29udGFpbnNYWShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGV4dGVudFswXSwgZXh0ZW50WzNdKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGxpbmVhclJpbmdDb250YWluc1hZKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZXh0ZW50WzJdLCBleHRlbnRbMV0pKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAobGluZWFyUmluZ0NvbnRhaW5zWFkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBleHRlbnRbMl0sIGV4dGVudFszXSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0c0xpbmVhclJpbmdBcnJheShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBleHRlbnQpIHtcbiAgaWYgKCFpbnRlcnNlY3RzTGluZWFyUmluZyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1swXSwgc3RyaWRlLCBleHRlbnQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGVuZHMubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMSwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBpZiAobGluZWFyUmluZ0NvbnRhaW5zRXh0ZW50KGZsYXRDb29yZGluYXRlcywgZW5kc1tpIC0gMV0sIGVuZHNbaV0sIHN0cmlkZSwgZXh0ZW50KSkge1xuICAgICAgaWYgKCFpbnRlcnNlY3RzTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMsIGVuZHNbaSAtIDFdLCBlbmRzW2ldLCBzdHJpZGUsIGV4dGVudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzTGluZWFyUmluZ011bHRpQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIGV4dGVudCkge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGVuZHMgPSBlbmRzc1tpXTtcblxuICAgIGlmIChpbnRlcnNlY3RzTGluZWFyUmluZ0FycmF5KGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIGV4dGVudCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3JldmVyc2VcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpIHtcbiAgd2hpbGUgKG9mZnNldCA8IGVuZCAtIHN0cmlkZSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlOyArK2kpIHtcbiAgICAgIHZhciB0bXAgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgaV07XG4gICAgICBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgaV0gPSBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlICsgaV07XG4gICAgICBmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gc3RyaWRlICsgaV0gPSB0bXA7XG4gICAgfVxuXG4gICAgb2Zmc2V0ICs9IHN0cmlkZTtcbiAgICBlbmQgLT0gc3RyaWRlO1xuICB9XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9vcmllbnRcbiAqL1xuaW1wb3J0IHsgY29vcmRpbmF0ZXMgYXMgcmV2ZXJzZUNvb3JkaW5hdGVzIH0gZnJvbSAnLi9yZXZlcnNlLmpzJztcbi8qKlxuICogSXMgdGhlIGxpbmVhciByaW5nIG9yaWVudGVkIGNsb2Nrd2lzZSBpbiBhIGNvb3JkaW5hdGUgc3lzdGVtIHdpdGggYSBib3R0b20tbGVmdFxuICogY29vcmRpbmF0ZSBvcmlnaW4/IEZvciBhIGNvb3JkaW5hdGUgc3lzdGVtIHdpdGggYSB0b3AtbGVmdCBjb29yZGluYXRlIG9yaWdpbixcbiAqIHRoZSByaW5nJ3Mgb3JpZW50YXRpb24gaXMgY2xvY2t3aXNlIHdoZW4gdGhpcyBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IElzIGNsb2Nrd2lzZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gbGluZWFyUmluZ0lzQ2xvY2t3aXNlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICAvLyBodHRwOi8vdGlueXVybC5jb20vY2xvY2t3aXNlLW1ldGhvZFxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vT1NHZW8vZ2RhbC9ibG9iL3RydW5rL2dkYWwvb2dyL29ncmxpbmVhcnJpbmcuY3BwXG4gIHZhciBlZGdlID0gMDtcbiAgdmFyIHgxID0gZmxhdENvb3JkaW5hdGVzW2VuZCAtIHN0cmlkZV07XG4gIHZhciB5MSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGUgKyAxXTtcblxuICBmb3IgKDsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICAgIGVkZ2UgKz0gKHgyIC0geDEpICogKHkyICsgeTEpO1xuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgfVxuXG4gIHJldHVybiBlZGdlID09PSAwID8gdW5kZWZpbmVkIDogZWRnZSA+IDA7XG59XG4vKipcbiAqIERldGVybWluZXMgaWYgbGluZWFyIHJpbmdzIGFyZSBvcmllbnRlZC4gIEJ5IGRlZmF1bHQsIGxlZnQtaGFuZCBvcmllbnRhdGlvblxuICogaXMgdGVzdGVkIChmaXJzdCByaW5nIG11c3QgYmUgY2xvY2t3aXNlLCByZW1haW5pbmcgcmluZ3MgY291bnRlci1jbG9ja3dpc2UpLlxuICogVG8gdGVzdCBmb3IgcmlnaHQtaGFuZCBvcmllbnRhdGlvbiwgdXNlIHRoZSBgb3B0X3JpZ2h0YCBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgQXJyYXkgb2YgZW5kIGluZGV4ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yaWdodCBUZXN0IGZvciByaWdodC1oYW5kIG9yaWVudGF0aW9uXG4gKiAgICAgKGNvdW50ZXItY2xvY2t3aXNlIGV4dGVyaW9yIHJpbmcgYW5kIGNsb2Nrd2lzZSBpbnRlcmlvciByaW5ncykuXG4gKiBAcmV0dXJuIHtib29sZWFufSBSaW5ncyBhcmUgY29ycmVjdGx5IG9yaWVudGVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc0FyZU9yaWVudGVkKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIG9wdF9yaWdodCkge1xuICB2YXIgcmlnaHQgPSBvcHRfcmlnaHQgIT09IHVuZGVmaW5lZCA/IG9wdF9yaWdodCA6IGZhbHNlO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgIHZhciBpc0Nsb2Nrd2lzZSA9IGxpbmVhclJpbmdJc0Nsb2Nrd2lzZShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUpO1xuXG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGlmIChyaWdodCAmJiBpc0Nsb2Nrd2lzZSB8fCAhcmlnaHQgJiYgIWlzQ2xvY2t3aXNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHJpZ2h0ICYmICFpc0Nsb2Nrd2lzZSB8fCAhcmlnaHQgJiYgaXNDbG9ja3dpc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBEZXRlcm1pbmVzIGlmIGxpbmVhciByaW5ncyBhcmUgb3JpZW50ZWQuICBCeSBkZWZhdWx0LCBsZWZ0LWhhbmQgb3JpZW50YXRpb25cbiAqIGlzIHRlc3RlZCAoZmlyc3QgcmluZyBtdXN0IGJlIGNsb2Nrd2lzZSwgcmVtYWluaW5nIHJpbmdzIGNvdW50ZXItY2xvY2t3aXNlKS5cbiAqIFRvIHRlc3QgZm9yIHJpZ2h0LWhhbmQgb3JpZW50YXRpb24sIHVzZSB0aGUgYG9wdF9yaWdodGAgYXJndW1lbnQuXG4gKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtBcnJheTxBcnJheTxudW1iZXI+Pn0gZW5kc3MgQXJyYXkgb2YgYXJyYXkgb2YgZW5kIGluZGV4ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yaWdodCBUZXN0IGZvciByaWdodC1oYW5kIG9yaWVudGF0aW9uXG4gKiAgICAgKGNvdW50ZXItY2xvY2t3aXNlIGV4dGVyaW9yIHJpbmcgYW5kIGNsb2Nrd2lzZSBpbnRlcmlvciByaW5ncykuXG4gKiBAcmV0dXJuIHtib29sZWFufSBSaW5ncyBhcmUgY29ycmVjdGx5IG9yaWVudGVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc3NBcmVPcmllbnRlZChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3MsIHN0cmlkZSwgb3B0X3JpZ2h0KSB7XG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuXG4gICAgaWYgKCFsaW5lYXJSaW5nc0FyZU9yaWVudGVkKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzLCBzdHJpZGUsIG9wdF9yaWdodCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoZW5kcy5sZW5ndGgpIHtcbiAgICAgIG9mZnNldCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogT3JpZW50IGNvb3JkaW5hdGVzIGluIGEgZmxhdCBhcnJheSBvZiBsaW5lYXIgcmluZ3MuICBCeSBkZWZhdWx0LCByaW5nc1xuICogYXJlIG9yaWVudGVkIGZvbGxvd2luZyB0aGUgbGVmdC1oYW5kIHJ1bGUgKGNsb2Nrd2lzZSBmb3IgZXh0ZXJpb3IgYW5kXG4gKiBjb3VudGVyLWNsb2Nrd2lzZSBmb3IgaW50ZXJpb3IgcmluZ3MpLiAgVG8gb3JpZW50IGFjY29yZGluZyB0byB0aGVcbiAqIHJpZ2h0LWhhbmQgcnVsZSwgdXNlIHRoZSBgb3B0X3JpZ2h0YCBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JpZ2h0IEZvbGxvdyB0aGUgcmlnaHQtaGFuZCBydWxlIGZvciBvcmllbnRhdGlvbi5cbiAqIEByZXR1cm4ge251bWJlcn0gRW5kLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBvcmllbnRMaW5lYXJSaW5ncyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBvcHRfcmlnaHQpIHtcbiAgdmFyIHJpZ2h0ID0gb3B0X3JpZ2h0ICE9PSB1bmRlZmluZWQgPyBvcHRfcmlnaHQgOiBmYWxzZTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICB2YXIgaXNDbG9ja3dpc2UgPSBsaW5lYXJSaW5nSXNDbG9ja3dpc2UoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKTtcbiAgICB2YXIgcmV2ZXJzZSA9IGkgPT09IDAgPyByaWdodCAmJiBpc0Nsb2Nrd2lzZSB8fCAhcmlnaHQgJiYgIWlzQ2xvY2t3aXNlIDogcmlnaHQgJiYgIWlzQ2xvY2t3aXNlIHx8ICFyaWdodCAmJiBpc0Nsb2Nrd2lzZTtcblxuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICByZXZlcnNlQ29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKTtcbiAgICB9XG5cbiAgICBvZmZzZXQgPSBlbmQ7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufVxuLyoqXG4gKiBPcmllbnQgY29vcmRpbmF0ZXMgaW4gYSBmbGF0IGFycmF5IG9mIGxpbmVhciByaW5ncy4gIEJ5IGRlZmF1bHQsIHJpbmdzXG4gKiBhcmUgb3JpZW50ZWQgZm9sbG93aW5nIHRoZSBsZWZ0LWhhbmQgcnVsZSAoY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmRcbiAqIGNvdW50ZXItY2xvY2t3aXNlIGZvciBpbnRlcmlvciByaW5ncykuICBUbyBvcmllbnQgYWNjb3JkaW5nIHRvIHRoZVxuICogcmlnaHQtaGFuZCBydWxlLCB1c2UgdGhlIGBvcHRfcmlnaHRgIGFyZ3VtZW50LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8bnVtYmVyPj59IGVuZHNzIEFycmF5IG9mIGFycmF5IG9mIGVuZCBpbmRleGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfcmlnaHQgRm9sbG93IHRoZSByaWdodC1oYW5kIHJ1bGUgZm9yIG9yaWVudGF0aW9uLlxuICogQHJldHVybiB7bnVtYmVyfSBFbmQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG9yaWVudExpbmVhclJpbmdzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUsIG9wdF9yaWdodCkge1xuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgb2Zmc2V0ID0gb3JpZW50TGluZWFyUmluZ3MoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzW2ldLCBzdHJpZGUsIG9wdF9yaWdodCk7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0O1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9Qb2x5Z29uXG4gKi9cblxuXG5pbXBvcnQgR2VvbWV0cnlMYXlvdXQgZnJvbSAnLi9HZW9tZXRyeUxheW91dC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBMaW5lYXJSaW5nIGZyb20gJy4vTGluZWFyUmluZy5qcyc7XG5pbXBvcnQgUG9pbnQgZnJvbSAnLi9Qb2ludC5qcyc7XG5pbXBvcnQgU2ltcGxlR2VvbWV0cnkgZnJvbSAnLi9TaW1wbGVHZW9tZXRyeS5qcyc7XG5pbXBvcnQgeyBhcnJheU1heFNxdWFyZWREZWx0YSwgYXNzaWduQ2xvc2VzdEFycmF5UG9pbnQgfSBmcm9tICcuL2ZsYXQvY2xvc2VzdC5qcyc7XG5pbXBvcnQgeyBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFksIGdldENlbnRlciB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGdldEludGVyaW9yUG9pbnRPZkFycmF5IH0gZnJvbSAnLi9mbGF0L2ludGVyaW9ycG9pbnQuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW5mbGF0ZS5qcyc7XG5pbXBvcnQgeyBpbnRlcnNlY3RzTGluZWFyUmluZ0FycmF5IH0gZnJvbSAnLi9mbGF0L2ludGVyc2VjdHNleHRlbnQuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZ3NBcmVPcmllbnRlZCwgb3JpZW50TGluZWFyUmluZ3MgfSBmcm9tICcuL2ZsYXQvb3JpZW50LmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdzIGFzIGxpbmVhclJpbmdzQXJlYSB9IGZyb20gJy4vZmxhdC9hcmVhLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdzQ29udGFpbnNYWSB9IGZyb20gJy4vZmxhdC9jb250YWlucy5qcyc7XG5pbXBvcnQgeyBtb2R1bG8gfSBmcm9tICcuLi9tYXRoLmpzJztcbmltcG9ydCB7IHF1YW50aXplQXJyYXkgfSBmcm9tICcuL2ZsYXQvc2ltcGxpZnkuanMnO1xuaW1wb3J0IHsgb2Zmc2V0IGFzIHNwaGVyZU9mZnNldCB9IGZyb20gJy4uL3NwaGVyZS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFBvbHlnb24gZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBQb2x5Z29uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFBvbHlnb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0geyFBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+PnwhQXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXNcbiAgICogICAgIEFycmF5IG9mIGxpbmVhciByaW5ncyB0aGF0IGRlZmluZSB0aGUgcG9seWdvbi4gVGhlIGZpcnN0IGxpbmVhciByaW5nIG9mIHRoZVxuICAgKiAgICAgYXJyYXkgZGVmaW5lcyB0aGUgb3V0ZXItYm91bmRhcnkgb3Igc3VyZmFjZSBvZiB0aGUgcG9seWdvbi4gRWFjaCBzdWJzZXF1ZW50XG4gICAqICAgICBsaW5lYXIgcmluZyBkZWZpbmVzIGEgaG9sZSBpbiB0aGUgc3VyZmFjZSBvZiB0aGUgcG9seWdvbi4gQSBsaW5lYXIgcmluZyBpc1xuICAgKiAgICAgYW4gYXJyYXkgb2YgdmVydGljZXMnIGNvb3JkaW5hdGVzIHdoZXJlIHRoZSBmaXJzdCBjb29yZGluYXRlIGFuZCB0aGUgbGFzdCBhcmVcbiAgICogICAgIGVxdWl2YWxlbnQuIChGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGhcbiAgICogICAgIGBvcHRfbGF5b3V0YCBhbmQgYG9wdF9lbmRzYCBhcmUgYWxzbyBhY2NlcHRlZC4pXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9HZW9tZXRyeUxheW91dC5qc1wiKS5kZWZhdWx0PX0gb3B0X2xheW91dCBMYXlvdXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9lbmRzIEVuZHMgKGZvciBpbnRlcm5hbCB1c2Ugd2l0aCBmbGF0IGNvb3JkaW5hdGVzKS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBQb2x5Z29uKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0LCBvcHRfZW5kcykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZW5kc18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5mbGF0SW50ZXJpb3JQb2ludFJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmZsYXRJbnRlcmlvclBvaW50XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFfID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmllbnRlZFJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18gPSBudWxsO1xuXG4gICAgaWYgKG9wdF9sYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRfZW5kcykge1xuICAgICAgX3RoaXMuc2V0RmxhdENvb3JkaW5hdGVzKG9wdF9sYXlvdXQsXG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICBjb29yZGluYXRlcyk7XG5cbiAgICAgIF90aGlzLmVuZHNfID0gb3B0X2VuZHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzLnNldENvb3JkaW5hdGVzKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFwcGVuZCB0aGUgcGFzc2VkIGxpbmVhciByaW5nIHRvIHRoaXMgcG9seWdvbi5cbiAgICogQHBhcmFtIHtMaW5lYXJSaW5nfSBsaW5lYXJSaW5nIExpbmVhciByaW5nLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuYXBwZW5kTGluZWFyUmluZyA9IGZ1bmN0aW9uIChsaW5lYXJSaW5nKSB7XG4gICAgaWYgKCF0aGlzLmZsYXRDb29yZGluYXRlcykge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBsaW5lYXJSaW5nLmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4dGVuZCh0aGlzLmZsYXRDb29yZGluYXRlcywgbGluZWFyUmluZy5nZXRGbGF0Q29vcmRpbmF0ZXMoKSk7XG4gICAgfVxuXG4gICAgdGhpcy5lbmRzXy5wdXNoKHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBNYWtlIGEgY29tcGxldGUgY29weSBvZiB0aGUgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4geyFQb2x5Z29ufSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwb2x5Z29uID0gbmV3IFBvbHlnb24odGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKSwgdGhpcy5sYXlvdXQsIHRoaXMuZW5kc18uc2xpY2UoKSk7XG4gICAgcG9seWdvbi5hcHBseVByb3BlcnRpZXModGhpcyk7XG4gICAgcmV0dXJuIHBvbHlnb247XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2xvc2VzdFBvaW50IENsb3Nlc3QgcG9pbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtaW5TcXVhcmVkRGlzdGFuY2UgTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRYWSA9IGZ1bmN0aW9uICh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgIGlmIChtaW5TcXVhcmVkRGlzdGFuY2UgPCBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkodGhpcy5nZXRFeHRlbnQoKSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLm1heERlbHRhXyA9IE1hdGguc3FydChhcnJheU1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIDApKTtcbiAgICAgIHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzc2lnbkNsb3Nlc3RBcnJheVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgdGhpcy5tYXhEZWx0YV8sIHRydWUsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zICh4LCB5KS5cbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5jb250YWluc1hZID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gbGluZWFyUmluZ3NDb250YWluc1hZKHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIHgsIHkpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBhcmVhIG9mIHRoZSBwb2x5Z29uIG9uIHByb2plY3RlZCBwbGFuZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBBcmVhIChvbiBwcm9qZWN0ZWQgcGxhbmUpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0QXJlYSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbGluZWFyUmluZ3NBcmVhKHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb29yZGluYXRlIGFycmF5IGZvciB0aGlzIGdlb21ldHJ5LiAgVGhpcyBhcnJheSBoYXMgdGhlIHN0cnVjdHVyZVxuICAgKiBvZiBhIEdlb0pTT04gY29vcmRpbmF0ZSBhcnJheSBmb3IgcG9seWdvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yaWdodCBPcmllbnQgY29vcmRpbmF0ZXMgYWNjb3JkaW5nIHRvIHRoZSByaWdodC1oYW5kXG4gICAqICAgICBydWxlIChjb3VudGVyLWNsb2Nrd2lzZSBmb3IgZXh0ZXJpb3IgYW5kIGNsb2Nrd2lzZSBmb3IgaW50ZXJpb3IgcmluZ3MpLlxuICAgKiAgICAgSWYgYGZhbHNlYCwgY29vcmRpbmF0ZXMgd2lsbCBiZSBvcmllbnRlZCBhY2NvcmRpbmcgdG8gdGhlIGxlZnQtaGFuZCBydWxlXG4gICAqICAgICAoY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmQgY291bnRlci1jbG9ja3dpc2UgZm9yIGludGVyaW9yIHJpbmdzKS5cbiAgICogICAgIEJ5IGRlZmF1bHQsIGNvb3JkaW5hdGUgb3JpZW50YXRpb24gd2lsbCBkZXBlbmQgb24gaG93IHRoZSBnZW9tZXRyeSB3YXNcbiAgICogICAgIGNvbnN0cnVjdGVkLlxuICAgKiBAcmV0dXJuIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gQ29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChvcHRfcmlnaHQpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzO1xuXG4gICAgaWYgKG9wdF9yaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCkuc2xpY2UoKTtcbiAgICAgIG9yaWVudExpbmVhclJpbmdzKGZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIG9wdF9yaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIH1cblxuICAgIHJldHVybiBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheShmbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEVuZHMuXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0RW5kcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5lbmRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEludGVyaW9yIHBvaW50LlxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmdldEZsYXRJbnRlcmlvclBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmZsYXRJbnRlcmlvclBvaW50UmV2aXNpb25fICE9IHRoaXMuZ2V0UmV2aXNpb24oKSkge1xuICAgICAgdmFyIGZsYXRDZW50ZXIgPSBnZXRDZW50ZXIodGhpcy5nZXRFeHRlbnQoKSk7XG4gICAgICB0aGlzLmZsYXRJbnRlcmlvclBvaW50XyA9IGdldEludGVyaW9yUG9pbnRPZkFycmF5KHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIGZsYXRDZW50ZXIsIDApO1xuICAgICAgdGhpcy5mbGF0SW50ZXJpb3JQb2ludFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mbGF0SW50ZXJpb3JQb2ludF87XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gYW4gaW50ZXJpb3IgcG9pbnQgb2YgdGhlIHBvbHlnb24uXG4gICAqIEByZXR1cm4ge1BvaW50fSBJbnRlcmlvciBwb2ludCBhcyBYWU0gY29vcmRpbmF0ZSwgd2hlcmUgTSBpcyB0aGVcbiAgICogbGVuZ3RoIG9mIHRoZSBob3Jpem9udGFsIGludGVyc2VjdGlvbiB0aGF0IHRoZSBwb2ludCBiZWxvbmdzIHRvLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0SW50ZXJpb3JQb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IFBvaW50KHRoaXMuZ2V0RmxhdEludGVyaW9yUG9pbnQoKSwgR2VvbWV0cnlMYXlvdXQuWFlNKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIHJpbmdzIG9mIHRoZSBwb2x5Z29uLCAgdGhpcyBpbmNsdWRlcyB0aGUgZXh0ZXJpb3JcbiAgICogcmluZyBhbmQgYW55IGludGVyaW9yIHJpbmdzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IE51bWJlciBvZiByaW5ncy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmdldExpbmVhclJpbmdDb3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5lbmRzXy5sZW5ndGg7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIE50aCBsaW5lYXIgcmluZyBvZiB0aGUgcG9seWdvbiBnZW9tZXRyeS4gUmV0dXJuIGBudWxsYCBpZiB0aGVcbiAgICogZ2l2ZW4gaW5kZXggaXMgb3V0IG9mIHJhbmdlLlxuICAgKiBUaGUgZXh0ZXJpb3IgbGluZWFyIHJpbmcgaXMgYXZhaWxhYmxlIGF0IGluZGV4IGAwYCBhbmQgdGhlIGludGVyaW9yIHJpbmdzXG4gICAqIGF0IGluZGV4IGAxYCBhbmQgYmV5b25kLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXguXG4gICAqIEByZXR1cm4ge0xpbmVhclJpbmd9IExpbmVhciByaW5nLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0TGluZWFyUmluZyA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIGlmIChpbmRleCA8IDAgfHwgdGhpcy5lbmRzXy5sZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTGluZWFyUmluZyh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZShpbmRleCA9PT0gMCA/IDAgOiB0aGlzLmVuZHNfW2luZGV4IC0gMV0sIHRoaXMuZW5kc19baW5kZXhdKSwgdGhpcy5sYXlvdXQpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsaW5lYXIgcmluZ3Mgb2YgdGhlIHBvbHlnb24uXG4gICAqIEByZXR1cm4ge0FycmF5PExpbmVhclJpbmc+fSBMaW5lYXIgcmluZ3MuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2x5Z29uLnByb3RvdHlwZS5nZXRMaW5lYXJSaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5b3V0ID0gdGhpcy5sYXlvdXQ7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIHZhciBlbmRzID0gdGhpcy5lbmRzXztcbiAgICB2YXIgbGluZWFyUmluZ3MgPSBbXTtcbiAgICB2YXIgb2Zmc2V0ID0gMDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgICB2YXIgbGluZWFyUmluZyA9IG5ldyBMaW5lYXJSaW5nKGZsYXRDb29yZGluYXRlcy5zbGljZShvZmZzZXQsIGVuZCksIGxheW91dCk7XG4gICAgICBsaW5lYXJSaW5ncy5wdXNoKGxpbmVhclJpbmcpO1xuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIHJldHVybiBsaW5lYXJSaW5ncztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE9yaWVudGVkIGZsYXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMub3JpZW50ZWRSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG5cbiAgICAgIGlmIChsaW5lYXJSaW5nc0FyZU9yaWVudGVkKGZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUpKSB7XG4gICAgICAgIHRoaXMub3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXNfID0gZmxhdENvb3JkaW5hdGVzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18gPSBmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18ubGVuZ3RoID0gb3JpZW50TGluZWFyUmluZ3ModGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18sIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5vcmllbnRlZFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7UG9seWdvbn0gU2ltcGxpZmllZCBQb2x5Z29uLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgUG9seWdvbi5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzID0gW107XG4gICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBxdWFudGl6ZUFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgTWF0aC5zcXJ0KHNxdWFyZWRUb2xlcmFuY2UpLCBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCAwLCBzaW1wbGlmaWVkRW5kcyk7XG4gICAgcmV0dXJuIG5ldyBQb2x5Z29uKHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBzaW1wbGlmaWVkRW5kcyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5QT0xZR09OO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGludGVyc2VjdHNMaW5lYXJSaW5nQXJyYXkodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIHBvbHlnb24uXG4gICAqIEBwYXJhbSB7IUFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvbHlnb24ucHJvdG90eXBlLnNldENvb3JkaW5hdGVzID0gZnVuY3Rpb24gKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KSB7XG4gICAgdGhpcy5zZXRMYXlvdXQob3B0X2xheW91dCwgY29vcmRpbmF0ZXMsIDIpO1xuXG4gICAgaWYgKCF0aGlzLmZsYXRDb29yZGluYXRlcykge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgZW5kcyA9IGRlZmxhdGVDb29yZGluYXRlc0FycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCBjb29yZGluYXRlcywgdGhpcy5zdHJpZGUsIHRoaXMuZW5kc18pO1xuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGVuZHMubGVuZ3RoID09PSAwID8gMCA6IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gUG9seWdvbjtcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBQb2x5Z29uO1xuLyoqXG4gKiBDcmVhdGUgYW4gYXBwcm94aW1hdGlvbiBvZiBhIGNpcmNsZSBvbiB0aGUgc3VyZmFjZSBvZiBhIHNwaGVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjZW50ZXIgQ2VudGVyIChgW2xvbiwgbGF0XWAgaW4gZGVncmVlcykuXG4gKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIFRoZSBncmVhdC1jaXJjbGUgZGlzdGFuY2UgZnJvbSB0aGUgY2VudGVyIHRvXG4gKiAgICAgdGhlIHBvbHlnb24gdmVydGljZXMuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9uIE9wdGlvbmFsIG51bWJlciBvZiB2ZXJ0aWNlcyBmb3IgdGhlIHJlc3VsdGluZ1xuICogICAgIHBvbHlnb24uIERlZmF1bHQgaXMgYDMyYC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3NwaGVyZVJhZGl1cyBPcHRpb25hbCByYWRpdXMgZm9yIHRoZSBzcGhlcmUgKGRlZmF1bHRzIHRvXG4gKiAgICAgdGhlIEVhcnRoJ3MgbWVhbiByYWRpdXMgdXNpbmcgdGhlIFdHUzg0IGVsbGlwc29pZCkuXG4gKiBAcmV0dXJuIHtQb2x5Z29ufSBUaGUgXCJjaXJjdWxhclwiIHBvbHlnb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNpcmN1bGFyKGNlbnRlciwgcmFkaXVzLCBvcHRfbiwgb3B0X3NwaGVyZVJhZGl1cykge1xuICB2YXIgbiA9IG9wdF9uID8gb3B0X24gOiAzMjtcbiAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuXG4gIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGV4dGVuZChmbGF0Q29vcmRpbmF0ZXMsIHNwaGVyZU9mZnNldChjZW50ZXIsIHJhZGl1cywgMiAqIE1hdGguUEkgKiBpIC8gbiwgb3B0X3NwaGVyZVJhZGl1cykpO1xuICB9XG5cbiAgZmxhdENvb3JkaW5hdGVzLnB1c2goZmxhdENvb3JkaW5hdGVzWzBdLCBmbGF0Q29vcmRpbmF0ZXNbMV0pO1xuICByZXR1cm4gbmV3IFBvbHlnb24oZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSwgW2ZsYXRDb29yZGluYXRlcy5sZW5ndGhdKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgcG9seWdvbiBmcm9tIGFuIGV4dGVudC4gVGhlIGxheW91dCB1c2VkIGlzIGBYWWAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBUaGUgZXh0ZW50LlxuICogQHJldHVybiB7UG9seWdvbn0gVGhlIHBvbHlnb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21FeHRlbnQoZXh0ZW50KSB7XG4gIHZhciBtaW5YID0gZXh0ZW50WzBdO1xuICB2YXIgbWluWSA9IGV4dGVudFsxXTtcbiAgdmFyIG1heFggPSBleHRlbnRbMl07XG4gIHZhciBtYXhZID0gZXh0ZW50WzNdO1xuICB2YXIgZmxhdENvb3JkaW5hdGVzID0gW21pblgsIG1pblksIG1pblgsIG1heFksIG1heFgsIG1heFksIG1heFgsIG1pblksIG1pblgsIG1pblldO1xuICByZXR1cm4gbmV3IFBvbHlnb24oZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSwgW2ZsYXRDb29yZGluYXRlcy5sZW5ndGhdKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgcmVndWxhciBwb2x5Z29uIGZyb20gYSBjaXJjbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGNpcmNsZSBDaXJjbGUgZ2VvbWV0cnkuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9zaWRlcyBOdW1iZXIgb2Ygc2lkZXMgb2YgdGhlIHBvbHlnb24uIERlZmF1bHQgaXMgMzIuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9hbmdsZSBTdGFydCBhbmdsZSBmb3IgdGhlIGZpcnN0IHZlcnRleCBvZiB0aGUgcG9seWdvbiBpblxuICogICAgIGNvdW50ZXItY2xvY2t3aXNlIHJhZGlhbnMuIDAgbWVhbnMgRWFzdC4gRGVmYXVsdCBpcyAwLlxuICogQHJldHVybiB7UG9seWdvbn0gUG9seWdvbiBnZW9tZXRyeS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUNpcmNsZShjaXJjbGUsIG9wdF9zaWRlcywgb3B0X2FuZ2xlKSB7XG4gIHZhciBzaWRlcyA9IG9wdF9zaWRlcyA/IG9wdF9zaWRlcyA6IDMyO1xuICB2YXIgc3RyaWRlID0gY2lyY2xlLmdldFN0cmlkZSgpO1xuICB2YXIgbGF5b3V0ID0gY2lyY2xlLmdldExheW91dCgpO1xuICB2YXIgY2VudGVyID0gY2lyY2xlLmdldENlbnRlcigpO1xuICB2YXIgYXJyYXlMZW5ndGggPSBzdHJpZGUgKiAoc2lkZXMgKyAxKTtcbiAgdmFyIGZsYXRDb29yZGluYXRlcyA9IG5ldyBBcnJheShhcnJheUxlbmd0aCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJheUxlbmd0aDsgaSArPSBzdHJpZGUpIHtcbiAgICBmbGF0Q29vcmRpbmF0ZXNbaV0gPSAwO1xuICAgIGZsYXRDb29yZGluYXRlc1tpICsgMV0gPSAwO1xuXG4gICAgZm9yICh2YXIgaiA9IDI7IGogPCBzdHJpZGU7IGorKykge1xuICAgICAgZmxhdENvb3JkaW5hdGVzW2kgKyBqXSA9IGNlbnRlcltqXTtcbiAgICB9XG4gIH1cblxuICB2YXIgZW5kcyA9IFtmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoXTtcbiAgdmFyIHBvbHlnb24gPSBuZXcgUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIGxheW91dCwgZW5kcyk7XG4gIG1ha2VSZWd1bGFyKHBvbHlnb24sIGNlbnRlciwgY2lyY2xlLmdldFJhZGl1cygpLCBvcHRfYW5nbGUpO1xuICByZXR1cm4gcG9seWdvbjtcbn1cbi8qKlxuICogTW9kaWZ5IHRoZSBjb29yZGluYXRlcyBvZiBhIHBvbHlnb24gdG8gbWFrZSBpdCBhIHJlZ3VsYXIgcG9seWdvbi5cbiAqIEBwYXJhbSB7UG9seWdvbn0gcG9seWdvbiBQb2x5Z29uIGdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNlbnRlciBDZW50ZXIgb2YgdGhlIHJlZ3VsYXIgcG9seWdvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYWRpdXMgUmFkaXVzIG9mIHRoZSByZWd1bGFyIHBvbHlnb24uXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9hbmdsZSBTdGFydCBhbmdsZSBmb3IgdGhlIGZpcnN0IHZlcnRleCBvZiB0aGUgcG9seWdvbiBpblxuICogICAgIGNvdW50ZXItY2xvY2t3aXNlIHJhZGlhbnMuIDAgbWVhbnMgRWFzdC4gRGVmYXVsdCBpcyAwLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlUmVndWxhcihwb2x5Z29uLCBjZW50ZXIsIHJhZGl1cywgb3B0X2FuZ2xlKSB7XG4gIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBwb2x5Z29uLmdldEZsYXRDb29yZGluYXRlcygpO1xuICB2YXIgc3RyaWRlID0gcG9seWdvbi5nZXRTdHJpZGUoKTtcbiAgdmFyIHNpZGVzID0gZmxhdENvb3JkaW5hdGVzLmxlbmd0aCAvIHN0cmlkZSAtIDE7XG4gIHZhciBzdGFydEFuZ2xlID0gb3B0X2FuZ2xlID8gb3B0X2FuZ2xlIDogMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8PSBzaWRlczsgKytpKSB7XG4gICAgdmFyIG9mZnNldCA9IGkgKiBzdHJpZGU7XG4gICAgdmFyIGFuZ2xlID0gc3RhcnRBbmdsZSArIG1vZHVsbyhpLCBzaWRlcykgKiAyICogTWF0aC5QSSAvIHNpZGVzO1xuICAgIGZsYXRDb29yZGluYXRlc1tvZmZzZXRdID0gY2VudGVyWzBdICsgcmFkaXVzICogTWF0aC5jb3MoYW5nbGUpO1xuICAgIGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXSA9IGNlbnRlclsxXSArIHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlKTtcbiAgfVxuXG4gIHBvbHlnb24uY2hhbmdlZCgpO1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvVmlld1xuICovXG5cblxuaW1wb3J0IEJhc2VPYmplY3QgZnJvbSAnLi9PYmplY3QuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBVbml0cyBmcm9tICcuL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IFZpZXdIaW50IGZyb20gJy4vVmlld0hpbnQuanMnO1xuaW1wb3J0IFZpZXdQcm9wZXJ0eSBmcm9tICcuL1ZpZXdQcm9wZXJ0eS5qcyc7XG5pbXBvcnQgeyBERUZBVUxUX1RJTEVfU0laRSB9IGZyb20gJy4vdGlsZWdyaWQvY29tbW9uLmpzJztcbmltcG9ydCB7IE1FVEVSU19QRVJfVU5JVCwgY3JlYXRlUHJvamVjdGlvbiwgZnJvbVVzZXJDb29yZGluYXRlLCBmcm9tVXNlckV4dGVudCwgZ2V0VXNlclByb2plY3Rpb24sIHRvVXNlckNvb3JkaW5hdGUsIHRvVXNlckV4dGVudCB9IGZyb20gJy4vcHJvai5qcyc7XG5pbXBvcnQgeyBWT0lEIH0gZnJvbSAnLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgYWRkIGFzIGFkZENvb3JkaW5hdGUsIGVxdWFscyBhcyBjb29yZGluYXRlc0VxdWFsLCByb3RhdGUgYXMgcm90YXRlQ29vcmRpbmF0ZSB9IGZyb20gJy4vY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi9vYmouanMnO1xuaW1wb3J0IHsgbm9uZSBhcyBjZW50ZXJOb25lLCBjcmVhdGVFeHRlbnQgfSBmcm9tICcuL2NlbnRlcmNvbnN0cmFpbnQuanMnO1xuaW1wb3J0IHsgY2xhbXAsIG1vZHVsbyB9IGZyb20gJy4vbWF0aC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVNaW5NYXhSZXNvbHV0aW9uIH0gZnJvbSAnLi9yZXNvbHV0aW9uY29uc3RyYWludC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVTbmFwVG9OLCBjcmVhdGVTbmFwVG9aZXJvLCBkaXNhYmxlLCBub25lIGFzIHJvdGF0aW9uTm9uZSB9IGZyb20gJy4vcm90YXRpb25jb25zdHJhaW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZVNuYXBUb1Bvd2VyLCBjcmVhdGVTbmFwVG9SZXNvbHV0aW9ucyB9IGZyb20gJy4vcmVzb2x1dGlvbmNvbnN0cmFpbnQuanMnO1xuaW1wb3J0IHsgZWFzZU91dCB9IGZyb20gJy4vZWFzaW5nLmpzJztcbmltcG9ydCB7IGVxdWFscyB9IGZyb20gJy4vY29vcmRpbmF0ZS5qcyc7XG5pbXBvcnQgeyBnZXRDZW50ZXIsIGdldEZvclZpZXdBbmRTaXplLCBnZXRIZWlnaHQsIGdldFdpZHRoLCBpc0VtcHR5IH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgaW5BbmRPdXQgfSBmcm9tICcuL2Vhc2luZy5qcyc7XG5pbXBvcnQgeyBsaW5lYXJGaW5kTmVhcmVzdCB9IGZyb20gJy4vYXJyYXkuanMnO1xuaW1wb3J0IHsgZnJvbUV4dGVudCBhcyBwb2x5Z29uRnJvbUV4dGVudCB9IGZyb20gJy4vZ2VvbS9Qb2x5Z29uLmpzJztcbi8qKlxuICogQW4gYW5pbWF0aW9uIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBbmltYXRpb25cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFtzb3VyY2VDZW50ZXJdXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbdGFyZ2V0Q2VudGVyXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtzb3VyY2VSZXNvbHV0aW9uXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0YXJnZXRSZXNvbHV0aW9uXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtzb3VyY2VSb3RhdGlvbl1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGFyZ2V0Um90YXRpb25dXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbYW5jaG9yXVxuICogQHByb3BlcnR5IHtudW1iZXJ9IHN0YXJ0XG4gKiBAcHJvcGVydHkge251bWJlcn0gZHVyYXRpb25cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gY29tcGxldGVcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTpudW1iZXJ9IGVhc2luZ1xuICogQHByb3BlcnR5IHtmdW5jdGlvbihib29sZWFuKTp2b2lkfSBjYWxsYmFja1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQ29uc3RyYWludHNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jZW50ZXJjb25zdHJhaW50LmpzXCIpLlR5cGV9IGNlbnRlclxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3Jlc29sdXRpb25jb25zdHJhaW50LmpzXCIpLlR5cGV9IHJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9yb3RhdGlvbmNvbnN0cmFpbnQuanNcIikuVHlwZX0gcm90YXRpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEZpdE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IFtzaXplXSBUaGUgc2l6ZSBpbiBwaXhlbHMgb2YgdGhlIGJveCB0byBmaXRcbiAqIHRoZSBleHRlbnQgaW50by4gRGVmYXVsdCBpcyB0aGUgY3VycmVudCBzaXplIG9mIHRoZSBmaXJzdCBtYXAgaW4gdGhlIERPTSB0aGF0XG4gKiB1c2VzIHRoaXMgdmlldywgb3IgYFsxMDAsIDEwMF1gIGlmIG5vIHN1Y2ggbWFwIGlzIGZvdW5kLlxuICogQHByb3BlcnR5IHshQXJyYXk8bnVtYmVyPn0gW3BhZGRpbmc9WzAsIDAsIDAsIDBdXSBQYWRkaW5nIChpbiBwaXhlbHMpIHRvIGJlXG4gKiBjbGVhcmVkIGluc2lkZSB0aGUgdmlldy4gVmFsdWVzIGluIHRoZSBhcnJheSBhcmUgdG9wLCByaWdodCwgYm90dG9tIGFuZCBsZWZ0XG4gKiBwYWRkaW5nLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbbmVhcmVzdD1mYWxzZV0gSWYgdGhlIHZpZXcgYGNvbnN0cmFpblJlc29sdXRpb25gIG9wdGlvbiBpcyBgdHJ1ZWAsXG4gKiBnZXQgdGhlIG5lYXJlc3QgZXh0ZW50IGluc3RlYWQgb2YgdGhlIGNsb3Nlc3QgdGhhdCBhY3R1YWxseSBmaXRzIHRoZSB2aWV3LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5SZXNvbHV0aW9uPTBdIE1pbmltdW0gcmVzb2x1dGlvbiB0aGF0IHdlIHpvb20gdG8uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFpvb21dIE1heGltdW0gem9vbSBsZXZlbCB0aGF0IHdlIHpvb20gdG8uIElmXG4gKiBgbWluUmVzb2x1dGlvbmAgaXMgZ2l2ZW4sIHRoaXMgcHJvcGVydHkgaXMgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb25dIFRoZSBkdXJhdGlvbiBvZiB0aGUgYW5pbWF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqIEJ5IGRlZmF1bHQsIHRoZXJlIGlzIG5vIGFuaW1hdGlvbiB0byB0aGUgdGFyZ2V0IGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTpudW1iZXJ9IFtlYXNpbmddIFRoZSBlYXNpbmcgZnVuY3Rpb24gdXNlZCBkdXJpbmdcbiAqIHRoZSBhbmltYXRpb24gKGRlZmF1bHRzIHRvIHtAbGluayBtb2R1bGU6b2wvZWFzaW5nfmluQW5kT3V0fSkuXG4gKiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgZm9yIGVhY2ggZnJhbWUgd2l0aCBhIG51bWJlciByZXByZXNlbnRpbmcgYVxuICogZnJhY3Rpb24gb2YgdGhlIGFuaW1hdGlvbidzIGR1cmF0aW9uLiAgVGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gYSBudW1iZXJcbiAqIGJldHdlZW4gMCBhbmQgMSByZXByZXNlbnRpbmcgdGhlIHByb2dyZXNzIHRvd2FyZCB0aGUgZGVzdGluYXRpb24gc3RhdGUuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGJvb2xlYW4pOnZvaWR9IFtjYWxsYmFja10gRnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIHZpZXcgaXMgaW5cbiAqIGl0cyBmaW5hbCBwb3NpdGlvbi4gVGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdpdGggYHRydWVgIGlmIHRoZSBhbmltYXRpb25cbiAqIHNlcmllcyBjb21wbGV0ZWQgb24gaXRzIG93biBvciBgZmFsc2VgIGlmIGl0IHdhcyBjYW5jZWxsZWQuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBWaWV3T3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gW2NlbnRlcl0gVGhlIGluaXRpYWwgY2VudGVyIGZvclxuICogdGhlIHZpZXcuIElmIGEgdXNlciBwcm9qZWN0aW9uIGlzIG5vdCBzZXQsIHRoZSBjb29yZGluYXRlIHN5c3RlbSBmb3IgdGhlIGNlbnRlciBpc1xuICogc3BlY2lmaWVkIHdpdGggdGhlIGBwcm9qZWN0aW9uYCBvcHRpb24uIExheWVyIHNvdXJjZXMgd2lsbCBub3QgYmUgZmV0Y2hlZCBpZiB0aGlzXG4gKiBpcyBub3Qgc2V0LCBidXQgdGhlIGNlbnRlciBjYW4gYmUgc2V0IGxhdGVyIHdpdGgge0BsaW5rICNzZXRDZW50ZXJ9LlxuICogQHByb3BlcnR5IHtib29sZWFufG51bWJlcn0gW2NvbnN0cmFpblJvdGF0aW9uPXRydWVdIFJvdGF0aW9uIGNvbnN0cmFpbnQuXG4gKiBgZmFsc2VgIG1lYW5zIG5vIGNvbnN0cmFpbnQuIGB0cnVlYCBtZWFucyBubyBjb25zdHJhaW50LCBidXQgc25hcCB0byB6ZXJvXG4gKiBuZWFyIHplcm8uIEEgbnVtYmVyIGNvbnN0cmFpbnMgdGhlIHJvdGF0aW9uIHRvIHRoYXQgbnVtYmVyIG9mIHZhbHVlcy4gRm9yXG4gKiBleGFtcGxlLCBgNGAgd2lsbCBjb25zdHJhaW4gdGhlIHJvdGF0aW9uIHRvIDAsIDkwLCAxODAsIGFuZCAyNzAgZGVncmVlcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2VuYWJsZVJvdGF0aW9uPXRydWVdIEVuYWJsZSByb3RhdGlvbi5cbiAqIElmIGBmYWxzZWAsIGEgcm90YXRpb24gY29uc3RyYWludCB0aGF0IGFsd2F5cyBzZXRzIHRoZSByb3RhdGlvbiB0byB6ZXJvIGlzXG4gKiB1c2VkLiBUaGUgYGNvbnN0cmFpblJvdGF0aW9uYCBvcHRpb24gaGFzIG5vIGVmZmVjdCBpZiBgZW5hYmxlUm90YXRpb25gIGlzXG4gKiBgZmFsc2VgLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBleHRlbnQgdGhhdCBjb25zdHJhaW5zIHRoZVxuICogdmlldywgaW4gb3RoZXIgd29yZHMsIG5vdGhpbmcgb3V0c2lkZSBvZiB0aGlzIGV4dGVudCBjYW4gYmUgdmlzaWJsZSBvbiB0aGUgbWFwLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbY29uc3RyYWluT25seUNlbnRlcj1mYWxzZV0gSWYgdHJ1ZSwgdGhlIGV4dGVudFxuICogY29uc3RyYWludCB3aWxsIG9ubHkgYXBwbHkgdG8gdGhlIHZpZXcgY2VudGVyIGFuZCBub3QgdGhlIHdob2xlIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Ntb290aEV4dGVudENvbnN0cmFpbnQ9dHJ1ZV0gSWYgdHJ1ZSwgdGhlIGV4dGVudFxuICogY29uc3RyYWludCB3aWxsIGJlIGFwcGxpZWQgc21vb3RobHksIGkuZS4gYWxsb3cgdGhlIHZpZXcgdG8gZ28gc2xpZ2h0bHkgb3V0c2lkZVxuICogb2YgdGhlIGdpdmVuIGBleHRlbnRgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lXG4gKiB0aGUgcmVzb2x1dGlvbiBjb25zdHJhaW50LiBJdCBpcyB1c2VkIHRvZ2V0aGVyIHdpdGggYG1pblJlc29sdXRpb25gIChvclxuICogYG1heFpvb21gKSBhbmQgYHpvb21GYWN0b3JgLiBJZiB1bnNwZWNpZmllZCBpdCBpcyBjYWxjdWxhdGVkIGluIHN1Y2ggYSB3YXlcbiAqIHRoYXQgdGhlIHByb2plY3Rpb24ncyB2YWxpZGl0eSBleHRlbnQgZml0cyBpbiBhIDI1NngyNTYgcHggdGlsZS4gSWYgdGhlXG4gKiBwcm9qZWN0aW9uIGlzIFNwaGVyaWNhbCBNZXJjYXRvciAodGhlIGRlZmF1bHQpIHRoZW4gYG1heFJlc29sdXRpb25gIGRlZmF1bHRzXG4gKiB0byBgNDAwNzUwMTYuNjg1NTc4NDkgLyAyNTYgPSAxNTY1NDMuMDMzOTI4MDQwOTdgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5SZXNvbHV0aW9uXSBUaGUgbWluaW11bSByZXNvbHV0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lXG4gKiB0aGUgcmVzb2x1dGlvbiBjb25zdHJhaW50LiAgSXQgaXMgdXNlZCB0b2dldGhlciB3aXRoIGBtYXhSZXNvbHV0aW9uYCAob3JcbiAqIGBtaW5ab29tYCkgYW5kIGB6b29tRmFjdG9yYC4gIElmIHVuc3BlY2lmaWVkIGl0IGlzIGNhbGN1bGF0ZWQgYXNzdW1pbmcgMjlcbiAqIHpvb20gbGV2ZWxzICh3aXRoIGEgZmFjdG9yIG9mIDIpLiBJZiB0aGUgcHJvamVjdGlvbiBpcyBTcGhlcmljYWwgTWVyY2F0b3JcbiAqICh0aGUgZGVmYXVsdCkgdGhlbiBgbWluUmVzb2x1dGlvbmAgZGVmYXVsdHMgdG9cbiAqIGA0MDA3NTAxNi42ODU1Nzg0OSAvIDI1NiAvIE1hdGgucG93KDIsIDI4KSA9IDAuMDAwNTgzMTY4MjQ1NTgzOTI1M2AuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFpvb209MjhdIFRoZSBtYXhpbXVtIHpvb20gbGV2ZWwgdXNlZCB0byBkZXRlcm1pbmUgdGhlXG4gKiByZXNvbHV0aW9uIGNvbnN0cmFpbnQuIEl0IGlzIHVzZWQgdG9nZXRoZXIgd2l0aCBgbWluWm9vbWAgKG9yXG4gKiBgbWF4UmVzb2x1dGlvbmApIGFuZCBgem9vbUZhY3RvcmAuICBOb3RlIHRoYXQgaWYgYG1pblJlc29sdXRpb25gIGlzIGFsc29cbiAqIHByb3ZpZGVkLCBpdCBpcyBnaXZlbiBwcmVjZWRlbmNlIG92ZXIgYG1heFpvb21gLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5ab29tPTBdIFRoZSBtaW5pbXVtIHpvb20gbGV2ZWwgdXNlZCB0byBkZXRlcm1pbmUgdGhlXG4gKiByZXNvbHV0aW9uIGNvbnN0cmFpbnQuIEl0IGlzIHVzZWQgdG9nZXRoZXIgd2l0aCBgbWF4Wm9vbWAgKG9yXG4gKiBgbWluUmVzb2x1dGlvbmApIGFuZCBgem9vbUZhY3RvcmAuICBOb3RlIHRoYXQgaWYgYG1heFJlc29sdXRpb25gIGlzIGFsc29cbiAqIHByb3ZpZGVkLCBpdCBpcyBnaXZlbiBwcmVjZWRlbmNlIG92ZXIgYG1pblpvb21gLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbbXVsdGlXb3JsZD1mYWxzZV0gSWYgYGZhbHNlYCB0aGUgdmlldyBpcyBjb25zdHJhaW5lZCBzb1xuICogb25seSBvbmUgd29ybGQgaXMgdmlzaWJsZSwgYW5kIHlvdSBjYW5ub3QgcGFuIG9mZiB0aGUgZWRnZS4gIElmIGB0cnVlYCB0aGUgbWFwXG4gKiBtYXkgc2hvdyBtdWx0aXBsZSB3b3JsZHMgYXQgbG93IHpvb20gbGV2ZWxzLiAgT25seSB1c2VkIGlmIHRoZSBgcHJvamVjdGlvbmAgaXNcbiAqIGdsb2JhbC4gIE5vdGUgdGhhdCBpZiBgZXh0ZW50YCBpcyBhbHNvIHByb3ZpZGVkIGl0IGlzIGdpdmVuIHByZWNlZGVuY2UuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb25zdHJhaW5SZXNvbHV0aW9uPWZhbHNlXSBJZiB0cnVlLCB0aGUgdmlldyB3aWxsIGFsd2F5c1xuICogYW5pbWF0ZSB0byB0aGUgY2xvc2VzdCB6b29tIGxldmVsIGFmdGVyIGFuIGludGVyYWN0aW9uOyBmYWxzZSBtZWFuc1xuICogaW50ZXJtZWRpYXJ5IHpvb20gbGV2ZWxzIGFyZSBhbGxvd2VkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbc21vb3RoUmVzb2x1dGlvbkNvbnN0cmFpbnQ9dHJ1ZV0gSWYgdHJ1ZSwgdGhlIHJlc29sdXRpb25cbiAqIG1pbi9tYXggdmFsdWVzIHdpbGwgYmUgYXBwbGllZCBzbW9vdGhseSwgaS4gZS4gYWxsb3cgdGhlIHZpZXcgdG8gZXhjZWVkIHNsaWdodGx5XG4gKiB0aGUgZ2l2ZW4gcmVzb2x1dGlvbiBvciB6b29tIGJvdW5kcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Nob3dGdWxsRXh0ZW50PWZhbHNlXSBBbGxvdyB0aGUgdmlldyB0byBiZSB6b29tZWQgb3V0IHRvXG4gKiBzaG93IHRoZSBmdWxsIGNvbmZpZ3VyZWQgZXh0ZW50LiBCeSBkZWZhdWx0LCB3aGVuIGEgdmlldyBpcyBjb25maWd1cmVkIHdpdGggYW5cbiAqIGV4dGVudCwgdXNlcnMgd2lsbCBub3QgYmUgYWJsZSB0byB6b29tIG91dCBzbyB0aGUgdmlld3BvcnQgZXhjZWVkcyB0aGUgZXh0ZW50IGluXG4gKiBlaXRoZXIgZGltZW5zaW9uLiBUaGlzIG1lYW5zIHRoZSBmdWxsIGV4dGVudCBtYXkgbm90IGJlIHZpc2libGUgaWYgdGhlIHZpZXdwb3J0XG4gKiBpcyB0YWxsZXIgb3Igd2lkZXIgdGhhbiB0aGUgYXNwZWN0IHJhdGlvIG9mIHRoZSBjb25maWd1cmVkIGV4dGVudC4gSWZcbiAqIHNob3dGdWxsRXh0ZW50IGlzIHRydWUsIHRoZSB1c2VyIHdpbGwgYmUgYWJsZSB0byB6b29tIG91dCBzbyB0aGF0IHRoZSB2aWV3cG9ydFxuICogZXhjZWVkcyB0aGUgaGVpZ2h0IG9yIHdpZHRoIG9mIHRoZSBjb25maWd1cmVkIGV4dGVudCwgYnV0IG5vdCBib3RoLCBhbGxvd2luZyB0aGVcbiAqIGZ1bGwgZXh0ZW50IHRvIGJlIHNob3duLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uPSdFUFNHOjM4NTcnXSBUaGVcbiAqIHByb2plY3Rpb24uIFRoZSBkZWZhdWx0IGlzIFNwaGVyaWNhbCBNZXJjYXRvci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmVzb2x1dGlvbl0gVGhlIGluaXRpYWwgcmVzb2x1dGlvbiBmb3IgdGhlIHZpZXcuIFRoZVxuICogdW5pdHMgYXJlIGBwcm9qZWN0aW9uYCB1bml0cyBwZXIgcGl4ZWwgKGUuZy4gbWV0ZXJzIHBlciBwaXhlbCkuIEFuXG4gKiBhbHRlcm5hdGl2ZSB0byBzZXR0aW5nIHRoaXMgaXMgdG8gc2V0IGB6b29tYC4gTGF5ZXIgc291cmNlcyB3aWxsIG5vdCBiZVxuICogZmV0Y2hlZCBpZiBuZWl0aGVyIHRoaXMgbm9yIGB6b29tYCBhcmUgZGVmaW5lZCwgYnV0IHRoZXkgY2FuIGJlIHNldCBsYXRlclxuICogd2l0aCB7QGxpbmsgI3NldFpvb219IG9yIHtAbGluayAjc2V0UmVzb2x1dGlvbn0uXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtyZXNvbHV0aW9uc10gUmVzb2x1dGlvbnMgdG8gZGV0ZXJtaW5lIHRoZVxuICogcmVzb2x1dGlvbiBjb25zdHJhaW50LiBJZiBzZXQgdGhlIGBtYXhSZXNvbHV0aW9uYCwgYG1pblJlc29sdXRpb25gLFxuICogYG1pblpvb21gLCBgbWF4Wm9vbWAsIGFuZCBgem9vbUZhY3RvcmAgb3B0aW9ucyBhcmUgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcm90YXRpb249MF0gVGhlIGluaXRpYWwgcm90YXRpb24gZm9yIHRoZSB2aWV3IGluIHJhZGlhbnNcbiAqIChwb3NpdGl2ZSByb3RhdGlvbiBjbG9ja3dpc2UsIDAgbWVhbnMgTm9ydGgpLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6b29tXSBPbmx5IHVzZWQgaWYgYHJlc29sdXRpb25gIGlzIG5vdCBkZWZpbmVkLiBab29tXG4gKiBsZXZlbCB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgaW5pdGlhbCByZXNvbHV0aW9uIGZvciB0aGUgdmlldy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbem9vbUZhY3Rvcj0yXSBUaGUgem9vbSBmYWN0b3IgdXNlZCB0byBjb21wdXRlIHRoZVxuICogY29ycmVzcG9uZGluZyByZXNvbHV0aW9uLlxuICogQHByb3BlcnR5IHshQXJyYXk8bnVtYmVyPn0gW3BhZGRpbmc9WzAsIDAsIDAsIDBdXSBQYWRkaW5nIChpbiBjc3MgcGl4ZWxzKS5cbiAqIElmIHRoZSBtYXAgdmlld3BvcnQgaXMgcGFydGlhbGx5IGNvdmVyZWQgd2l0aCBvdGhlciBjb250ZW50IChvdmVybGF5cykgYWxvbmdcbiAqIGl0cyBlZGdlcywgdGhpcyBzZXR0aW5nIGFsbG93cyB0byBzaGlmdCB0aGUgY2VudGVyIG9mIHRoZSB2aWV3cG9ydCBhd2F5IGZyb21cbiAqIHRoYXQgY29udGVudC4gVGhlIG9yZGVyIG9mIHRoZSB2YWx1ZXMgaXMgdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0LlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQW5pbWF0aW9uT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gW2NlbnRlcl0gVGhlIGNlbnRlciBvZiB0aGUgdmlldyBhdCB0aGUgZW5kIG9mXG4gKiB0aGUgYW5pbWF0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6b29tXSBUaGUgem9vbSBsZXZlbCBvZiB0aGUgdmlldyBhdCB0aGUgZW5kIG9mIHRoZVxuICogYW5pbWF0aW9uLiBUaGlzIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBgcmVzb2x1dGlvbmAuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3Jlc29sdXRpb25dIFRoZSByZXNvbHV0aW9uIG9mIHRoZSB2aWV3IGF0IHRoZSBlbmRcbiAqIG9mIHRoZSBhbmltYXRpb24uICBJZiBgem9vbWAgaXMgYWxzbyBwcm92aWRlZCwgdGhpcyBvcHRpb24gd2lsbCBiZSBpZ25vcmVkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyb3RhdGlvbl0gVGhlIHJvdGF0aW9uIG9mIHRoZSB2aWV3IGF0IHRoZSBlbmQgb2ZcbiAqIHRoZSBhbmltYXRpb24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBbYW5jaG9yXSBPcHRpb25hbCBhbmNob3IgdG8gcmVtYWluIGZpeGVkXG4gKiBkdXJpbmcgYSByb3RhdGlvbiBvciByZXNvbHV0aW9uIGFuaW1hdGlvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MTAwMF0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOm51bWJlcn0gW2Vhc2luZ10gVGhlIGVhc2luZyBmdW5jdGlvbiB1c2VkXG4gKiBkdXJpbmcgdGhlIGFuaW1hdGlvbiAoZGVmYXVsdHMgdG8ge0BsaW5rIG1vZHVsZTpvbC9lYXNpbmd+aW5BbmRPdXR9KS5cbiAqIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBmb3IgZWFjaCBmcmFtZSB3aXRoIGEgbnVtYmVyIHJlcHJlc2VudGluZyBhXG4gKiBmcmFjdGlvbiBvZiB0aGUgYW5pbWF0aW9uJ3MgZHVyYXRpb24uICBUaGUgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBhIG51bWJlclxuICogYmV0d2VlbiAwIGFuZCAxIHJlcHJlc2VudGluZyB0aGUgcHJvZ3Jlc3MgdG93YXJkIHRoZSBkZXN0aW5hdGlvbiBzdGF0ZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFN0YXRlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjZW50ZXJcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IHJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByb3RhdGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IHpvb21cbiAqL1xuXG4vKipcbiAqIERlZmF1bHQgbWluIHpvb20gbGV2ZWwgZm9yIHRoZSBtYXAgdmlldy5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxudmFyIERFRkFVTFRfTUlOX1pPT00gPSAwO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIFZpZXcgb2JqZWN0IHJlcHJlc2VudHMgYSBzaW1wbGUgMkQgdmlldyBvZiB0aGUgbWFwLlxuICpcbiAqIFRoaXMgaXMgdGhlIG9iamVjdCB0byBhY3QgdXBvbiB0byBjaGFuZ2UgdGhlIGNlbnRlciwgcmVzb2x1dGlvbixcbiAqIGFuZCByb3RhdGlvbiBvZiB0aGUgbWFwLlxuICpcbiAqIEEgVmlldyBoYXMgYSBgcHJvamVjdGlvbmAuIFRoZSBwcm9qZWN0aW9uIGRldGVybWluZXMgdGhlXG4gKiBjb29yZGluYXRlIHN5c3RlbSBvZiB0aGUgY2VudGVyLCBhbmQgaXRzIHVuaXRzIGRldGVybWluZSB0aGUgdW5pdHMgb2YgdGhlXG4gKiByZXNvbHV0aW9uIChwcm9qZWN0aW9uIHVuaXRzIHBlciBwaXhlbCkuIFRoZSBkZWZhdWx0IHByb2plY3Rpb24gaXNcbiAqIFNwaGVyaWNhbCBNZXJjYXRvciAoRVBTRzozODU3KS5cbiAqXG4gKiAjIyMgVGhlIHZpZXcgc3RhdGVzXG4gKlxuICogQSBWaWV3IGlzIGRldGVybWluZWQgYnkgdGhyZWUgc3RhdGVzOiBgY2VudGVyYCwgYHJlc29sdXRpb25gLFxuICogYW5kIGByb3RhdGlvbmAuIEVhY2ggc3RhdGUgaGFzIGEgY29ycmVzcG9uZGluZyBnZXR0ZXIgYW5kIHNldHRlciwgZS5nLlxuICogYGdldENlbnRlcmAgYW5kIGBzZXRDZW50ZXJgIGZvciB0aGUgYGNlbnRlcmAgc3RhdGUuXG4gKlxuICogVGhlIGB6b29tYCBzdGF0ZSBpcyBhY3R1YWxseSBub3Qgc2F2ZWQgb24gdGhlIHZpZXc6IGFsbCBjb21wdXRhdGlvbnNcbiAqIGludGVybmFsbHkgdXNlIHRoZSBgcmVzb2x1dGlvbmAgc3RhdGUuIFN0aWxsLCB0aGUgYHNldFpvb21gIGFuZCBgZ2V0Wm9vbWBcbiAqIG1ldGhvZHMgYXJlIGF2YWlsYWJsZSwgYXMgd2VsbCBhcyBgZ2V0UmVzb2x1dGlvbkZvclpvb21gIGFuZFxuICogYGdldFpvb21Gb3JSZXNvbHV0aW9uYCB0byBzd2l0Y2ggZnJvbSBvbmUgc3lzdGVtIHRvIHRoZSBvdGhlci5cbiAqXG4gKiAjIyMgVGhlIGNvbnN0cmFpbnRzXG4gKlxuICogYHNldENlbnRlcmAsIGBzZXRSZXNvbHV0aW9uYCBhbmQgYHNldFJvdGF0aW9uYCBjYW4gYmUgdXNlZCB0byBjaGFuZ2UgdGhlXG4gKiBzdGF0ZXMgb2YgdGhlIHZpZXcsIGJ1dCBhbnkgY29uc3RyYWludCBkZWZpbmVkIGluIHRoZSBjb25zdHJ1Y3RvciB3aWxsXG4gKiBiZSBhcHBsaWVkIGFsb25nIHRoZSB3YXkuXG4gKlxuICogQSBWaWV3IG9iamVjdCBjYW4gaGF2ZSBhICpyZXNvbHV0aW9uIGNvbnN0cmFpbnQqLCBhICpyb3RhdGlvbiBjb25zdHJhaW50KlxuICogYW5kIGEgKmNlbnRlciBjb25zdHJhaW50Ki5cbiAqXG4gKiBUaGUgKnJlc29sdXRpb24gY29uc3RyYWludCogdHlwaWNhbGx5IHJlc3RyaWN0cyBtaW4vbWF4IHZhbHVlcyBhbmRcbiAqIHNuYXBzIHRvIHNwZWNpZmljIHJlc29sdXRpb25zLiBJdCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBmb2xsb3dpbmdcbiAqIG9wdGlvbnM6IGByZXNvbHV0aW9uc2AsIGBtYXhSZXNvbHV0aW9uYCwgYG1heFpvb21gIGFuZCBgem9vbUZhY3RvcmAuXG4gKiBJZiBgcmVzb2x1dGlvbnNgIGlzIHNldCwgdGhlIG90aGVyIHRocmVlIG9wdGlvbnMgYXJlIGlnbm9yZWQuIFNlZVxuICogZG9jdW1lbnRhdGlvbiBmb3IgZWFjaCBvcHRpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24uIEJ5IGRlZmF1bHQsIHRoZSB2aWV3XG4gKiBvbmx5IGhhcyBhIG1pbi9tYXggcmVzdHJpY3Rpb24gYW5kIGFsbG93IGludGVybWVkaWFyeSB6b29tIGxldmVscyB3aGVuXG4gKiBwaW5jaC16b29taW5nIGZvciBleGFtcGxlLlxuICpcbiAqIFRoZSAqcm90YXRpb24gY29uc3RyYWludCogc25hcHMgdG8gc3BlY2lmaWMgYW5nbGVzLiBJdCBpcyBkZXRlcm1pbmVkXG4gKiBieSB0aGUgZm9sbG93aW5nIG9wdGlvbnM6IGBlbmFibGVSb3RhdGlvbmAgYW5kIGBjb25zdHJhaW5Sb3RhdGlvbmAuXG4gKiBCeSBkZWZhdWx0IHJvdGF0aW9uIGlzIGFsbG93ZWQgYW5kIGl0cyB2YWx1ZSBpcyBzbmFwcGVkIHRvIHplcm8gd2hlbiBhcHByb2FjaGluZyB0aGVcbiAqIGhvcml6b250YWwuXG4gKlxuICogVGhlICpjZW50ZXIgY29uc3RyYWludCogaXMgZGV0ZXJtaW5lZCBieSB0aGUgYGV4dGVudGAgb3B0aW9uLiBCeVxuICogZGVmYXVsdCB0aGUgdmlldyBjZW50ZXIgaXMgbm90IGNvbnN0cmFpbmVkIGF0IGFsbC5cbiAqXG4gKiAjIyMgQ2hhbmdpbmcgdGhlIHZpZXcgc3RhdGVcbiAqXG4gKiBJdCBpcyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IGBzZXRab29tYCwgYHNldFJlc29sdXRpb25gLCBgc2V0Q2VudGVyYCBhbmRcbiAqIGBzZXRSb3RhdGlvbmAgYXJlIHN1YmplY3QgdG8gdGhlIGFib3ZlIG1lbnRpb25lZCBjb25zdHJhaW50cy4gQXMgc3VjaCwgaXRcbiAqIG1heSBzb21ldGltZXMgbm90IGJlIHBvc3NpYmxlIHRvIGtub3cgaW4gYWR2YW5jZSB0aGUgcmVzdWx0aW5nIHN0YXRlIG9mIHRoZVxuICogVmlldy4gRm9yIGV4YW1wbGUsIGNhbGxpbmcgYHNldFJlc29sdXRpb24oMTApYCBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdFxuICogYGdldFJlc29sdXRpb24oKWAgd2lsbCByZXR1cm4gYDEwYC5cbiAqXG4gKiBBIGNvbnNlcXVlbmNlIG9mIHRoaXMgaXMgdGhhdCwgd2hlbiBhcHBseWluZyBhIGRlbHRhIG9uIHRoZSB2aWV3IHN0YXRlLCBvbmVcbiAqIHNob3VsZCB1c2UgYGFkanVzdENlbnRlcmAsIGBhZGp1c3RSb3RhdGlvbmAsIGBhZGp1c3Rab29tYCBhbmQgYGFkanVzdFJlc29sdXRpb25gXG4gKiByYXRoZXIgdGhhbiB0aGUgY29ycmVzcG9uZGluZyBzZXR0ZXJzLiBUaGlzIHdpbGwgbGV0IHZpZXcgZG8gaXRzIGludGVybmFsXG4gKiBjb21wdXRhdGlvbnMuIEJlc2lkZXMsIHRoZSBgYWRqdXN0KmAgbWV0aG9kcyBhbHNvIHRha2UgYW4gYG9wdF9hbmNob3JgXG4gKiBhcmd1bWVudCB3aGljaCBhbGxvd3Mgc3BlY2lmeWluZyBhbiBvcmlnaW4gZm9yIHRoZSB0cmFuc2Zvcm1hdGlvbi5cbiAqXG4gKiAjIyMgSW50ZXJhY3Rpbmcgd2l0aCB0aGUgdmlld1xuICpcbiAqIFZpZXcgY29uc3RyYWludHMgYXJlIHVzdWFsbHkgb25seSBhcHBsaWVkIHdoZW4gdGhlIHZpZXcgaXMgKmF0IHJlc3QqLCBtZWFuaW5nIHRoYXRcbiAqIG5vIGludGVyYWN0aW9uIG9yIGFuaW1hdGlvbiBpcyBvbmdvaW5nLiBBcyBzdWNoLCBpZiB0aGUgdXNlciBwdXRzIHRoZSB2aWV3IGluIGFcbiAqIHN0YXRlIHRoYXQgaXMgbm90IGVxdWl2YWxlbnQgdG8gYSBjb25zdHJhaW5lZCBvbmUgKGUuZy4gcm90YXRpbmcgdGhlIHZpZXcgd2hlblxuICogdGhlIHNuYXAgYW5nbGUgaXMgMCksIGFuIGFuaW1hdGlvbiB3aWxsIGJlIHRyaWdnZXJlZCBhdCB0aGUgaW50ZXJhY3Rpb24gZW5kIHRvXG4gKiBwdXQgYmFjayB0aGUgdmlldyB0byBhIHN0YWJsZSBzdGF0ZTtcbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIFZpZXcgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmlldywgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Vmlld09wdGlvbnM9fSBvcHRfb3B0aW9ucyBWaWV3IG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVmlldyhvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0X29wdGlvbnMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaW50c18gPSBbMCwgMF07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8QXJyYXk8QW5pbWF0aW9uPj59XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmltYXRpb25zXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy51cGRhdGVBbmltYXRpb25LZXlfO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGNvbnN0XG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5wcm9qZWN0aW9uXyA9IGNyZWF0ZVByb2plY3Rpb24ob3B0aW9ucy5wcm9qZWN0aW9uLCAnRVBTRzozODU3Jyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy52aWV3cG9ydFNpemVfID0gWzEwMCwgMTAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy50YXJnZXRDZW50ZXJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGFyZ2V0UmVzb2x1dGlvbl87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRhcmdldFJvdGF0aW9uXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5jYW5jZWxBbmNob3JfID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKG9wdGlvbnMuY2VudGVyKSB7XG4gICAgICBvcHRpb25zLmNlbnRlciA9IGZyb21Vc2VyQ29vcmRpbmF0ZShvcHRpb25zLmNlbnRlciwgX3RoaXMucHJvamVjdGlvbl8pO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmV4dGVudCkge1xuICAgICAgb3B0aW9ucy5leHRlbnQgPSBmcm9tVXNlckV4dGVudChvcHRpb25zLmV4dGVudCwgX3RoaXMucHJvamVjdGlvbl8pO1xuICAgIH1cblxuICAgIF90aGlzLmFwcGx5T3B0aW9uc18ob3B0aW9ucyk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFNldCB1cCB0aGUgdmlldyB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxuICAgKiBAcGFyYW0ge1ZpZXdPcHRpb25zfSBvcHRpb25zIFZpZXcgb3B0aW9ucy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hcHBseU9wdGlvbnNfID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgKj59XG4gICAgICovXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICB2YXIgcmVzb2x1dGlvbkNvbnN0cmFpbnRJbmZvID0gY3JlYXRlUmVzb2x1dGlvbkNvbnN0cmFpbnQob3B0aW9ucyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5tYXhSZXNvbHV0aW9uXyA9IHJlc29sdXRpb25Db25zdHJhaW50SW5mby5tYXhSZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMubWluUmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uQ29uc3RyYWludEluZm8ubWluUmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLnpvb21GYWN0b3JfID0gcmVzb2x1dGlvbkNvbnN0cmFpbnRJbmZvLnpvb21GYWN0b3I7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLnJlc29sdXRpb25zXyA9IG9wdGlvbnMucmVzb2x1dGlvbnM7XG4gICAgLyoqXG4gICAgICogUGFkZGluZyAoaW4gY3NzIHBpeGVscykuXG4gICAgICogSWYgdGhlIG1hcCB2aWV3cG9ydCBpcyBwYXJ0aWFsbHkgY292ZXJlZCB3aXRoIG90aGVyIGNvbnRlbnQgKG92ZXJsYXlzKSBhbG9uZ1xuICAgICAqIGl0cyBlZGdlcywgdGhpcyBzZXR0aW5nIGFsbG93cyB0byBzaGlmdCB0aGUgY2VudGVyIG9mIHRoZSB2aWV3cG9ydCBhd2F5IGZyb20gdGhhdFxuICAgICAqIGNvbnRlbnQuIFRoZSBvcmRlciBvZiB0aGUgdmFsdWVzIGluIHRoZSBhcnJheSBpcyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQuXG4gICAgICogVGhlIGRlZmF1bHQgaXMgbm8gcGFkZGluZywgd2hpY2ggaXMgZXF1aXZhbGVudCB0byBgWzAsIDAsIDAsIDBdYC5cbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPnx1bmRlZmluZWR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgdGhpcy5wYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMubWluWm9vbV8gPSByZXNvbHV0aW9uQ29uc3RyYWludEluZm8ubWluWm9vbTtcbiAgICB2YXIgY2VudGVyQ29uc3RyYWludCA9IGNyZWF0ZUNlbnRlckNvbnN0cmFpbnQob3B0aW9ucyk7XG4gICAgdmFyIHJlc29sdXRpb25Db25zdHJhaW50ID0gcmVzb2x1dGlvbkNvbnN0cmFpbnRJbmZvLmNvbnN0cmFpbnQ7XG4gICAgdmFyIHJvdGF0aW9uQ29uc3RyYWludCA9IGNyZWF0ZVJvdGF0aW9uQ29uc3RyYWludChvcHRpb25zKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtDb25zdHJhaW50c31cbiAgICAgKi9cblxuICAgIHRoaXMuY29uc3RyYWludHNfID0ge1xuICAgICAgY2VudGVyOiBjZW50ZXJDb25zdHJhaW50LFxuICAgICAgcmVzb2x1dGlvbjogcmVzb2x1dGlvbkNvbnN0cmFpbnQsXG4gICAgICByb3RhdGlvbjogcm90YXRpb25Db25zdHJhaW50XG4gICAgfTtcbiAgICB0aGlzLnNldFJvdGF0aW9uKG9wdGlvbnMucm90YXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucm90YXRpb24gOiAwKTtcbiAgICB0aGlzLnNldENlbnRlckludGVybmFsKG9wdGlvbnMuY2VudGVyICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNlbnRlciA6IG51bGwpO1xuXG4gICAgaWYgKG9wdGlvbnMucmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNldFJlc29sdXRpb24ob3B0aW9ucy5yZXNvbHV0aW9uKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMuem9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNldFpvb20ob3B0aW9ucy56b29tKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldFByb3BlcnRpZXMocHJvcGVydGllcyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Vmlld09wdGlvbnN9XG4gICAgICovXG5cbiAgICB0aGlzLm9wdGlvbnNfID0gb3B0aW9ucztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbiB1cGRhdGVkIHZlcnNpb24gb2YgdGhlIHZpZXcgb3B0aW9ucyB1c2VkIHRvIGNvbnN0cnVjdCB0aGUgdmlldy4gIFRoZVxuICAgKiBjdXJyZW50IHJlc29sdXRpb24gKG9yIHpvb20pLCBjZW50ZXIsIGFuZCByb3RhdGlvbiBhcmUgYXBwbGllZCB0byBhbnkgc3RvcmVkXG4gICAqIG9wdGlvbnMuICBUaGUgcHJvdmlkZWQgb3B0aW9ucyBjYW4gYmUgdXNlZCB0byBhcHBseSBuZXcgbWluL21heCB6b29tIG9yXG4gICAqIHJlc29sdXRpb24gbGltaXRzLlxuICAgKiBAcGFyYW0ge1ZpZXdPcHRpb25zfSBuZXdPcHRpb25zIE5ldyBvcHRpb25zIHRvIGJlIGFwcGxpZWQuXG4gICAqIEByZXR1cm4ge1ZpZXdPcHRpb25zfSBOZXcgb3B0aW9ucyB1cGRhdGVkIHdpdGggdGhlIGN1cnJlbnQgdmlldyBzdGF0ZS5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRVcGRhdGVkT3B0aW9uc18gPSBmdW5jdGlvbiAobmV3T3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zID0gYXNzaWduKHt9LCB0aGlzLm9wdGlvbnNfKTsgLy8gcHJlc2VydmUgcmVzb2x1dGlvbiAob3Igem9vbSlcblxuICAgIGlmIChvcHRpb25zLnJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0aW9ucy5yZXNvbHV0aW9uID0gdGhpcy5nZXRSZXNvbHV0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMuem9vbSA9IHRoaXMuZ2V0Wm9vbSgpO1xuICAgIH0gLy8gcHJlc2VydmUgY2VudGVyXG5cblxuICAgIG9wdGlvbnMuY2VudGVyID0gdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpOyAvLyBwcmVzZXJ2ZSByb3RhdGlvblxuXG4gICAgb3B0aW9ucy5yb3RhdGlvbiA9IHRoaXMuZ2V0Um90YXRpb24oKTtcbiAgICByZXR1cm4gYXNzaWduKHt9LCBvcHRpb25zLCBuZXdPcHRpb25zKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFuaW1hdGUgdGhlIHZpZXcuICBUaGUgdmlldydzIGNlbnRlciwgem9vbSAob3IgcmVzb2x1dGlvbiksIGFuZCByb3RhdGlvblxuICAgKiBjYW4gYmUgYW5pbWF0ZWQgZm9yIHNtb290aCB0cmFuc2l0aW9ucyBiZXR3ZWVuIHZpZXcgc3RhdGVzLiAgRm9yIGV4YW1wbGUsXG4gICAqIHRvIGFuaW1hdGUgdGhlIHZpZXcgdG8gYSBuZXcgem9vbSBsZXZlbDpcbiAgICpcbiAgICogICAgIHZpZXcuYW5pbWF0ZSh7em9vbTogdmlldy5nZXRab29tKCkgKyAxfSk7XG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHRoZSBhbmltYXRpb24gbGFzdHMgb25lIHNlY29uZCBhbmQgdXNlcyBpbi1hbmQtb3V0IGVhc2luZy4gIFlvdVxuICAgKiBjYW4gY3VzdG9taXplIHRoaXMgYmVoYXZpb3IgYnkgaW5jbHVkaW5nIGBkdXJhdGlvbmAgKGluIG1pbGxpc2Vjb25kcykgYW5kXG4gICAqIGBlYXNpbmdgIG9wdGlvbnMgKHNlZSB7QGxpbmsgbW9kdWxlOm9sL2Vhc2luZ30pLlxuICAgKlxuICAgKiBUbyBjaGFpbiB0b2dldGhlciBtdWx0aXBsZSBhbmltYXRpb25zLCBjYWxsIHRoZSBtZXRob2Qgd2l0aCBtdWx0aXBsZVxuICAgKiBhbmltYXRpb24gb2JqZWN0cy4gIEZvciBleGFtcGxlLCB0byBmaXJzdCB6b29tIGFuZCB0aGVuIHBhbjpcbiAgICpcbiAgICogICAgIHZpZXcuYW5pbWF0ZSh7em9vbTogMTB9LCB7Y2VudGVyOiBbMCwgMF19KTtcbiAgICpcbiAgICogSWYgeW91IHByb3ZpZGUgYSBmdW5jdGlvbiBhcyB0aGUgbGFzdCBhcmd1bWVudCB0byB0aGUgYW5pbWF0ZSBtZXRob2QsIGl0XG4gICAqIHdpbGwgZ2V0IGNhbGxlZCBhdCB0aGUgZW5kIG9mIGFuIGFuaW1hdGlvbiBzZXJpZXMuICBUaGUgY2FsbGJhY2sgd2lsbCBiZVxuICAgKiBjYWxsZWQgd2l0aCBgdHJ1ZWAgaWYgdGhlIGFuaW1hdGlvbiBzZXJpZXMgY29tcGxldGVkIG9uIGl0cyBvd24gb3IgYGZhbHNlYFxuICAgKiBpZiBpdCB3YXMgY2FuY2VsbGVkLlxuICAgKlxuICAgKiBBbmltYXRpb25zIGFyZSBjYW5jZWxsZWQgYnkgdXNlciBpbnRlcmFjdGlvbnMgKGUuZy4gZHJhZ2dpbmcgdGhlIG1hcCkgb3IgYnlcbiAgICogY2FsbGluZyBgdmlldy5zZXRDZW50ZXIoKWAsIGB2aWV3LnNldFJlc29sdXRpb24oKWAsIG9yIGB2aWV3LnNldFJvdGF0aW9uKClgXG4gICAqIChvciBhbm90aGVyIG1ldGhvZCB0aGF0IGNhbGxzIG9uZSBvZiB0aGVzZSkuXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uKEFuaW1hdGlvbk9wdGlvbnN8ZnVuY3Rpb24oYm9vbGVhbik6IHZvaWQpfSB2YXJfYXJncyBBbmltYXRpb25cbiAgICogICAgIG9wdGlvbnMuICBNdWx0aXBsZSBhbmltYXRpb25zIGNhbiBiZSBydW4gaW4gc2VyaWVzIGJ5IHBhc3NpbmcgbXVsdGlwbGVcbiAgICogICAgIG9wdGlvbnMgb2JqZWN0cy4gIFRvIHJ1biBtdWx0aXBsZSBhbmltYXRpb25zIGluIHBhcmFsbGVsLCBjYWxsIHRoZSBtZXRob2RcbiAgICogICAgIG11bHRpcGxlIHRpbWVzLiAgQW4gb3B0aW9uYWwgY2FsbGJhY2sgY2FuIGJlIHByb3ZpZGVkIGFzIGEgZmluYWxcbiAgICogICAgIGFyZ3VtZW50LiAgVGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdpdGggYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlclxuICAgKiAgICAgdGhlIGFuaW1hdGlvbiBjb21wbGV0ZWQgd2l0aG91dCBiZWluZyBjYW5jZWxsZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hbmltYXRlID0gZnVuY3Rpb24gKHZhcl9hcmdzKSB7XG4gICAgaWYgKHRoaXMuaXNEZWYoKSAmJiAhdGhpcy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgdGhpcy5yZXNvbHZlQ29uc3RyYWludHMoMCk7XG4gICAgfVxuXG4gICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICBpZiAob3B0aW9ucy5jZW50ZXIpIHtcbiAgICAgICAgb3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgICAgIG9wdGlvbnMuY2VudGVyID0gZnJvbVVzZXJDb29yZGluYXRlKG9wdGlvbnMuY2VudGVyLCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmFuY2hvcikge1xuICAgICAgICBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRpb25zKTtcbiAgICAgICAgb3B0aW9ucy5hbmNob3IgPSBmcm9tVXNlckNvb3JkaW5hdGUob3B0aW9ucy5hbmNob3IsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICAgIH1cblxuICAgICAgYXJnc1tpXSA9IG9wdGlvbnM7XG4gICAgfVxuXG4gICAgdGhpcy5hbmltYXRlSW50ZXJuYWwuYXBwbHkodGhpcywgYXJncyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0gey4uLihBbmltYXRpb25PcHRpb25zfGZ1bmN0aW9uKGJvb2xlYW4pOiB2b2lkKX0gdmFyX2FyZ3MgQW5pbWF0aW9uIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYW5pbWF0ZUludGVybmFsID0gZnVuY3Rpb24gKHZhcl9hcmdzKSB7XG4gICAgdmFyIGFuaW1hdGlvbkNvdW50ID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgY2FsbGJhY2s7XG5cbiAgICBpZiAoYW5pbWF0aW9uQ291bnQgPiAxICYmIHR5cGVvZiBhcmd1bWVudHNbYW5pbWF0aW9uQ291bnQgLSAxXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2sgPSBhcmd1bWVudHNbYW5pbWF0aW9uQ291bnQgLSAxXTtcbiAgICAgIC0tYW5pbWF0aW9uQ291bnQ7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmlzRGVmKCkpIHtcbiAgICAgIC8vIGlmIHZpZXcgcHJvcGVydGllcyBhcmUgbm90IHlldCBzZXQsIHNob3J0Y3V0IHRvIHRoZSBmaW5hbCBzdGF0ZVxuICAgICAgdmFyIHN0YXRlID0gYXJndW1lbnRzW2FuaW1hdGlvbkNvdW50IC0gMV07XG5cbiAgICAgIGlmIChzdGF0ZS5jZW50ZXIpIHtcbiAgICAgICAgdGhpcy5zZXRDZW50ZXJJbnRlcm5hbChzdGF0ZS5jZW50ZXIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3RhdGUuem9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuc2V0Wm9vbShzdGF0ZS56b29tKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlLnJvdGF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5zZXRSb3RhdGlvbihzdGF0ZS5yb3RhdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICBhbmltYXRpb25DYWxsYmFjayhjYWxsYmFjaywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHZhciBjZW50ZXIgPSB0aGlzLnRhcmdldENlbnRlcl8uc2xpY2UoKTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMudGFyZ2V0UmVzb2x1dGlvbl87XG4gICAgdmFyIHJvdGF0aW9uID0gdGhpcy50YXJnZXRSb3RhdGlvbl87XG4gICAgdmFyIHNlcmllcyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbmltYXRpb25Db3VudDsgKytpKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9XG4gICAgICAvKiogQHR5cGUge0FuaW1hdGlvbk9wdGlvbnN9ICovXG4gICAgICBhcmd1bWVudHNbaV07XG4gICAgICB2YXIgYW5pbWF0aW9uID0ge1xuICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgIGNvbXBsZXRlOiBmYWxzZSxcbiAgICAgICAgYW5jaG9yOiBvcHRpb25zLmFuY2hvcixcbiAgICAgICAgZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAxMDAwLFxuICAgICAgICBlYXNpbmc6IG9wdGlvbnMuZWFzaW5nIHx8IGluQW5kT3V0LFxuICAgICAgICBjYWxsYmFjazogY2FsbGJhY2tcbiAgICAgIH07XG5cbiAgICAgIGlmIChvcHRpb25zLmNlbnRlcikge1xuICAgICAgICBhbmltYXRpb24uc291cmNlQ2VudGVyID0gY2VudGVyO1xuICAgICAgICBhbmltYXRpb24udGFyZ2V0Q2VudGVyID0gb3B0aW9ucy5jZW50ZXIuc2xpY2UoKTtcbiAgICAgICAgY2VudGVyID0gYW5pbWF0aW9uLnRhcmdldENlbnRlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMuem9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFuaW1hdGlvbi5zb3VyY2VSZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAgICAgYW5pbWF0aW9uLnRhcmdldFJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb25Gb3Jab29tKG9wdGlvbnMuem9vbSk7XG4gICAgICAgIHJlc29sdXRpb24gPSBhbmltYXRpb24udGFyZ2V0UmVzb2x1dGlvbjtcbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5yZXNvbHV0aW9uKSB7XG4gICAgICAgIGFuaW1hdGlvbi5zb3VyY2VSZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAgICAgYW5pbWF0aW9uLnRhcmdldFJlc29sdXRpb24gPSBvcHRpb25zLnJlc29sdXRpb247XG4gICAgICAgIHJlc29sdXRpb24gPSBhbmltYXRpb24udGFyZ2V0UmVzb2x1dGlvbjtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMucm90YXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhbmltYXRpb24uc291cmNlUm90YXRpb24gPSByb3RhdGlvbjtcbiAgICAgICAgdmFyIGRlbHRhID0gbW9kdWxvKG9wdGlvbnMucm90YXRpb24gLSByb3RhdGlvbiArIE1hdGguUEksIDIgKiBNYXRoLlBJKSAtIE1hdGguUEk7XG4gICAgICAgIGFuaW1hdGlvbi50YXJnZXRSb3RhdGlvbiA9IHJvdGF0aW9uICsgZGVsdGE7XG4gICAgICAgIHJvdGF0aW9uID0gYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uO1xuICAgICAgfSAvLyBjaGVjayBpZiBhbmltYXRpb24gaXMgYSBuby1vcFxuXG5cbiAgICAgIGlmIChpc05vb3BBbmltYXRpb24oYW5pbWF0aW9uKSkge1xuICAgICAgICBhbmltYXRpb24uY29tcGxldGUgPSB0cnVlOyAvLyB3ZSBzdGlsbCBwdXNoIGl0IG9udG8gdGhlIHNlcmllcyBmb3IgY2FsbGJhY2sgaGFuZGxpbmdcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ICs9IGFuaW1hdGlvbi5kdXJhdGlvbjtcbiAgICAgIH1cblxuICAgICAgc2VyaWVzLnB1c2goYW5pbWF0aW9uKTtcbiAgICB9XG5cbiAgICB0aGlzLmFuaW1hdGlvbnNfLnB1c2goc2VyaWVzKTtcbiAgICB0aGlzLnNldEhpbnQoVmlld0hpbnQuQU5JTUFUSU5HLCAxKTtcbiAgICB0aGlzLnVwZGF0ZUFuaW1hdGlvbnNfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgaWYgdGhlIHZpZXcgaXMgYmVpbmcgYW5pbWF0ZWQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB2aWV3IGlzIGJlaW5nIGFuaW1hdGVkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0QW5pbWF0aW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmhpbnRzX1tWaWV3SGludC5BTklNQVRJTkddID4gMDtcbiAgfTtcbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgdXNlciBpcyBpbnRlcmFjdGluZyB3aXRoIHRoZSB2aWV3LCBzdWNoIGFzIHBhbm5pbmcgb3Igem9vbWluZy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHZpZXcgaXMgYmVpbmcgaW50ZXJhY3RlZCB3aXRoLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0SW50ZXJhY3RpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGludHNfW1ZpZXdIaW50LklOVEVSQUNUSU5HXSA+IDA7XG4gIH07XG4gIC8qKlxuICAgKiBDYW5jZWwgYW55IG9uZ29pbmcgYW5pbWF0aW9ucy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNhbmNlbEFuaW1hdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRIaW50KFZpZXdIaW50LkFOSU1BVElORywgLXRoaXMuaGludHNfW1ZpZXdIaW50LkFOSU1BVElOR10pO1xuICAgIHZhciBhbmNob3I7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSB0aGlzLmFuaW1hdGlvbnNfLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBzZXJpZXMgPSB0aGlzLmFuaW1hdGlvbnNfW2ldO1xuXG4gICAgICBpZiAoc2VyaWVzWzBdLmNhbGxiYWNrKSB7XG4gICAgICAgIGFuaW1hdGlvbkNhbGxiYWNrKHNlcmllc1swXS5jYWxsYmFjaywgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWFuY2hvcikge1xuICAgICAgICBmb3IgKHZhciBqID0gMCwgamogPSBzZXJpZXMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgIHZhciBhbmltYXRpb24gPSBzZXJpZXNbal07XG5cbiAgICAgICAgICBpZiAoIWFuaW1hdGlvbi5jb21wbGV0ZSkge1xuICAgICAgICAgICAgYW5jaG9yID0gYW5pbWF0aW9uLmFuY2hvcjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuYW5pbWF0aW9uc18ubGVuZ3RoID0gMDtcbiAgICB0aGlzLmNhbmNlbEFuY2hvcl8gPSBhbmNob3I7XG4gIH07XG4gIC8qKlxuICAgKiBVcGRhdGUgYWxsIGFuaW1hdGlvbnMuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUudXBkYXRlQW5pbWF0aW9uc18gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMudXBkYXRlQW5pbWF0aW9uS2V5XyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLnVwZGF0ZUFuaW1hdGlvbktleV8pO1xuICAgICAgdGhpcy51cGRhdGVBbmltYXRpb25LZXlfID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICAgIHZhciBtb3JlID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gdGhpcy5hbmltYXRpb25zXy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdmFyIHNlcmllcyA9IHRoaXMuYW5pbWF0aW9uc19baV07XG4gICAgICB2YXIgc2VyaWVzQ29tcGxldGUgPSB0cnVlO1xuXG4gICAgICBmb3IgKHZhciBqID0gMCwgamogPSBzZXJpZXMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICB2YXIgYW5pbWF0aW9uID0gc2VyaWVzW2pdO1xuXG4gICAgICAgIGlmIChhbmltYXRpb24uY29tcGxldGUpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlbGFwc2VkID0gbm93IC0gYW5pbWF0aW9uLnN0YXJ0O1xuICAgICAgICB2YXIgZnJhY3Rpb24gPSBhbmltYXRpb24uZHVyYXRpb24gPiAwID8gZWxhcHNlZCAvIGFuaW1hdGlvbi5kdXJhdGlvbiA6IDE7XG5cbiAgICAgICAgaWYgKGZyYWN0aW9uID49IDEpIHtcbiAgICAgICAgICBhbmltYXRpb24uY29tcGxldGUgPSB0cnVlO1xuICAgICAgICAgIGZyYWN0aW9uID0gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZXJpZXNDb21wbGV0ZSA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHByb2dyZXNzID0gYW5pbWF0aW9uLmVhc2luZyhmcmFjdGlvbik7XG5cbiAgICAgICAgaWYgKGFuaW1hdGlvbi5zb3VyY2VDZW50ZXIpIHtcbiAgICAgICAgICB2YXIgeDAgPSBhbmltYXRpb24uc291cmNlQ2VudGVyWzBdO1xuICAgICAgICAgIHZhciB5MCA9IGFuaW1hdGlvbi5zb3VyY2VDZW50ZXJbMV07XG4gICAgICAgICAgdmFyIHgxID0gYW5pbWF0aW9uLnRhcmdldENlbnRlclswXTtcbiAgICAgICAgICB2YXIgeTEgPSBhbmltYXRpb24udGFyZ2V0Q2VudGVyWzFdO1xuICAgICAgICAgIHZhciB4ID0geDAgKyBwcm9ncmVzcyAqICh4MSAtIHgwKTtcbiAgICAgICAgICB2YXIgeSA9IHkwICsgcHJvZ3Jlc3MgKiAoeTEgLSB5MCk7XG4gICAgICAgICAgdGhpcy50YXJnZXRDZW50ZXJfID0gW3gsIHldO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFuaW1hdGlvbi5zb3VyY2VSZXNvbHV0aW9uICYmIGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uKSB7XG4gICAgICAgICAgdmFyIHJlc29sdXRpb24gPSBwcm9ncmVzcyA9PT0gMSA/IGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uIDogYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24gKyBwcm9ncmVzcyAqIChhbmltYXRpb24udGFyZ2V0UmVzb2x1dGlvbiAtIGFuaW1hdGlvbi5zb3VyY2VSZXNvbHV0aW9uKTtcblxuICAgICAgICAgIGlmIChhbmltYXRpb24uYW5jaG9yKSB7XG4gICAgICAgICAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplXyh0aGlzLmdldFJvdGF0aW9uKCkpO1xuICAgICAgICAgICAgdmFyIGNvbnN0cmFpbmVkUmVzb2x1dGlvbiA9IHRoaXMuY29uc3RyYWludHNfLnJlc29sdXRpb24ocmVzb2x1dGlvbiwgMCwgc2l6ZSwgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSB0aGlzLmNhbGN1bGF0ZUNlbnRlclpvb20oY29uc3RyYWluZWRSZXNvbHV0aW9uLCBhbmltYXRpb24uYW5jaG9yKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnRhcmdldFJlc29sdXRpb25fID0gcmVzb2x1dGlvbjtcbiAgICAgICAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFuaW1hdGlvbi5zb3VyY2VSb3RhdGlvbiAhPT0gdW5kZWZpbmVkICYmIGFuaW1hdGlvbi50YXJnZXRSb3RhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFyIHJvdGF0aW9uID0gcHJvZ3Jlc3MgPT09IDEgPyBtb2R1bG8oYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uICsgTWF0aC5QSSwgMiAqIE1hdGguUEkpIC0gTWF0aC5QSSA6IGFuaW1hdGlvbi5zb3VyY2VSb3RhdGlvbiArIHByb2dyZXNzICogKGFuaW1hdGlvbi50YXJnZXRSb3RhdGlvbiAtIGFuaW1hdGlvbi5zb3VyY2VSb3RhdGlvbik7XG5cbiAgICAgICAgICBpZiAoYW5pbWF0aW9uLmFuY2hvcikge1xuICAgICAgICAgICAgdmFyIGNvbnN0cmFpbmVkUm90YXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yb3RhdGlvbihyb3RhdGlvbiwgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSB0aGlzLmNhbGN1bGF0ZUNlbnRlclJvdGF0ZShjb25zdHJhaW5lZFJvdGF0aW9uLCBhbmltYXRpb24uYW5jaG9yKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnRhcmdldFJvdGF0aW9uXyA9IHJvdGF0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5hcHBseVRhcmdldFN0YXRlXyh0cnVlKTtcbiAgICAgICAgbW9yZSA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFhbmltYXRpb24uY29tcGxldGUpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc2VyaWVzQ29tcGxldGUpIHtcbiAgICAgICAgdGhpcy5hbmltYXRpb25zX1tpXSA9IG51bGw7XG4gICAgICAgIHRoaXMuc2V0SGludChWaWV3SGludC5BTklNQVRJTkcsIC0xKTtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gc2VyaWVzWzBdLmNhbGxiYWNrO1xuXG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgIGFuaW1hdGlvbkNhbGxiYWNrKGNhbGxiYWNrLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gLy8gcHJ1bmUgY29tcGxldGVkIHNlcmllc1xuXG5cbiAgICB0aGlzLmFuaW1hdGlvbnNfID0gdGhpcy5hbmltYXRpb25zXy5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICBpZiAobW9yZSAmJiB0aGlzLnVwZGF0ZUFuaW1hdGlvbktleV8gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy51cGRhdGVBbmltYXRpb25LZXlfID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMudXBkYXRlQW5pbWF0aW9uc18uYmluZCh0aGlzKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFRhcmdldCByb3RhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYW5jaG9yIFJvdGF0aW9uIGFuY2hvci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBDZW50ZXIgZm9yIHJvdGF0aW9uIGFuZCBhbmNob3IuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2FsY3VsYXRlQ2VudGVyUm90YXRlID0gZnVuY3Rpb24gKHJvdGF0aW9uLCBhbmNob3IpIHtcbiAgICB2YXIgY2VudGVyO1xuICAgIHZhciBjdXJyZW50Q2VudGVyID0gdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuXG4gICAgaWYgKGN1cnJlbnRDZW50ZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2VudGVyID0gW2N1cnJlbnRDZW50ZXJbMF0gLSBhbmNob3JbMF0sIGN1cnJlbnRDZW50ZXJbMV0gLSBhbmNob3JbMV1dO1xuICAgICAgcm90YXRlQ29vcmRpbmF0ZShjZW50ZXIsIHJvdGF0aW9uIC0gdGhpcy5nZXRSb3RhdGlvbigpKTtcbiAgICAgIGFkZENvb3JkaW5hdGUoY2VudGVyLCBhbmNob3IpO1xuICAgIH1cblxuICAgIHJldHVybiBjZW50ZXI7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBUYXJnZXQgcmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYW5jaG9yIFpvb20gYW5jaG9yLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IENlbnRlciBmb3IgcmVzb2x1dGlvbiBhbmQgYW5jaG9yLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNhbGN1bGF0ZUNlbnRlclpvb20gPSBmdW5jdGlvbiAocmVzb2x1dGlvbiwgYW5jaG9yKSB7XG4gICAgdmFyIGNlbnRlcjtcbiAgICB2YXIgY3VycmVudENlbnRlciA9IHRoaXMuZ2V0Q2VudGVySW50ZXJuYWwoKTtcbiAgICB2YXIgY3VycmVudFJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24oKTtcblxuICAgIGlmIChjdXJyZW50Q2VudGVyICE9PSB1bmRlZmluZWQgJiYgY3VycmVudFJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIHggPSBhbmNob3JbMF0gLSByZXNvbHV0aW9uICogKGFuY2hvclswXSAtIGN1cnJlbnRDZW50ZXJbMF0pIC8gY3VycmVudFJlc29sdXRpb247XG4gICAgICB2YXIgeSA9IGFuY2hvclsxXSAtIHJlc29sdXRpb24gKiAoYW5jaG9yWzFdIC0gY3VycmVudENlbnRlclsxXSkgLyBjdXJyZW50UmVzb2x1dGlvbjtcbiAgICAgIGNlbnRlciA9IFt4LCB5XTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2VudGVyO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCB2aWV3cG9ydCBzaXplLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9yb3RhdGlvbiBUYWtlIGludG8gYWNjb3VudCB0aGUgcm90YXRpb24gb2YgdGhlIHZpZXdwb3J0IHdoZW4gZ2l2aW5nIHRoZSBzaXplXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBWaWV3cG9ydCBzaXplIG9yIGBbMTAwLCAxMDBdYCB3aGVuIG5vIHZpZXdwb3J0IGlzIGZvdW5kLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFZpZXdwb3J0U2l6ZV8gPSBmdW5jdGlvbiAob3B0X3JvdGF0aW9uKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLnZpZXdwb3J0U2l6ZV87XG5cbiAgICBpZiAob3B0X3JvdGF0aW9uKSB7XG4gICAgICB2YXIgdyA9IHNpemVbMF07XG4gICAgICB2YXIgaCA9IHNpemVbMV07XG4gICAgICByZXR1cm4gW01hdGguYWJzKHcgKiBNYXRoLmNvcyhvcHRfcm90YXRpb24pKSArIE1hdGguYWJzKGggKiBNYXRoLnNpbihvcHRfcm90YXRpb24pKSwgTWF0aC5hYnModyAqIE1hdGguc2luKG9wdF9yb3RhdGlvbikpICsgTWF0aC5hYnMoaCAqIE1hdGguY29zKG9wdF9yb3RhdGlvbikpXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNpemU7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU3RvcmVzIHRoZSB2aWV3cG9ydCBzaXplIG9uIHRoZSB2aWV3LiBUaGUgdmlld3BvcnQgc2l6ZSBpcyBub3QgcmVhZCBldmVyeSB0aW1lIGZyb20gdGhlIERPTVxuICAgKiB0byBhdm9pZCBwZXJmb3JtYW5jZSBoaXQgYW5kIGxheW91dCByZWZsb3cuXG4gICAqIFRoaXMgc2hvdWxkIGJlIGRvbmUgb24gbWFwIHNpemUgY2hhbmdlLlxuICAgKiBOb3RlOiB0aGUgY29uc3RyYWludHMgYXJlIG5vdCByZXNvbHZlZCBkdXJpbmcgYW4gYW5pbWF0aW9uIHRvIGF2b2lkIHN0b3BwaW5nIGl0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemU9fSBvcHRfc2l6ZSBWaWV3cG9ydCBzaXplOyBpZiB1bmRlZmluZWQsIFsxMDAsIDEwMF0gaXMgYXNzdW1lZFxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldFZpZXdwb3J0U2l6ZSA9IGZ1bmN0aW9uIChvcHRfc2l6ZSkge1xuICAgIHRoaXMudmlld3BvcnRTaXplXyA9IEFycmF5LmlzQXJyYXkob3B0X3NpemUpID8gb3B0X3NpemUuc2xpY2UoKSA6IFsxMDAsIDEwMF07XG5cbiAgICBpZiAoIXRoaXMuZ2V0QW5pbWF0aW5nKCkpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUNvbnN0cmFpbnRzKDApO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdmlldyBjZW50ZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gVGhlIGNlbnRlciBvZiB0aGUgdmlldy5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldENlbnRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2VudGVyID0gdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuXG4gICAgaWYgKCFjZW50ZXIpIHtcbiAgICAgIHJldHVybiBjZW50ZXI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvVXNlckNvb3JkaW5hdGUoY2VudGVyLCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZpZXcgY2VudGVyIHdpdGhvdXQgdHJhbnNmb3JtaW5nIHRvIHVzZXIgcHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSBUaGUgY2VudGVyIG9mIHRoZSB2aWV3LlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldENlbnRlckludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KFZpZXdQcm9wZXJ0eS5DRU5URVIpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0NvbnN0cmFpbnRzfSBDb25zdHJhaW50cy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRDb25zdHJhaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJhaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBSZXNvbHV0aW9uIGNvbnN0cmFpbnQgaXMgc2V0XG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Q29uc3RyYWluUmVzb2x1dGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zXy5jb25zdHJhaW5SZXNvbHV0aW9uO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2hpbnRzIERlc3RpbmF0aW9uIGFycmF5LlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBIaW50LlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldEhpbnRzID0gZnVuY3Rpb24gKG9wdF9oaW50cykge1xuICAgIGlmIChvcHRfaGludHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb3B0X2hpbnRzWzBdID0gdGhpcy5oaW50c19bMF07XG4gICAgICBvcHRfaGludHNbMV0gPSB0aGlzLmhpbnRzX1sxXTtcbiAgICAgIHJldHVybiBvcHRfaGludHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmhpbnRzXy5zbGljZSgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZSB0aGUgZXh0ZW50IGZvciB0aGUgY3VycmVudCB2aWV3IHN0YXRlIGFuZCB0aGUgcGFzc2VkIHNpemUuXG4gICAqIFRoZSBzaXplIGlzIHRoZSBwaXhlbCBkaW1lbnNpb25zIG9mIHRoZSBib3ggaW50byB3aGljaCB0aGUgY2FsY3VsYXRlZCBleHRlbnRcbiAgICogc2hvdWxkIGZpdC4gSW4gbW9zdCBjYXNlcyB5b3Ugd2FudCB0byBnZXQgdGhlIGV4dGVudCBvZiB0aGUgZW50aXJlIG1hcCxcbiAgICogdGhhdCBpcyBgbWFwLmdldFNpemUoKWAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemU9fSBvcHRfc2l6ZSBCb3ggcGl4ZWwgc2l6ZS4gSWYgbm90IHByb3ZpZGVkLCB0aGUgc2l6ZVxuICAgKiBvZiB0aGUgbWFwIHRoYXQgdXNlcyB0aGlzIHZpZXcgd2lsbCBiZSB1c2VkLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNhbGN1bGF0ZUV4dGVudCA9IGZ1bmN0aW9uIChvcHRfc2l6ZSkge1xuICAgIHZhciBleHRlbnQgPSB0aGlzLmNhbGN1bGF0ZUV4dGVudEludGVybmFsKG9wdF9zaXplKTtcbiAgICByZXR1cm4gdG9Vc2VyRXh0ZW50KGV4dGVudCwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF9zaXplIEJveCBwaXhlbCBzaXplLiBJZiBub3QgcHJvdmlkZWQsXG4gICAqIHRoZSBtYXAncyBsYXN0IGtub3duIHZpZXdwb3J0IHNpemUgd2lsbCBiZSB1c2VkLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5jYWxjdWxhdGVFeHRlbnRJbnRlcm5hbCA9IGZ1bmN0aW9uIChvcHRfc2l6ZSkge1xuICAgIHZhciBzaXplID0gb3B0X3NpemUgfHwgdGhpcy5nZXRWaWV3cG9ydFNpemVfKCk7XG4gICAgdmFyIGNlbnRlciA9XG4gICAgLyoqIEB0eXBlIHshaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9ICovXG4gICAgdGhpcy5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuICAgIGFzc2VydChjZW50ZXIsIDEpOyAvLyBUaGUgdmlldyBjZW50ZXIgaXMgbm90IGRlZmluZWRcblxuICAgIHZhciByZXNvbHV0aW9uID1cbiAgICAvKiogQHR5cGUgeyFudW1iZXJ9ICovXG4gICAgdGhpcy5nZXRSZXNvbHV0aW9uKCk7XG4gICAgYXNzZXJ0KHJlc29sdXRpb24gIT09IHVuZGVmaW5lZCwgMik7IC8vIFRoZSB2aWV3IHJlc29sdXRpb24gaXMgbm90IGRlZmluZWRcblxuICAgIHZhciByb3RhdGlvbiA9XG4gICAgLyoqIEB0eXBlIHshbnVtYmVyfSAqL1xuICAgIHRoaXMuZ2V0Um90YXRpb24oKTtcbiAgICBhc3NlcnQocm90YXRpb24gIT09IHVuZGVmaW5lZCwgMyk7IC8vIFRoZSB2aWV3IHJvdGF0aW9uIGlzIG5vdCBkZWZpbmVkXG5cbiAgICByZXR1cm4gZ2V0Rm9yVmlld0FuZFNpemUoY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgc2l6ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gcmVzb2x1dGlvbiBvZiB0aGUgdmlldy5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIG9mIHRoZSB2aWV3LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0TWF4UmVzb2x1dGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXhSZXNvbHV0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWluaW11bSByZXNvbHV0aW9uIG9mIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtaW5pbXVtIHJlc29sdXRpb24gb2YgdGhlIHZpZXcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRNaW5SZXNvbHV0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1pblJlc29sdXRpb25fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXhpbXVtIHpvb20gbGV2ZWwgZm9yIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBtYXhpbXVtIHpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRNYXhab29tID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgIHRoaXMuZ2V0Wm9vbUZvclJlc29sdXRpb24odGhpcy5taW5SZXNvbHV0aW9uXylcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IGEgbmV3IG1heGltdW0gem9vbSBsZXZlbCBmb3IgdGhlIHZpZXcuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFRoZSBtYXhpbXVtIHpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRNYXhab29tID0gZnVuY3Rpb24gKHpvb20pIHtcbiAgICB0aGlzLmFwcGx5T3B0aW9uc18odGhpcy5nZXRVcGRhdGVkT3B0aW9uc18oe1xuICAgICAgbWF4Wm9vbTogem9vbVxuICAgIH0pKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWluaW11bSB6b29tIGxldmVsIGZvciB0aGUgdmlldy5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbWluaW11bSB6b29tIGxldmVsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0TWluWm9vbSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldFpvb21Gb3JSZXNvbHV0aW9uKHRoaXMubWF4UmVzb2x1dGlvbl8pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBhIG5ldyBtaW5pbXVtIHpvb20gbGV2ZWwgZm9yIHRoZSB2aWV3LlxuICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSBUaGUgbWluaW11bSB6b29tIGxldmVsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0TWluWm9vbSA9IGZ1bmN0aW9uICh6b29tKSB7XG4gICAgdGhpcy5hcHBseU9wdGlvbnNfKHRoaXMuZ2V0VXBkYXRlZE9wdGlvbnNfKHtcbiAgICAgIG1pblpvb206IHpvb21cbiAgICB9KSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgd2hldGhlciB0aGUgdmlldyBzaG91ZCBhbGxvdyBpbnRlcm1lZGlhcnkgem9vbSBsZXZlbHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZW5hYmxlZCBXaGV0aGVyIHRoZSByZXNvbHV0aW9uIGlzIGNvbnN0cmFpbmVkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0Q29uc3RyYWluUmVzb2x1dGlvbiA9IGZ1bmN0aW9uIChlbmFibGVkKSB7XG4gICAgdGhpcy5hcHBseU9wdGlvbnNfKHRoaXMuZ2V0VXBkYXRlZE9wdGlvbnNfKHtcbiAgICAgIGNvbnN0cmFpblJlc29sdXRpb246IGVuYWJsZWRcbiAgICB9KSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZpZXcgcHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gVGhlIHByb2plY3Rpb24gb2YgdGhlIHZpZXcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRQcm9qZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnByb2plY3Rpb25fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB2aWV3IHJlc29sdXRpb24uXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFRoZSByZXNvbHV0aW9uIG9mIHRoZSB2aWV3LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoVmlld1Byb3BlcnR5LlJFU09MVVRJT04pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcmVzb2x1dGlvbnMgZm9yIHRoZSB2aWV3LiBUaGlzIHJldHVybnMgdGhlIGFycmF5IG9mIHJlc29sdXRpb25zXG4gICAqIHBhc3NlZCB0byB0aGUgY29uc3RydWN0b3Igb2YgdGhlIFZpZXcsIG9yIHVuZGVmaW5lZCBpZiBub25lIHdlcmUgZ2l2ZW4uXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj58dW5kZWZpbmVkfSBUaGUgcmVzb2x1dGlvbnMgb2YgdGhlIHZpZXcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSZXNvbHV0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHV0aW9uc187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlc29sdXRpb24gZm9yIGEgcHJvdmlkZWQgZXh0ZW50IChpbiBtYXAgdW5pdHMpIGFuZCBzaXplIChpbiBwaXhlbHMpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF9zaXplIEJveCBwaXhlbCBzaXplLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSByZXNvbHV0aW9uIGF0IHdoaWNoIHRoZSBwcm92aWRlZCBleHRlbnQgd2lsbCByZW5kZXIgYXRcbiAgICogICAgIHRoZSBnaXZlbiBzaXplLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbkZvckV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQsIG9wdF9zaXplKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVzb2x1dGlvbkZvckV4dGVudEludGVybmFsKGZyb21Vc2VyRXh0ZW50KGV4dGVudCwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpLCBvcHRfc2l6ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlc29sdXRpb24gZm9yIGEgcHJvdmlkZWQgZXh0ZW50IChpbiBtYXAgdW5pdHMpIGFuZCBzaXplIChpbiBwaXhlbHMpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF9zaXplIEJveCBwaXhlbCBzaXplLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSByZXNvbHV0aW9uIGF0IHdoaWNoIHRoZSBwcm92aWRlZCBleHRlbnQgd2lsbCByZW5kZXIgYXRcbiAgICogICAgIHRoZSBnaXZlbiBzaXplLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFJlc29sdXRpb25Gb3JFeHRlbnRJbnRlcm5hbCA9IGZ1bmN0aW9uIChleHRlbnQsIG9wdF9zaXplKSB7XG4gICAgdmFyIHNpemUgPSBvcHRfc2l6ZSB8fCB0aGlzLmdldFZpZXdwb3J0U2l6ZV8oKTtcbiAgICB2YXIgeFJlc29sdXRpb24gPSBnZXRXaWR0aChleHRlbnQpIC8gc2l6ZVswXTtcbiAgICB2YXIgeVJlc29sdXRpb24gPSBnZXRIZWlnaHQoZXh0ZW50KSAvIHNpemVbMV07XG4gICAgcmV0dXJuIE1hdGgubWF4KHhSZXNvbHV0aW9uLCB5UmVzb2x1dGlvbik7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDEgZm9yIGFcbiAgICogcmVzb2x1dGlvbi4gRXhwb25lbnRpYWwgc2NhbGluZyBpcyBhc3N1bWVkLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9wb3dlciBQb3dlci5cbiAgICogQHJldHVybiB7ZnVuY3Rpb24obnVtYmVyKTogbnVtYmVyfSBSZXNvbHV0aW9uIGZvciB2YWx1ZSBmdW5jdGlvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSZXNvbHV0aW9uRm9yVmFsdWVGdW5jdGlvbiA9IGZ1bmN0aW9uIChvcHRfcG93ZXIpIHtcbiAgICB2YXIgcG93ZXIgPSBvcHRfcG93ZXIgfHwgMjtcbiAgICB2YXIgbWF4UmVzb2x1dGlvbiA9IHRoaXMuZ2V0Q29uc3RyYWluZWRSZXNvbHV0aW9uKHRoaXMubWF4UmVzb2x1dGlvbl8pO1xuICAgIHZhciBtaW5SZXNvbHV0aW9uID0gdGhpcy5taW5SZXNvbHV0aW9uXztcbiAgICB2YXIgbWF4ID0gTWF0aC5sb2cobWF4UmVzb2x1dGlvbiAvIG1pblJlc29sdXRpb24pIC8gTWF0aC5sb2cocG93ZXIpO1xuICAgIHJldHVybiAoXG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZS5cbiAgICAgICAqIEByZXR1cm4ge251bWJlcn0gUmVzb2x1dGlvbi5cbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByZXNvbHV0aW9uID0gbWF4UmVzb2x1dGlvbiAvIE1hdGgucG93KHBvd2VyLCB2YWx1ZSAqIG1heCk7XG4gICAgICAgIHJldHVybiByZXNvbHV0aW9uO1xuICAgICAgfVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZpZXcgcm90YXRpb24uXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIHJvdGF0aW9uIG9mIHRoZSB2aWV3IGluIHJhZGlhbnMuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRSb3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChWaWV3UHJvcGVydHkuUk9UQVRJT04pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHJlc29sdXRpb24gZm9yIGEgdmFsdWUgYmV0d2VlblxuICAgKiAwIGFuZCAxLiBFeHBvbmVudGlhbCBzY2FsaW5nIGlzIGFzc3VtZWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3Bvd2VyIFBvd2VyLlxuICAgKiBAcmV0dXJuIHtmdW5jdGlvbihudW1iZXIpOiBudW1iZXJ9IFZhbHVlIGZvciByZXNvbHV0aW9uIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFZhbHVlRm9yUmVzb2x1dGlvbkZ1bmN0aW9uID0gZnVuY3Rpb24gKG9wdF9wb3dlcikge1xuICAgIHZhciBsb2dQb3dlciA9IE1hdGgubG9nKG9wdF9wb3dlciB8fCAyKTtcbiAgICB2YXIgbWF4UmVzb2x1dGlvbiA9IHRoaXMuZ2V0Q29uc3RyYWluZWRSZXNvbHV0aW9uKHRoaXMubWF4UmVzb2x1dGlvbl8pO1xuICAgIHZhciBtaW5SZXNvbHV0aW9uID0gdGhpcy5taW5SZXNvbHV0aW9uXztcbiAgICB2YXIgbWF4ID0gTWF0aC5sb2cobWF4UmVzb2x1dGlvbiAvIG1pblJlc29sdXRpb24pIC8gbG9nUG93ZXI7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKlxuICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICAgICAqIEByZXR1cm4ge251bWJlcn0gVmFsdWUuXG4gICAgICAgKi9cbiAgICAgIGZ1bmN0aW9uIChyZXNvbHV0aW9uKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IE1hdGgubG9nKG1heFJlc29sdXRpb24gLyByZXNvbHV0aW9uKSAvIGxvZ1Bvd2VyIC8gbWF4O1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHZpZXdwb3J0IG1pbnVzIHBhZGRpbmcuXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3JvdGF0aW9uIFRha2UgaW50byBhY2NvdW50IHRoZSByb3RhdGlvbiBvZiB0aGUgdmlld3BvcnQgd2hlbiBnaXZpbmcgdGhlIHNpemVcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IFZpZXdwb3J0IHNpemUgcmVkdWNlZCBieSB0aGUgcGFkZGluZy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRWaWV3cG9ydFNpemVNaW51c1BhZGRpbmdfID0gZnVuY3Rpb24gKG9wdF9yb3RhdGlvbikge1xuICAgIHZhciBzaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVfKG9wdF9yb3RhdGlvbik7XG4gICAgdmFyIHBhZGRpbmcgPSB0aGlzLnBhZGRpbmc7XG5cbiAgICBpZiAocGFkZGluZykge1xuICAgICAgc2l6ZSA9IFtzaXplWzBdIC0gcGFkZGluZ1sxXSAtIHBhZGRpbmdbM10sIHNpemVbMV0gLSBwYWRkaW5nWzBdIC0gcGFkZGluZ1syXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHNpemU7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtTdGF0ZX0gVmlldyBzdGF0ZS5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcHJvamVjdGlvbiA9IHRoaXMuZ2V0UHJvamVjdGlvbigpO1xuICAgIHZhciByZXNvbHV0aW9uID1cbiAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICB0aGlzLmdldFJlc29sdXRpb24oKTtcbiAgICB2YXIgcm90YXRpb24gPSB0aGlzLmdldFJvdGF0aW9uKCk7XG4gICAgdmFyIGNlbnRlciA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cbiAgICB0aGlzLmdldENlbnRlckludGVybmFsKCk7XG4gICAgdmFyIHBhZGRpbmcgPSB0aGlzLnBhZGRpbmc7XG5cbiAgICBpZiAocGFkZGluZykge1xuICAgICAgdmFyIHJlZHVjZWRTaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVNaW51c1BhZGRpbmdfKCk7XG4gICAgICBjZW50ZXIgPSBjYWxjdWxhdGVDZW50ZXJPbihjZW50ZXIsIHRoaXMuZ2V0Vmlld3BvcnRTaXplXygpLCBbcmVkdWNlZFNpemVbMF0gLyAyICsgcGFkZGluZ1szXSwgcmVkdWNlZFNpemVbMV0gLyAyICsgcGFkZGluZ1swXV0sIHJlc29sdXRpb24sIHJvdGF0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY2VudGVyOiBjZW50ZXIuc2xpY2UoMCksXG4gICAgICBwcm9qZWN0aW9uOiBwcm9qZWN0aW9uICE9PSB1bmRlZmluZWQgPyBwcm9qZWN0aW9uIDogbnVsbCxcbiAgICAgIHJlc29sdXRpb246IHJlc29sdXRpb24sXG4gICAgICByb3RhdGlvbjogcm90YXRpb24sXG4gICAgICB6b29tOiB0aGlzLmdldFpvb20oKVxuICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgem9vbSBsZXZlbC4gVGhpcyBtZXRob2QgbWF5IHJldHVybiBub24taW50ZWdlciB6b29tIGxldmVsc1xuICAgKiBpZiB0aGUgdmlldyBkb2VzIG5vdCBjb25zdHJhaW4gdGhlIHJlc29sdXRpb24sIG9yIGlmIGFuIGludGVyYWN0aW9uIG9yXG4gICAqIGFuaW1hdGlvbiBpcyB1bmRlcndheS5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gWm9vbS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldFpvb20gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHpvb207XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24oKTtcblxuICAgIGlmIChyZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHpvb20gPSB0aGlzLmdldFpvb21Gb3JSZXNvbHV0aW9uKHJlc29sdXRpb24pO1xuICAgIH1cblxuICAgIHJldHVybiB6b29tO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB6b29tIGxldmVsIGZvciBhIHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFRoZSByZXNvbHV0aW9uLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBUaGUgem9vbSBsZXZlbCBmb3IgdGhlIHByb3ZpZGVkIHJlc29sdXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRab29tRm9yUmVzb2x1dGlvbiA9IGZ1bmN0aW9uIChyZXNvbHV0aW9uKSB7XG4gICAgdmFyIG9mZnNldCA9IHRoaXMubWluWm9vbV8gfHwgMDtcbiAgICB2YXIgbWF4LCB6b29tRmFjdG9yO1xuXG4gICAgaWYgKHRoaXMucmVzb2x1dGlvbnNfKSB7XG4gICAgICB2YXIgbmVhcmVzdCA9IGxpbmVhckZpbmROZWFyZXN0KHRoaXMucmVzb2x1dGlvbnNfLCByZXNvbHV0aW9uLCAxKTtcbiAgICAgIG9mZnNldCA9IG5lYXJlc3Q7XG4gICAgICBtYXggPSB0aGlzLnJlc29sdXRpb25zX1tuZWFyZXN0XTtcblxuICAgICAgaWYgKG5lYXJlc3QgPT0gdGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoIC0gMSkge1xuICAgICAgICB6b29tRmFjdG9yID0gMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHpvb21GYWN0b3IgPSBtYXggLyB0aGlzLnJlc29sdXRpb25zX1tuZWFyZXN0ICsgMV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1heCA9IHRoaXMubWF4UmVzb2x1dGlvbl87XG4gICAgICB6b29tRmFjdG9yID0gdGhpcy56b29tRmFjdG9yXztcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0ICsgTWF0aC5sb2cobWF4IC8gcmVzb2x1dGlvbikgLyBNYXRoLmxvZyh6b29tRmFjdG9yKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcmVzb2x1dGlvbiBmb3IgYSB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0gem9vbSBab29tIGxldmVsLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSB2aWV3IHJlc29sdXRpb24gZm9yIHRoZSBwcm92aWRlZCB6b29tIGxldmVsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbkZvclpvb20gPSBmdW5jdGlvbiAoem9vbSkge1xuICAgIGlmICh0aGlzLnJlc29sdXRpb25zXykge1xuICAgICAgaWYgKHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuXG4gICAgICB2YXIgYmFzZUxldmVsID0gY2xhbXAoTWF0aC5mbG9vcih6b29tKSwgMCwgdGhpcy5yZXNvbHV0aW9uc18ubGVuZ3RoIC0gMik7XG4gICAgICB2YXIgem9vbUZhY3RvciA9IHRoaXMucmVzb2x1dGlvbnNfW2Jhc2VMZXZlbF0gLyB0aGlzLnJlc29sdXRpb25zX1tiYXNlTGV2ZWwgKyAxXTtcbiAgICAgIHJldHVybiB0aGlzLnJlc29sdXRpb25zX1tiYXNlTGV2ZWxdIC8gTWF0aC5wb3coem9vbUZhY3RvciwgY2xhbXAoem9vbSAtIGJhc2VMZXZlbCwgMCwgMSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5tYXhSZXNvbHV0aW9uXyAvIE1hdGgucG93KHRoaXMuem9vbUZhY3Rvcl8sIHpvb20gLSB0aGlzLm1pblpvb21fKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBGaXQgdGhlIGdpdmVuIGdlb21ldHJ5IG9yIGV4dGVudCBiYXNlZCBvbiB0aGUgZ2l2ZW4gbWFwIHNpemUgYW5kIGJvcmRlci5cbiAgICogVGhlIHNpemUgaXMgcGl4ZWwgZGltZW5zaW9ucyBvZiB0aGUgYm94IHRvIGZpdCB0aGUgZXh0ZW50IGludG8uXG4gICAqIEluIG1vc3QgY2FzZXMgeW91IHdpbGwgd2FudCB0byB1c2UgdGhlIG1hcCBzaXplLCB0aGF0IGlzIGBtYXAuZ2V0U2l6ZSgpYC5cbiAgICogVGFrZXMgY2FyZSBvZiB0aGUgbWFwIGFuZ2xlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZ2VvbWV0cnlPckV4dGVudCBUaGUgZ2VvbWV0cnkgb3JcbiAgICogICAgIGV4dGVudCB0byBmaXQgdGhlIHZpZXcgdG8uXG4gICAqIEBwYXJhbSB7Rml0T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5maXQgPSBmdW5jdGlvbiAoZ2VvbWV0cnlPckV4dGVudCwgb3B0X29wdGlvbnMpIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHZhciBnZW9tZXRyeTtcbiAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShnZW9tZXRyeU9yRXh0ZW50KSB8fCB0eXBlb2ZcbiAgICAvKiogQHR5cGUgez99ICovXG4gICAgZ2VvbWV0cnlPckV4dGVudC5nZXRTaW1wbGlmaWVkR2VvbWV0cnkgPT09ICdmdW5jdGlvbicsIDI0KTsgLy8gSW52YWxpZCBleHRlbnQgb3IgZ2VvbWV0cnkgcHJvdmlkZWQgYXMgYGdlb21ldHJ5YFxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZ2VvbWV0cnlPckV4dGVudCkpIHtcbiAgICAgIGFzc2VydCghaXNFbXB0eShnZW9tZXRyeU9yRXh0ZW50KSwgMjUpOyAvLyBDYW5ub3QgZml0IGVtcHR5IGV4dGVudCBwcm92aWRlZCBhcyBgZ2VvbWV0cnlgXG5cbiAgICAgIHZhciBleHRlbnQgPSBmcm9tVXNlckV4dGVudChnZW9tZXRyeU9yRXh0ZW50LCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gICAgICBnZW9tZXRyeSA9IHBvbHlnb25Gcm9tRXh0ZW50KGV4dGVudCk7XG4gICAgfSBlbHNlIGlmIChnZW9tZXRyeU9yRXh0ZW50LmdldFR5cGUoKSA9PT0gR2VvbWV0cnlUeXBlLkNJUkNMRSkge1xuICAgICAgdmFyIGV4dGVudCA9IGZyb21Vc2VyRXh0ZW50KGdlb21ldHJ5T3JFeHRlbnQuZ2V0RXh0ZW50KCksIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICAgIGdlb21ldHJ5ID0gcG9seWdvbkZyb21FeHRlbnQoZXh0ZW50KTtcbiAgICAgIGdlb21ldHJ5LnJvdGF0ZSh0aGlzLmdldFJvdGF0aW9uKCksIGdldENlbnRlcihleHRlbnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVzZXJQcm9qZWN0aW9uID0gZ2V0VXNlclByb2plY3Rpb24oKTtcblxuICAgICAgaWYgKHVzZXJQcm9qZWN0aW9uKSB7XG4gICAgICAgIGdlb21ldHJ5ID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnlPckV4dGVudC5jbG9uZSgpLnRyYW5zZm9ybSh1c2VyUHJvamVjdGlvbiwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2VvbWV0cnkgPSBnZW9tZXRyeU9yRXh0ZW50O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZml0SW50ZXJuYWwoZ2VvbWV0cnksIG9wdF9vcHRpb25zKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IFRoZSBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtGaXRPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5maXRJbnRlcm5hbCA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgb3B0X29wdGlvbnMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIHZhciBzaXplID0gb3B0aW9ucy5zaXplO1xuXG4gICAgaWYgKCFzaXplKSB7XG4gICAgICBzaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVNaW51c1BhZGRpbmdfKCk7XG4gICAgfVxuXG4gICAgdmFyIHBhZGRpbmcgPSBvcHRpb25zLnBhZGRpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGFkZGluZyA6IFswLCAwLCAwLCAwXTtcbiAgICB2YXIgbmVhcmVzdCA9IG9wdGlvbnMubmVhcmVzdCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uZWFyZXN0IDogZmFsc2U7XG4gICAgdmFyIG1pblJlc29sdXRpb247XG5cbiAgICBpZiAob3B0aW9ucy5taW5SZXNvbHV0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pblJlc29sdXRpb24gPSBvcHRpb25zLm1pblJlc29sdXRpb247XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLm1heFpvb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgbWluUmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbkZvclpvb20ob3B0aW9ucy5tYXhab29tKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWluUmVzb2x1dGlvbiA9IDA7XG4gICAgfVxuXG4gICAgdmFyIGNvb3JkcyA9IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpOyAvLyBjYWxjdWxhdGUgcm90YXRlZCBleHRlbnRcblxuICAgIHZhciByb3RhdGlvbiA9IHRoaXMuZ2V0Um90YXRpb24oKTtcbiAgICB2YXIgY29zQW5nbGUgPSBNYXRoLmNvcygtcm90YXRpb24pO1xuICAgIHZhciBzaW5BbmdsZSA9IE1hdGguc2luKC1yb3RhdGlvbik7XG4gICAgdmFyIG1pblJvdFggPSArSW5maW5pdHk7XG4gICAgdmFyIG1pblJvdFkgPSArSW5maW5pdHk7XG4gICAgdmFyIG1heFJvdFggPSAtSW5maW5pdHk7XG4gICAgdmFyIG1heFJvdFkgPSAtSW5maW5pdHk7XG4gICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRzLmxlbmd0aDsgaSA8IGlpOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmFyIHJvdFggPSBjb29yZHNbaV0gKiBjb3NBbmdsZSAtIGNvb3Jkc1tpICsgMV0gKiBzaW5BbmdsZTtcbiAgICAgIHZhciByb3RZID0gY29vcmRzW2ldICogc2luQW5nbGUgKyBjb29yZHNbaSArIDFdICogY29zQW5nbGU7XG4gICAgICBtaW5Sb3RYID0gTWF0aC5taW4obWluUm90WCwgcm90WCk7XG4gICAgICBtaW5Sb3RZID0gTWF0aC5taW4obWluUm90WSwgcm90WSk7XG4gICAgICBtYXhSb3RYID0gTWF0aC5tYXgobWF4Um90WCwgcm90WCk7XG4gICAgICBtYXhSb3RZID0gTWF0aC5tYXgobWF4Um90WSwgcm90WSk7XG4gICAgfSAvLyBjYWxjdWxhdGUgcmVzb2x1dGlvblxuXG5cbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbkZvckV4dGVudEludGVybmFsKFttaW5Sb3RYLCBtaW5Sb3RZLCBtYXhSb3RYLCBtYXhSb3RZXSwgW3NpemVbMF0gLSBwYWRkaW5nWzFdIC0gcGFkZGluZ1szXSwgc2l6ZVsxXSAtIHBhZGRpbmdbMF0gLSBwYWRkaW5nWzJdXSk7XG4gICAgcmVzb2x1dGlvbiA9IGlzTmFOKHJlc29sdXRpb24pID8gbWluUmVzb2x1dGlvbiA6IE1hdGgubWF4KHJlc29sdXRpb24sIG1pblJlc29sdXRpb24pO1xuICAgIHJlc29sdXRpb24gPSB0aGlzLmdldENvbnN0cmFpbmVkUmVzb2x1dGlvbihyZXNvbHV0aW9uLCBuZWFyZXN0ID8gMCA6IDEpOyAvLyBjYWxjdWxhdGUgY2VudGVyXG5cbiAgICBzaW5BbmdsZSA9IC1zaW5BbmdsZTsgLy8gZ28gYmFjayB0byBvcmlnaW5hbCByb3RhdGlvblxuXG4gICAgdmFyIGNlbnRlclJvdFggPSAobWluUm90WCArIG1heFJvdFgpIC8gMjtcbiAgICB2YXIgY2VudGVyUm90WSA9IChtaW5Sb3RZICsgbWF4Um90WSkgLyAyO1xuICAgIGNlbnRlclJvdFggKz0gKHBhZGRpbmdbMV0gLSBwYWRkaW5nWzNdKSAvIDIgKiByZXNvbHV0aW9uO1xuICAgIGNlbnRlclJvdFkgKz0gKHBhZGRpbmdbMF0gLSBwYWRkaW5nWzJdKSAvIDIgKiByZXNvbHV0aW9uO1xuICAgIHZhciBjZW50ZXJYID0gY2VudGVyUm90WCAqIGNvc0FuZ2xlIC0gY2VudGVyUm90WSAqIHNpbkFuZ2xlO1xuICAgIHZhciBjZW50ZXJZID0gY2VudGVyUm90WSAqIGNvc0FuZ2xlICsgY2VudGVyUm90WCAqIHNpbkFuZ2xlO1xuICAgIHZhciBjZW50ZXIgPSB0aGlzLmdldENvbnN0cmFpbmVkQ2VudGVyKFtjZW50ZXJYLCBjZW50ZXJZXSwgcmVzb2x1dGlvbik7XG4gICAgdmFyIGNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjayA/IG9wdGlvbnMuY2FsbGJhY2sgOiBWT0lEO1xuXG4gICAgaWYgKG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5hbmltYXRlSW50ZXJuYWwoe1xuICAgICAgICByZXNvbHV0aW9uOiByZXNvbHV0aW9uLFxuICAgICAgICBjZW50ZXI6IGNlbnRlcixcbiAgICAgICAgZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sXG4gICAgICAgIGVhc2luZzogb3B0aW9ucy5lYXNpbmdcbiAgICAgIH0sIGNhbGxiYWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50YXJnZXRSZXNvbHV0aW9uXyA9IHJlc29sdXRpb247XG4gICAgICB0aGlzLnRhcmdldENlbnRlcl8gPSBjZW50ZXI7XG4gICAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKGZhbHNlLCB0cnVlKTtcbiAgICAgIGFuaW1hdGlvbkNhbGxiYWNrKGNhbGxiYWNrLCB0cnVlKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBDZW50ZXIgb24gY29vcmRpbmF0ZSBhbmQgdmlldyBwb3NpdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIEJveCBwaXhlbCBzaXplLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBvc2l0aW9uIFBvc2l0aW9uIG9uIHRoZSB2aWV3IHRvIGNlbnRlciBvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNlbnRlck9uID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIHNpemUsIHBvc2l0aW9uKSB7XG4gICAgdGhpcy5jZW50ZXJPbkludGVybmFsKGZyb21Vc2VyQ29vcmRpbmF0ZShjb29yZGluYXRlLCB0aGlzLmdldFByb2plY3Rpb24oKSksIHNpemUsIHBvc2l0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBCb3ggcGl4ZWwgc2l6ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBwb3NpdGlvbiBQb3NpdGlvbiBvbiB0aGUgdmlldyB0byBjZW50ZXIgb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuY2VudGVyT25JbnRlcm5hbCA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBzaXplLCBwb3NpdGlvbikge1xuICAgIHRoaXMuc2V0Q2VudGVySW50ZXJuYWwoY2FsY3VsYXRlQ2VudGVyT24oY29vcmRpbmF0ZSwgc2l6ZSwgcG9zaXRpb24sIHRoaXMuZ2V0UmVzb2x1dGlvbigpLCB0aGlzLmdldFJvdGF0aW9uKCkpKTtcbiAgfTtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIHNoaWZ0IGJldHdlZW4gbWFwIGFuZCB2aWV3cG9ydCBjZW50ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNlbnRlciBDZW50ZXIuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBTaXplLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fHVuZGVmaW5lZH0gQ2VudGVyIHNoaWZ0LlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmNhbGN1bGF0ZUNlbnRlclNoaWZ0ID0gZnVuY3Rpb24gKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIHNpemUpIHtcbiAgICB2YXIgY2VudGVyU2hpZnQ7XG4gICAgdmFyIHBhZGRpbmcgPSB0aGlzLnBhZGRpbmc7XG5cbiAgICBpZiAocGFkZGluZyAmJiBjZW50ZXIpIHtcbiAgICAgIHZhciByZWR1Y2VkU2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplTWludXNQYWRkaW5nXygtcm90YXRpb24pO1xuICAgICAgdmFyIHNoaWZ0ZWRDZW50ZXIgPSBjYWxjdWxhdGVDZW50ZXJPbihjZW50ZXIsIHNpemUsIFtyZWR1Y2VkU2l6ZVswXSAvIDIgKyBwYWRkaW5nWzNdLCByZWR1Y2VkU2l6ZVsxXSAvIDIgKyBwYWRkaW5nWzBdXSwgcmVzb2x1dGlvbiwgcm90YXRpb24pO1xuICAgICAgY2VudGVyU2hpZnQgPSBbY2VudGVyWzBdIC0gc2hpZnRlZENlbnRlclswXSwgY2VudGVyWzFdIC0gc2hpZnRlZENlbnRlclsxXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGNlbnRlclNoaWZ0O1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgZGVmaW5lZC5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5pc0RlZiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gISF0aGlzLmdldENlbnRlckludGVybmFsKCkgJiYgdGhpcy5nZXRSZXNvbHV0aW9uKCkgIT09IHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZHMgcmVsYXRpdmUgY29vcmRpbmF0ZXMgdG8gdGhlIGNlbnRlciBvZiB0aGUgdmlldy4gQW55IGV4dGVudCBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGRlbHRhQ29vcmRpbmF0ZXMgUmVsYXRpdmUgdmFsdWUgdG8gYWRkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYWRqdXN0Q2VudGVyID0gZnVuY3Rpb24gKGRlbHRhQ29vcmRpbmF0ZXMpIHtcbiAgICB2YXIgY2VudGVyID0gdG9Vc2VyQ29vcmRpbmF0ZSh0aGlzLnRhcmdldENlbnRlcl8sIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICB0aGlzLnNldENlbnRlcihbY2VudGVyWzBdICsgZGVsdGFDb29yZGluYXRlc1swXSwgY2VudGVyWzFdICsgZGVsdGFDb29yZGluYXRlc1sxXV0pO1xuICB9O1xuICAvKipcbiAgICogQWRkcyByZWxhdGl2ZSBjb29yZGluYXRlcyB0byB0aGUgY2VudGVyIG9mIHRoZSB2aWV3LiBBbnkgZXh0ZW50IGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gZGVsdGFDb29yZGluYXRlcyBSZWxhdGl2ZSB2YWx1ZSB0byBhZGQuXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYWRqdXN0Q2VudGVySW50ZXJuYWwgPSBmdW5jdGlvbiAoZGVsdGFDb29yZGluYXRlcykge1xuICAgIHZhciBjZW50ZXIgPSB0aGlzLnRhcmdldENlbnRlcl87XG4gICAgdGhpcy5zZXRDZW50ZXJJbnRlcm5hbChbY2VudGVyWzBdICsgZGVsdGFDb29yZGluYXRlc1swXSwgY2VudGVyWzFdICsgZGVsdGFDb29yZGluYXRlc1sxXV0pO1xuICB9O1xuICAvKipcbiAgICogTXVsdGlwbHkgdGhlIHZpZXcgcmVzb2x1dGlvbiBieSBhIHJhdGlvLCBvcHRpb25hbGx5IHVzaW5nIGFuIGFuY2hvci4gQW55IHJlc29sdXRpb25cbiAgICogY29uc3RyYWludCB3aWxsIGFwcGx5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmF0aW8gVGhlIHJhdGlvIHRvIGFwcGx5IG9uIHRoZSB2aWV3IHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBvcmlnaW4gb2YgdGhlIHRyYW5zZm9ybWF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYWRqdXN0UmVzb2x1dGlvbiA9IGZ1bmN0aW9uIChyYXRpbywgb3B0X2FuY2hvcikge1xuICAgIHZhciBhbmNob3IgPSBvcHRfYW5jaG9yICYmIGZyb21Vc2VyQ29vcmRpbmF0ZShvcHRfYW5jaG9yLCB0aGlzLmdldFByb2plY3Rpb24oKSk7XG4gICAgdGhpcy5hZGp1c3RSZXNvbHV0aW9uSW50ZXJuYWwocmF0aW8sIGFuY2hvcik7XG4gIH07XG4gIC8qKlxuICAgKiBNdWx0aXBseSB0aGUgdmlldyByZXNvbHV0aW9uIGJ5IGEgcmF0aW8sIG9wdGlvbmFsbHkgdXNpbmcgYW4gYW5jaG9yLiBBbnkgcmVzb2x1dGlvblxuICAgKiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByYXRpbyBUaGUgcmF0aW8gdG8gYXBwbHkgb24gdGhlIHZpZXcgcmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIG9yaWdpbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYWRqdXN0UmVzb2x1dGlvbkludGVybmFsID0gZnVuY3Rpb24gKHJhdGlvLCBvcHRfYW5jaG9yKSB7XG4gICAgdmFyIGlzTW92aW5nID0gdGhpcy5nZXRBbmltYXRpbmcoKSB8fCB0aGlzLmdldEludGVyYWN0aW5nKCk7XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZV8odGhpcy5nZXRSb3RhdGlvbigpKTtcbiAgICB2YXIgbmV3UmVzb2x1dGlvbiA9IHRoaXMuY29uc3RyYWludHNfLnJlc29sdXRpb24odGhpcy50YXJnZXRSZXNvbHV0aW9uXyAqIHJhdGlvLCAwLCBzaXplLCBpc01vdmluZyk7XG5cbiAgICBpZiAob3B0X2FuY2hvcikge1xuICAgICAgdGhpcy50YXJnZXRDZW50ZXJfID0gdGhpcy5jYWxjdWxhdGVDZW50ZXJab29tKG5ld1Jlc29sdXRpb24sIG9wdF9hbmNob3IpO1xuICAgIH1cblxuICAgIHRoaXMudGFyZ2V0UmVzb2x1dGlvbl8gKj0gcmF0aW87XG4gICAgdGhpcy5hcHBseVRhcmdldFN0YXRlXygpO1xuICB9O1xuICAvKipcbiAgICogQWRkcyBhIHZhbHVlIHRvIHRoZSB2aWV3IHpvb20gbGV2ZWwsIG9wdGlvbmFsbHkgdXNpbmcgYW4gYW5jaG9yLiBBbnkgcmVzb2x1dGlvblxuICAgKiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSBSZWxhdGl2ZSB2YWx1ZSB0byBhZGQgdG8gdGhlIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBvcmlnaW4gb2YgdGhlIHRyYW5zZm9ybWF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYWRqdXN0Wm9vbSA9IGZ1bmN0aW9uIChkZWx0YSwgb3B0X2FuY2hvcikge1xuICAgIHRoaXMuYWRqdXN0UmVzb2x1dGlvbihNYXRoLnBvdyh0aGlzLnpvb21GYWN0b3JfLCAtZGVsdGEpLCBvcHRfYW5jaG9yKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZHMgYSB2YWx1ZSB0byB0aGUgdmlldyByb3RhdGlvbiwgb3B0aW9uYWxseSB1c2luZyBhbiBhbmNob3IuIEFueSByb3RhdGlvblxuICAgKiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSBSZWxhdGl2ZSB2YWx1ZSB0byBhZGQgdG8gdGhlIHpvb20gcm90YXRpb24sIGluIHJhZGlhbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSByb3RhdGlvbiBjZW50ZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RSb3RhdGlvbiA9IGZ1bmN0aW9uIChkZWx0YSwgb3B0X2FuY2hvcikge1xuICAgIGlmIChvcHRfYW5jaG9yKSB7XG4gICAgICBvcHRfYW5jaG9yID0gZnJvbVVzZXJDb29yZGluYXRlKG9wdF9hbmNob3IsIHRoaXMuZ2V0UHJvamVjdGlvbigpKTtcbiAgICB9XG5cbiAgICB0aGlzLmFkanVzdFJvdGF0aW9uSW50ZXJuYWwoZGVsdGEsIG9wdF9hbmNob3IpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhIFJlbGF0aXZlIHZhbHVlIHRvIGFkZCB0byB0aGUgem9vbSByb3RhdGlvbiwgaW4gcmFkaWFucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIHJvdGF0aW9uIGNlbnRlci5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5hZGp1c3RSb3RhdGlvbkludGVybmFsID0gZnVuY3Rpb24gKGRlbHRhLCBvcHRfYW5jaG9yKSB7XG4gICAgdmFyIGlzTW92aW5nID0gdGhpcy5nZXRBbmltYXRpbmcoKSB8fCB0aGlzLmdldEludGVyYWN0aW5nKCk7XG4gICAgdmFyIG5ld1JvdGF0aW9uID0gdGhpcy5jb25zdHJhaW50c18ucm90YXRpb24odGhpcy50YXJnZXRSb3RhdGlvbl8gKyBkZWx0YSwgaXNNb3ZpbmcpO1xuXG4gICAgaWYgKG9wdF9hbmNob3IpIHtcbiAgICAgIHRoaXMudGFyZ2V0Q2VudGVyXyA9IHRoaXMuY2FsY3VsYXRlQ2VudGVyUm90YXRlKG5ld1JvdGF0aW9uLCBvcHRfYW5jaG9yKTtcbiAgICB9XG5cbiAgICB0aGlzLnRhcmdldFJvdGF0aW9uXyArPSBkZWx0YTtcbiAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNlbnRlciBvZiB0aGUgY3VycmVudCB2aWV3LiBBbnkgZXh0ZW50IGNvbnN0cmFpbnQgd2lsbCBhcHBseS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IGNlbnRlciBUaGUgY2VudGVyIG9mIHRoZSB2aWV3LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuc2V0Q2VudGVyID0gZnVuY3Rpb24gKGNlbnRlcikge1xuICAgIHRoaXMuc2V0Q2VudGVySW50ZXJuYWwoZnJvbVVzZXJDb29yZGluYXRlKGNlbnRlciwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY2VudGVyIHVzaW5nIHRoZSB2aWV3IHByb2plY3Rpb24gKG5vdCB0aGUgdXNlciBwcm9qZWN0aW9uKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IGNlbnRlciBUaGUgY2VudGVyIG9mIHRoZSB2aWV3LlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldENlbnRlckludGVybmFsID0gZnVuY3Rpb24gKGNlbnRlcikge1xuICAgIHRoaXMudGFyZ2V0Q2VudGVyXyA9IGNlbnRlcjtcbiAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVmlld0hpbnQuanNcIikuZGVmYXVsdH0gaGludCBIaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGEgRGVsdGEuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTmV3IHZhbHVlLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldEhpbnQgPSBmdW5jdGlvbiAoaGludCwgZGVsdGEpIHtcbiAgICB0aGlzLmhpbnRzX1toaW50XSArPSBkZWx0YTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICByZXR1cm4gdGhpcy5oaW50c19baGludF07XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJlc29sdXRpb24gZm9yIHRoaXMgdmlldy4gQW55IHJlc29sdXRpb24gY29uc3RyYWludCB3aWxsIGFwcGx5LlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJlc29sdXRpb24gVGhlIHJlc29sdXRpb24gb2YgdGhlIHZpZXcuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHJlc29sdXRpb24pIHtcbiAgICB0aGlzLnRhcmdldFJlc29sdXRpb25fID0gcmVzb2x1dGlvbjtcbiAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJvdGF0aW9uIGZvciB0aGlzIHZpZXcuIEFueSByb3RhdGlvbiBjb25zdHJhaW50IHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByb3RhdGlvbiBUaGUgcm90YXRpb24gb2YgdGhlIHZpZXcgaW4gcmFkaWFucy5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLnNldFJvdGF0aW9uID0gZnVuY3Rpb24gKHJvdGF0aW9uKSB7XG4gICAgdGhpcy50YXJnZXRSb3RhdGlvbl8gPSByb3RhdGlvbjtcbiAgICB0aGlzLmFwcGx5VGFyZ2V0U3RhdGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBab29tIHRvIGEgc3BlY2lmaWMgem9vbSBsZXZlbC4gQW55IHJlc29sdXRpb24gY29uc3RyYWluIHdpbGwgYXBwbHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFpvb20gbGV2ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5zZXRab29tID0gZnVuY3Rpb24gKHpvb20pIHtcbiAgICB0aGlzLnNldFJlc29sdXRpb24odGhpcy5nZXRSZXNvbHV0aW9uRm9yWm9vbSh6b29tKSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWNvbXB1dGUgcm90YXRpb24vcmVzb2x1dGlvbi9jZW50ZXIgYmFzZWQgb24gdGFyZ2V0IHZhbHVlcy5cbiAgICogTm90ZTogd2UgaGF2ZSB0byBjb21wdXRlIHJvdGF0aW9uIGZpcnN0LCB0aGVuIHJlc29sdXRpb24gYW5kIGNlbnRlciBjb25zaWRlcmluZyB0aGF0XG4gICAqIHBhcmFtZXRlcnMgY2FuIGluZmx1ZW5jZSBvbmUgYW5vdGhlciBpbiBjYXNlIGEgdmlldyBleHRlbnQgY29uc3RyYWludCBpcyBwcmVzZW50LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfZG9Ob3RDYW5jZWxBbmltcyBEbyBub3QgY2FuY2VsIGFuaW1hdGlvbnMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9mb3JjZU1vdmluZyBBcHBseSBjb25zdHJhaW50cyBhcyBpZiB0aGUgdmlldyBpcyBtb3ZpbmcuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuYXBwbHlUYXJnZXRTdGF0ZV8gPSBmdW5jdGlvbiAob3B0X2RvTm90Q2FuY2VsQW5pbXMsIG9wdF9mb3JjZU1vdmluZykge1xuICAgIHZhciBpc01vdmluZyA9IHRoaXMuZ2V0QW5pbWF0aW5nKCkgfHwgdGhpcy5nZXRJbnRlcmFjdGluZygpIHx8IG9wdF9mb3JjZU1vdmluZzsgLy8gY29tcHV0ZSByb3RhdGlvblxuXG4gICAgdmFyIG5ld1JvdGF0aW9uID0gdGhpcy5jb25zdHJhaW50c18ucm90YXRpb24odGhpcy50YXJnZXRSb3RhdGlvbl8sIGlzTW92aW5nKTtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplXyhuZXdSb3RhdGlvbik7XG4gICAgdmFyIG5ld1Jlc29sdXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yZXNvbHV0aW9uKHRoaXMudGFyZ2V0UmVzb2x1dGlvbl8sIDAsIHNpemUsIGlzTW92aW5nKTtcbiAgICB2YXIgbmV3Q2VudGVyID0gdGhpcy5jb25zdHJhaW50c18uY2VudGVyKHRoaXMudGFyZ2V0Q2VudGVyXywgbmV3UmVzb2x1dGlvbiwgc2l6ZSwgaXNNb3ZpbmcsIHRoaXMuY2FsY3VsYXRlQ2VudGVyU2hpZnQodGhpcy50YXJnZXRDZW50ZXJfLCBuZXdSZXNvbHV0aW9uLCBuZXdSb3RhdGlvbiwgc2l6ZSkpO1xuXG4gICAgaWYgKHRoaXMuZ2V0KFZpZXdQcm9wZXJ0eS5ST1RBVElPTikgIT09IG5ld1JvdGF0aW9uKSB7XG4gICAgICB0aGlzLnNldChWaWV3UHJvcGVydHkuUk9UQVRJT04sIG5ld1JvdGF0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5nZXQoVmlld1Byb3BlcnR5LlJFU09MVVRJT04pICE9PSBuZXdSZXNvbHV0aW9uKSB7XG4gICAgICB0aGlzLnNldChWaWV3UHJvcGVydHkuUkVTT0xVVElPTiwgbmV3UmVzb2x1dGlvbik7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmdldChWaWV3UHJvcGVydHkuQ0VOVEVSKSB8fCAhZXF1YWxzKHRoaXMuZ2V0KFZpZXdQcm9wZXJ0eS5DRU5URVIpLCBuZXdDZW50ZXIpKSB7XG4gICAgICB0aGlzLnNldChWaWV3UHJvcGVydHkuQ0VOVEVSLCBuZXdDZW50ZXIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmdldEFuaW1hdGluZygpICYmICFvcHRfZG9Ob3RDYW5jZWxBbmltcykge1xuICAgICAgdGhpcy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jYW5jZWxBbmNob3JfID0gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogSWYgYW55IGNvbnN0cmFpbnRzIG5lZWQgdG8gYmUgYXBwbGllZCwgYW4gYW5pbWF0aW9uIHdpbGwgYmUgdHJpZ2dlcmVkLlxuICAgKiBUaGlzIGlzIHR5cGljYWxseSBkb25lIG9uIGludGVyYWN0aW9uIGVuZC5cbiAgICogTm90ZTogY2FsbGluZyB0aGlzIHdpdGggYSBkdXJhdGlvbiBvZiAwIHdpbGwgYXBwbHkgdGhlIGNvbnN0cmFpbmVkIHZhbHVlcyBzdHJhaWdodCBhd2F5LFxuICAgKiB3aXRob3V0IGFuaW1hdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZHVyYXRpb24gVGhlIGFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtcy5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiBXaGljaCBkaXJlY3Rpb24gdG8gem9vbS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9hbmNob3IgVGhlIG9yaWdpbiBvZiB0aGUgdHJhbnNmb3JtYXRpb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUucmVzb2x2ZUNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKG9wdF9kdXJhdGlvbiwgb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24sIG9wdF9hbmNob3IpIHtcbiAgICB2YXIgZHVyYXRpb24gPSBvcHRfZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9kdXJhdGlvbiA6IDIwMDtcbiAgICB2YXIgZGlyZWN0aW9uID0gb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24gfHwgMDtcbiAgICB2YXIgbmV3Um90YXRpb24gPSB0aGlzLmNvbnN0cmFpbnRzXy5yb3RhdGlvbih0aGlzLnRhcmdldFJvdGF0aW9uXyk7XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZV8obmV3Um90YXRpb24pO1xuICAgIHZhciBuZXdSZXNvbHV0aW9uID0gdGhpcy5jb25zdHJhaW50c18ucmVzb2x1dGlvbih0aGlzLnRhcmdldFJlc29sdXRpb25fLCBkaXJlY3Rpb24sIHNpemUpO1xuICAgIHZhciBuZXdDZW50ZXIgPSB0aGlzLmNvbnN0cmFpbnRzXy5jZW50ZXIodGhpcy50YXJnZXRDZW50ZXJfLCBuZXdSZXNvbHV0aW9uLCBzaXplLCBmYWxzZSwgdGhpcy5jYWxjdWxhdGVDZW50ZXJTaGlmdCh0aGlzLnRhcmdldENlbnRlcl8sIG5ld1Jlc29sdXRpb24sIG5ld1JvdGF0aW9uLCBzaXplKSk7XG5cbiAgICBpZiAoZHVyYXRpb24gPT09IDAgJiYgIXRoaXMuY2FuY2VsQW5jaG9yXykge1xuICAgICAgdGhpcy50YXJnZXRSZXNvbHV0aW9uXyA9IG5ld1Jlc29sdXRpb247XG4gICAgICB0aGlzLnRhcmdldFJvdGF0aW9uXyA9IG5ld1JvdGF0aW9uO1xuICAgICAgdGhpcy50YXJnZXRDZW50ZXJfID0gbmV3Q2VudGVyO1xuICAgICAgdGhpcy5hcHBseVRhcmdldFN0YXRlXygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhbmNob3IgPSBvcHRfYW5jaG9yIHx8IChkdXJhdGlvbiA9PT0gMCA/IHRoaXMuY2FuY2VsQW5jaG9yXyA6IHVuZGVmaW5lZCk7XG4gICAgdGhpcy5jYW5jZWxBbmNob3JfID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKHRoaXMuZ2V0UmVzb2x1dGlvbigpICE9PSBuZXdSZXNvbHV0aW9uIHx8IHRoaXMuZ2V0Um90YXRpb24oKSAhPT0gbmV3Um90YXRpb24gfHwgIXRoaXMuZ2V0Q2VudGVySW50ZXJuYWwoKSB8fCAhZXF1YWxzKHRoaXMuZ2V0Q2VudGVySW50ZXJuYWwoKSwgbmV3Q2VudGVyKSkge1xuICAgICAgaWYgKHRoaXMuZ2V0QW5pbWF0aW5nKCkpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYW5pbWF0ZUludGVybmFsKHtcbiAgICAgICAgcm90YXRpb246IG5ld1JvdGF0aW9uLFxuICAgICAgICBjZW50ZXI6IG5ld0NlbnRlcixcbiAgICAgICAgcmVzb2x1dGlvbjogbmV3UmVzb2x1dGlvbixcbiAgICAgICAgZHVyYXRpb246IGR1cmF0aW9uLFxuICAgICAgICBlYXNpbmc6IGVhc2VPdXQsXG4gICAgICAgIGFuY2hvcjogYW5jaG9yXG4gICAgICB9KTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBOb3RpZnkgdGhlIFZpZXcgdGhhdCBhbiBpbnRlcmFjdGlvbiBoYXMgc3RhcnRlZC5cbiAgICogVGhlIHZpZXcgc3RhdGUgd2lsbCBiZSByZXNvbHZlZCB0byBhIHN0YWJsZSBvbmUgaWYgbmVlZGVkXG4gICAqIChkZXBlbmRpbmcgb24gaXRzIGNvbnN0cmFpbnRzKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmJlZ2luSW50ZXJhY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZXNvbHZlQ29uc3RyYWludHMoMCk7XG4gICAgdGhpcy5zZXRIaW50KFZpZXdIaW50LklOVEVSQUNUSU5HLCAxKTtcbiAgfTtcbiAgLyoqXG4gICAqIE5vdGlmeSB0aGUgVmlldyB0aGF0IGFuIGludGVyYWN0aW9uIGhhcyBlbmRlZC4gVGhlIHZpZXcgc3RhdGUgd2lsbCBiZSByZXNvbHZlZFxuICAgKiB0byBhIHN0YWJsZSBvbmUgaWYgbmVlZGVkIChkZXBlbmRpbmcgb24gaXRzIGNvbnN0cmFpbnRzKS5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZHVyYXRpb24gQW5pbWF0aW9uIGR1cmF0aW9uIGluIG1zLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9yZXNvbHV0aW9uRGlyZWN0aW9uIFdoaWNoIGRpcmVjdGlvbiB0byB6b29tLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPX0gb3B0X2FuY2hvciBUaGUgb3JpZ2luIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmVuZEludGVyYWN0aW9uID0gZnVuY3Rpb24gKG9wdF9kdXJhdGlvbiwgb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24sIG9wdF9hbmNob3IpIHtcbiAgICB2YXIgYW5jaG9yID0gb3B0X2FuY2hvciAmJiBmcm9tVXNlckNvb3JkaW5hdGUob3B0X2FuY2hvciwgdGhpcy5nZXRQcm9qZWN0aW9uKCkpO1xuICAgIHRoaXMuZW5kSW50ZXJhY3Rpb25JbnRlcm5hbChvcHRfZHVyYXRpb24sIG9wdF9yZXNvbHV0aW9uRGlyZWN0aW9uLCBhbmNob3IpO1xuICB9O1xuICAvKipcbiAgICogTm90aWZ5IHRoZSBWaWV3IHRoYXQgYW4gaW50ZXJhY3Rpb24gaGFzIGVuZGVkLiBUaGUgdmlldyBzdGF0ZSB3aWxsIGJlIHJlc29sdmVkXG4gICAqIHRvIGEgc3RhYmxlIG9uZSBpZiBuZWVkZWQgKGRlcGVuZGluZyBvbiBpdHMgY29uc3RyYWludHMpLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9kdXJhdGlvbiBBbmltYXRpb24gZHVyYXRpb24gaW4gbXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24gV2hpY2ggZGlyZWN0aW9uIHRvIHpvb20uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBvcmlnaW4gb2YgdGhlIHRyYW5zZm9ybWF0aW9uLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmVuZEludGVyYWN0aW9uSW50ZXJuYWwgPSBmdW5jdGlvbiAob3B0X2R1cmF0aW9uLCBvcHRfcmVzb2x1dGlvbkRpcmVjdGlvbiwgb3B0X2FuY2hvcikge1xuICAgIHRoaXMuc2V0SGludChWaWV3SGludC5JTlRFUkFDVElORywgLTEpO1xuICAgIHRoaXMucmVzb2x2ZUNvbnN0cmFpbnRzKG9wdF9kdXJhdGlvbiwgb3B0X3Jlc29sdXRpb25EaXJlY3Rpb24sIG9wdF9hbmNob3IpO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgdmFsaWQgcG9zaXRpb24gZm9yIHRoZSB2aWV3IGNlbnRlciBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgY29uc3RyYWludHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSB0YXJnZXRDZW50ZXIgVGFyZ2V0IGNlbnRlciBwb3NpdGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfdGFyZ2V0UmVzb2x1dGlvbiBUYXJnZXQgcmVzb2x1dGlvbi4gSWYgbm90IHN1cHBsaWVkLCB0aGUgY3VycmVudCBvbmUgd2lsbCBiZSB1c2VkLlxuICAgKiBUaGlzIGlzIHVzZWZ1bCB0byBndWVzcyBhIHZhbGlkIGNlbnRlciBwb3NpdGlvbiBhdCBhIGRpZmZlcmVudCB6b29tIGxldmVsLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IFZhbGlkIGNlbnRlciBwb3NpdGlvbi5cbiAgICovXG5cblxuICBWaWV3LnByb3RvdHlwZS5nZXRDb25zdHJhaW5lZENlbnRlciA9IGZ1bmN0aW9uICh0YXJnZXRDZW50ZXIsIG9wdF90YXJnZXRSZXNvbHV0aW9uKSB7XG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFZpZXdwb3J0U2l6ZV8odGhpcy5nZXRSb3RhdGlvbigpKTtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJhaW50c18uY2VudGVyKHRhcmdldENlbnRlciwgb3B0X3RhcmdldFJlc29sdXRpb24gfHwgdGhpcy5nZXRSZXNvbHV0aW9uKCksIHNpemUpO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgdmFsaWQgem9vbSBsZXZlbCBhY2NvcmRpbmcgdG8gdGhlIGN1cnJlbnQgdmlldyBjb25zdHJhaW50cy5cbiAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSB0YXJnZXRab29tIFRhcmdldCB6b29tLlxuICAgKiBAcGFyYW0ge251bWJlcj19IFtvcHRfZGlyZWN0aW9uPTBdIEluZGljYXRlIHdoaWNoIHJlc29sdXRpb24gc2hvdWxkIGJlIHVzZWRcbiAgICogYnkgYSByZW5kZXJlciBpZiB0aGUgdmlldyByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGFueSByZXNvbHV0aW9uIG9mIHRoZSB0aWxlIHNvdXJjZS5cbiAgICogSWYgMCwgdGhlIG5lYXJlc3QgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuIElmIDEsIHRoZSBuZWFyZXN0IGxvd2VyIHJlc29sdXRpb25cbiAgICogd2lsbCBiZSB1c2VkLiBJZiAtMSwgdGhlIG5lYXJlc3QgaGlnaGVyIHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBWYWxpZCB6b29tIGxldmVsLlxuICAgKi9cblxuXG4gIFZpZXcucHJvdG90eXBlLmdldENvbnN0cmFpbmVkWm9vbSA9IGZ1bmN0aW9uICh0YXJnZXRab29tLCBvcHRfZGlyZWN0aW9uKSB7XG4gICAgdmFyIHRhcmdldFJlcyA9IHRoaXMuZ2V0UmVzb2x1dGlvbkZvclpvb20odGFyZ2V0Wm9vbSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Wm9vbUZvclJlc29sdXRpb24odGhpcy5nZXRDb25zdHJhaW5lZFJlc29sdXRpb24odGFyZ2V0UmVzLCBvcHRfZGlyZWN0aW9uKSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSB2YWxpZCByZXNvbHV0aW9uIGFjY29yZGluZyB0byB0aGUgY3VycmVudCB2aWV3IGNvbnN0cmFpbnRzLlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHRhcmdldFJlc29sdXRpb24gVGFyZ2V0IHJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gW29wdF9kaXJlY3Rpb249MF0gSW5kaWNhdGUgd2hpY2ggcmVzb2x1dGlvbiBzaG91bGQgYmUgdXNlZFxuICAgKiBieSBhIHJlbmRlcmVyIGlmIHRoZSB2aWV3IHJlc29sdXRpb24gZG9lcyBub3QgbWF0Y2ggYW55IHJlc29sdXRpb24gb2YgdGhlIHRpbGUgc291cmNlLlxuICAgKiBJZiAwLCB0aGUgbmVhcmVzdCByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gSWYgMSwgdGhlIG5lYXJlc3QgbG93ZXIgcmVzb2x1dGlvblxuICAgKiB3aWxsIGJlIHVzZWQuIElmIC0xLCB0aGUgbmVhcmVzdCBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFZhbGlkIHJlc29sdXRpb24uXG4gICAqL1xuXG5cbiAgVmlldy5wcm90b3R5cGUuZ2V0Q29uc3RyYWluZWRSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHRhcmdldFJlc29sdXRpb24sIG9wdF9kaXJlY3Rpb24pIHtcbiAgICB2YXIgZGlyZWN0aW9uID0gb3B0X2RpcmVjdGlvbiB8fCAwO1xuICAgIHZhciBzaXplID0gdGhpcy5nZXRWaWV3cG9ydFNpemVfKHRoaXMuZ2V0Um90YXRpb24oKSk7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RyYWludHNfLnJlc29sdXRpb24odGFyZ2V0UmVzb2x1dGlvbiwgZGlyZWN0aW9uLCBzaXplKTtcbiAgfTtcblxuICByZXR1cm4gVmlldztcbn0oQmFzZU9iamVjdCk7XG4vKipcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrLlxuICogQHBhcmFtIHsqfSByZXR1cm5WYWx1ZSBSZXR1cm4gdmFsdWUuXG4gKi9cblxuXG5mdW5jdGlvbiBhbmltYXRpb25DYWxsYmFjayhjYWxsYmFjaywgcmV0dXJuVmFsdWUpIHtcbiAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgY2FsbGJhY2socmV0dXJuVmFsdWUpO1xuICB9LCAwKTtcbn1cbi8qKlxuICogQHBhcmFtIHtWaWV3T3B0aW9uc30gb3B0aW9ucyBWaWV3IG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2NlbnRlcmNvbnN0cmFpbnQuanNcIikuVHlwZX0gVGhlIGNvbnN0cmFpbnQuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2VudGVyQ29uc3RyYWludChvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLmV4dGVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHNtb290aCA9IG9wdGlvbnMuc21vb3RoRXh0ZW50Q29uc3RyYWludCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zbW9vdGhFeHRlbnRDb25zdHJhaW50IDogdHJ1ZTtcbiAgICByZXR1cm4gY3JlYXRlRXh0ZW50KG9wdGlvbnMuZXh0ZW50LCBvcHRpb25zLmNvbnN0cmFpbk9ubHlDZW50ZXIsIHNtb290aCk7XG4gIH1cblxuICB2YXIgcHJvamVjdGlvbiA9IGNyZWF0ZVByb2plY3Rpb24ob3B0aW9ucy5wcm9qZWN0aW9uLCAnRVBTRzozODU3Jyk7XG5cbiAgaWYgKG9wdGlvbnMubXVsdGlXb3JsZCAhPT0gdHJ1ZSAmJiBwcm9qZWN0aW9uLmlzR2xvYmFsKCkpIHtcbiAgICB2YXIgZXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKS5zbGljZSgpO1xuICAgIGV4dGVudFswXSA9IC1JbmZpbml0eTtcbiAgICBleHRlbnRbMl0gPSBJbmZpbml0eTtcbiAgICByZXR1cm4gY3JlYXRlRXh0ZW50KGV4dGVudCwgZmFsc2UsIGZhbHNlKTtcbiAgfVxuXG4gIHJldHVybiBjZW50ZXJOb25lO1xufVxuLyoqXG4gKiBAcGFyYW0ge1ZpZXdPcHRpb25zfSBvcHRpb25zIFZpZXcgb3B0aW9ucy5cbiAqIEByZXR1cm4ge3tjb25zdHJhaW50OiBpbXBvcnQoXCIuL3Jlc29sdXRpb25jb25zdHJhaW50LmpzXCIpLlR5cGUsIG1heFJlc29sdXRpb246IG51bWJlcixcbiAqICAgICBtaW5SZXNvbHV0aW9uOiBudW1iZXIsIG1pblpvb206IG51bWJlciwgem9vbUZhY3RvcjogbnVtYmVyfX0gVGhlIGNvbnN0cmFpbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJlc29sdXRpb25Db25zdHJhaW50KG9wdGlvbnMpIHtcbiAgdmFyIHJlc29sdXRpb25Db25zdHJhaW50O1xuICB2YXIgbWF4UmVzb2x1dGlvbjtcbiAgdmFyIG1pblJlc29sdXRpb247IC8vIFRPRE86IG1vdmUgdGhlc2UgdG8gYmUgb2wgY29uc3RhbnRzXG4gIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vb3BlbmxheWVycy9vcGVubGF5ZXJzL2lzc3Vlcy8yMDc2XG5cbiAgdmFyIGRlZmF1bHRNYXhab29tID0gMjg7XG4gIHZhciBkZWZhdWx0Wm9vbUZhY3RvciA9IDI7XG4gIHZhciBtaW5ab29tID0gb3B0aW9ucy5taW5ab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1pblpvb20gOiBERUZBVUxUX01JTl9aT09NO1xuICB2YXIgbWF4Wm9vbSA9IG9wdGlvbnMubWF4Wm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tYXhab29tIDogZGVmYXVsdE1heFpvb207XG4gIHZhciB6b29tRmFjdG9yID0gb3B0aW9ucy56b29tRmFjdG9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb21GYWN0b3IgOiBkZWZhdWx0Wm9vbUZhY3RvcjtcbiAgdmFyIG11bHRpV29ybGQgPSBvcHRpb25zLm11bHRpV29ybGQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubXVsdGlXb3JsZCA6IGZhbHNlO1xuICB2YXIgc21vb3RoID0gb3B0aW9ucy5zbW9vdGhSZXNvbHV0aW9uQ29uc3RyYWludCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zbW9vdGhSZXNvbHV0aW9uQ29uc3RyYWludCA6IHRydWU7XG4gIHZhciBzaG93RnVsbEV4dGVudCA9IG9wdGlvbnMuc2hvd0Z1bGxFeHRlbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2hvd0Z1bGxFeHRlbnQgOiBmYWxzZTtcbiAgdmFyIHByb2plY3Rpb24gPSBjcmVhdGVQcm9qZWN0aW9uKG9wdGlvbnMucHJvamVjdGlvbiwgJ0VQU0c6Mzg1NycpO1xuICB2YXIgcHJvakV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG4gIHZhciBjb25zdHJhaW5Pbmx5Q2VudGVyID0gb3B0aW9ucy5jb25zdHJhaW5Pbmx5Q2VudGVyO1xuICB2YXIgZXh0ZW50ID0gb3B0aW9ucy5leHRlbnQ7XG5cbiAgaWYgKCFtdWx0aVdvcmxkICYmICFleHRlbnQgJiYgcHJvamVjdGlvbi5pc0dsb2JhbCgpKSB7XG4gICAgY29uc3RyYWluT25seUNlbnRlciA9IGZhbHNlO1xuICAgIGV4dGVudCA9IHByb2pFeHRlbnQ7XG4gIH1cblxuICBpZiAob3B0aW9ucy5yZXNvbHV0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlc29sdXRpb25zID0gb3B0aW9ucy5yZXNvbHV0aW9ucztcbiAgICBtYXhSZXNvbHV0aW9uID0gcmVzb2x1dGlvbnNbbWluWm9vbV07XG4gICAgbWluUmVzb2x1dGlvbiA9IHJlc29sdXRpb25zW21heFpvb21dICE9PSB1bmRlZmluZWQgPyByZXNvbHV0aW9uc1ttYXhab29tXSA6IHJlc29sdXRpb25zW3Jlc29sdXRpb25zLmxlbmd0aCAtIDFdO1xuXG4gICAgaWYgKG9wdGlvbnMuY29uc3RyYWluUmVzb2x1dGlvbikge1xuICAgICAgcmVzb2x1dGlvbkNvbnN0cmFpbnQgPSBjcmVhdGVTbmFwVG9SZXNvbHV0aW9ucyhyZXNvbHV0aW9ucywgc21vb3RoLCAhY29uc3RyYWluT25seUNlbnRlciAmJiBleHRlbnQsIHNob3dGdWxsRXh0ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzb2x1dGlvbkNvbnN0cmFpbnQgPSBjcmVhdGVNaW5NYXhSZXNvbHV0aW9uKG1heFJlc29sdXRpb24sIG1pblJlc29sdXRpb24sIHNtb290aCwgIWNvbnN0cmFpbk9ubHlDZW50ZXIgJiYgZXh0ZW50LCBzaG93RnVsbEV4dGVudCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIGNhbGN1bGF0ZSB0aGUgZGVmYXVsdCBtaW4gYW5kIG1heCByZXNvbHV0aW9uXG4gICAgdmFyIHNpemUgPSAhcHJvakV4dGVudCA/IC8vIHVzZSBhbiBleHRlbnQgdGhhdCBjYW4gZml0IHRoZSB3aG9sZSB3b3JsZCBpZiBuZWVkIGJlXG4gICAgMzYwICogTUVURVJTX1BFUl9VTklUW1VuaXRzLkRFR1JFRVNdIC8gcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCkgOiBNYXRoLm1heChnZXRXaWR0aChwcm9qRXh0ZW50KSwgZ2V0SGVpZ2h0KHByb2pFeHRlbnQpKTtcbiAgICB2YXIgZGVmYXVsdE1heFJlc29sdXRpb24gPSBzaXplIC8gREVGQVVMVF9USUxFX1NJWkUgLyBNYXRoLnBvdyhkZWZhdWx0Wm9vbUZhY3RvciwgREVGQVVMVF9NSU5fWk9PTSk7XG4gICAgdmFyIGRlZmF1bHRNaW5SZXNvbHV0aW9uID0gZGVmYXVsdE1heFJlc29sdXRpb24gLyBNYXRoLnBvdyhkZWZhdWx0Wm9vbUZhY3RvciwgZGVmYXVsdE1heFpvb20gLSBERUZBVUxUX01JTl9aT09NKTsgLy8gdXNlciBwcm92aWRlZCBtYXhSZXNvbHV0aW9uIHRha2VzIHByZWNlZGVuY2VcblxuICAgIG1heFJlc29sdXRpb24gPSBvcHRpb25zLm1heFJlc29sdXRpb247XG5cbiAgICBpZiAobWF4UmVzb2x1dGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5ab29tID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgbWF4UmVzb2x1dGlvbiA9IGRlZmF1bHRNYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3coem9vbUZhY3RvciwgbWluWm9vbSk7XG4gICAgfSAvLyB1c2VyIHByb3ZpZGVkIG1pblJlc29sdXRpb24gdGFrZXMgcHJlY2VkZW5jZVxuXG5cbiAgICBtaW5SZXNvbHV0aW9uID0gb3B0aW9ucy5taW5SZXNvbHV0aW9uO1xuXG4gICAgaWYgKG1pblJlc29sdXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKG9wdGlvbnMubWF4Wm9vbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChvcHRpb25zLm1heFJlc29sdXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIG1pblJlc29sdXRpb24gPSBtYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3coem9vbUZhY3RvciwgbWF4Wm9vbSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWluUmVzb2x1dGlvbiA9IGRlZmF1bHRNYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3coem9vbUZhY3RvciwgbWF4Wm9vbSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1pblJlc29sdXRpb24gPSBkZWZhdWx0TWluUmVzb2x1dGlvbjtcbiAgICAgIH1cbiAgICB9IC8vIGdpdmVuIGRpc2NyZXRlIHpvb20gbGV2ZWxzLCBtaW5SZXNvbHV0aW9uIG1heSBiZSBkaWZmZXJlbnQgdGhhbiBwcm92aWRlZFxuXG5cbiAgICBtYXhab29tID0gbWluWm9vbSArIE1hdGguZmxvb3IoTWF0aC5sb2cobWF4UmVzb2x1dGlvbiAvIG1pblJlc29sdXRpb24pIC8gTWF0aC5sb2coem9vbUZhY3RvcikpO1xuICAgIG1pblJlc29sdXRpb24gPSBtYXhSZXNvbHV0aW9uIC8gTWF0aC5wb3coem9vbUZhY3RvciwgbWF4Wm9vbSAtIG1pblpvb20pO1xuXG4gICAgaWYgKG9wdGlvbnMuY29uc3RyYWluUmVzb2x1dGlvbikge1xuICAgICAgcmVzb2x1dGlvbkNvbnN0cmFpbnQgPSBjcmVhdGVTbmFwVG9Qb3dlcih6b29tRmFjdG9yLCBtYXhSZXNvbHV0aW9uLCBtaW5SZXNvbHV0aW9uLCBzbW9vdGgsICFjb25zdHJhaW5Pbmx5Q2VudGVyICYmIGV4dGVudCwgc2hvd0Z1bGxFeHRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXNvbHV0aW9uQ29uc3RyYWludCA9IGNyZWF0ZU1pbk1heFJlc29sdXRpb24obWF4UmVzb2x1dGlvbiwgbWluUmVzb2x1dGlvbiwgc21vb3RoLCAhY29uc3RyYWluT25seUNlbnRlciAmJiBleHRlbnQsIHNob3dGdWxsRXh0ZW50KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbnN0cmFpbnQ6IHJlc29sdXRpb25Db25zdHJhaW50LFxuICAgIG1heFJlc29sdXRpb246IG1heFJlc29sdXRpb24sXG4gICAgbWluUmVzb2x1dGlvbjogbWluUmVzb2x1dGlvbixcbiAgICBtaW5ab29tOiBtaW5ab29tLFxuICAgIHpvb21GYWN0b3I6IHpvb21GYWN0b3JcbiAgfTtcbn1cbi8qKlxuICogQHBhcmFtIHtWaWV3T3B0aW9uc30gb3B0aW9ucyBWaWV3IG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3JvdGF0aW9uY29uc3RyYWludC5qc1wiKS5UeXBlfSBSb3RhdGlvbiBjb25zdHJhaW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSb3RhdGlvbkNvbnN0cmFpbnQob3B0aW9ucykge1xuICB2YXIgZW5hYmxlUm90YXRpb24gPSBvcHRpb25zLmVuYWJsZVJvdGF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmVuYWJsZVJvdGF0aW9uIDogdHJ1ZTtcblxuICBpZiAoZW5hYmxlUm90YXRpb24pIHtcbiAgICB2YXIgY29uc3RyYWluUm90YXRpb24gPSBvcHRpb25zLmNvbnN0cmFpblJvdGF0aW9uO1xuXG4gICAgaWYgKGNvbnN0cmFpblJvdGF0aW9uID09PSB1bmRlZmluZWQgfHwgY29uc3RyYWluUm90YXRpb24gPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBjcmVhdGVTbmFwVG9aZXJvKCk7XG4gICAgfSBlbHNlIGlmIChjb25zdHJhaW5Sb3RhdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiByb3RhdGlvbk5vbmU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgY29uc3RyYWluUm90YXRpb24gPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gY3JlYXRlU25hcFRvTihjb25zdHJhaW5Sb3RhdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByb3RhdGlvbk5vbmU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBkaXNhYmxlO1xuICB9XG59XG4vKipcbiAqIERldGVybWluZSBpZiBhbiBhbmltYXRpb24gaW52b2x2ZXMgbm8gdmlldyBjaGFuZ2UuXG4gKiBAcGFyYW0ge0FuaW1hdGlvbn0gYW5pbWF0aW9uIFRoZSBhbmltYXRpb24uXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgYW5pbWF0aW9uIGludm9sdmVzIG5vIHZpZXcgY2hhbmdlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpc05vb3BBbmltYXRpb24oYW5pbWF0aW9uKSB7XG4gIGlmIChhbmltYXRpb24uc291cmNlQ2VudGVyICYmIGFuaW1hdGlvbi50YXJnZXRDZW50ZXIpIHtcbiAgICBpZiAoIWNvb3JkaW5hdGVzRXF1YWwoYW5pbWF0aW9uLnNvdXJjZUNlbnRlciwgYW5pbWF0aW9uLnRhcmdldENlbnRlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBpZiAoYW5pbWF0aW9uLnNvdXJjZVJlc29sdXRpb24gIT09IGFuaW1hdGlvbi50YXJnZXRSZXNvbHV0aW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGFuaW1hdGlvbi5zb3VyY2VSb3RhdGlvbiAhPT0gYW5pbWF0aW9uLnRhcmdldFJvdGF0aW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IHNpemUgQm94IHBpeGVsIHNpemUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBvc2l0aW9uIFBvc2l0aW9uIG9uIHRoZSB2aWV3IHRvIGNlbnRlciBvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gU2hpZnRlZCBjZW50ZXIuXG4gKi9cblxuZnVuY3Rpb24gY2FsY3VsYXRlQ2VudGVyT24oY29vcmRpbmF0ZSwgc2l6ZSwgcG9zaXRpb24sIHJlc29sdXRpb24sIHJvdGF0aW9uKSB7XG4gIC8vIGNhbGN1bGF0ZSByb3RhdGVkIHBvc2l0aW9uXG4gIHZhciBjb3NBbmdsZSA9IE1hdGguY29zKC1yb3RhdGlvbik7XG4gIHZhciBzaW5BbmdsZSA9IE1hdGguc2luKC1yb3RhdGlvbik7XG4gIHZhciByb3RYID0gY29vcmRpbmF0ZVswXSAqIGNvc0FuZ2xlIC0gY29vcmRpbmF0ZVsxXSAqIHNpbkFuZ2xlO1xuICB2YXIgcm90WSA9IGNvb3JkaW5hdGVbMV0gKiBjb3NBbmdsZSArIGNvb3JkaW5hdGVbMF0gKiBzaW5BbmdsZTtcbiAgcm90WCArPSAoc2l6ZVswXSAvIDIgLSBwb3NpdGlvblswXSkgKiByZXNvbHV0aW9uO1xuICByb3RZICs9IChwb3NpdGlvblsxXSAtIHNpemVbMV0gLyAyKSAqIHJlc29sdXRpb247IC8vIGdvIGJhY2sgdG8gb3JpZ2luYWwgYW5nbGVcblxuICBzaW5BbmdsZSA9IC1zaW5BbmdsZTsgLy8gZ28gYmFjayB0byBvcmlnaW5hbCByb3RhdGlvblxuXG4gIHZhciBjZW50ZXJYID0gcm90WCAqIGNvc0FuZ2xlIC0gcm90WSAqIHNpbkFuZ2xlO1xuICB2YXIgY2VudGVyWSA9IHJvdFkgKiBjb3NBbmdsZSArIHJvdFggKiBzaW5BbmdsZTtcbiAgcmV0dXJuIFtjZW50ZXJYLCBjZW50ZXJZXTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgVmlldzsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc2l6ZVxuICovXG5cbi8qKlxuICogQW4gYXJyYXkgb2YgbnVtYmVycyByZXByZXNlbnRpbmcgYSBzaXplOiBgW3dpZHRoLCBoZWlnaHRdYC5cbiAqIEB0eXBlZGVmIHtBcnJheTxudW1iZXI+fSBTaXplXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgYnVmZmVyZWQgc2l6ZS5cbiAqIEBwYXJhbSB7U2l6ZX0gc2l6ZSBTaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IG51bSBUaGUgYW1vdW50IGJ5IHdoaWNoIHRvIGJ1ZmZlci5cbiAqIEBwYXJhbSB7U2l6ZT19IG9wdF9zaXplIE9wdGlvbmFsIHJldXNhYmxlIHNpemUgYXJyYXkuXG4gKiBAcmV0dXJuIHtTaXplfSBUaGUgYnVmZmVyZWQgc2l6ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1ZmZlcihzaXplLCBudW0sIG9wdF9zaXplKSB7XG4gIGlmIChvcHRfc2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgb3B0X3NpemUgPSBbMCwgMF07XG4gIH1cblxuICBvcHRfc2l6ZVswXSA9IHNpemVbMF0gKyAyICogbnVtO1xuICBvcHRfc2l6ZVsxXSA9IHNpemVbMV0gKyAyICogbnVtO1xuICByZXR1cm4gb3B0X3NpemU7XG59XG4vKipcbiAqIERldGVybWluZXMgaWYgYSBzaXplIGhhcyBhIHBvc2l0aXZlIGFyZWEuXG4gKiBAcGFyYW0ge1NpemV9IHNpemUgVGhlIHNpemUgdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBzaXplIGhhcyBhIHBvc2l0aXZlIGFyZWEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0FyZWEoc2l6ZSkge1xuICByZXR1cm4gc2l6ZVswXSA+IDAgJiYgc2l6ZVsxXSA+IDA7XG59XG4vKipcbiAqIFJldHVybnMgYSBzaXplIHNjYWxlZCBieSBhIHJhdGlvLiBUaGUgcmVzdWx0IHdpbGwgYmUgYW4gYXJyYXkgb2YgaW50ZWdlcnMuXG4gKiBAcGFyYW0ge1NpemV9IHNpemUgU2l6ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYXRpbyBSYXRpby5cbiAqIEBwYXJhbSB7U2l6ZT19IG9wdF9zaXplIE9wdGlvbmFsIHJldXNhYmxlIHNpemUgYXJyYXkuXG4gKiBAcmV0dXJuIHtTaXplfSBUaGUgc2NhbGVkIHNpemUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlKHNpemUsIHJhdGlvLCBvcHRfc2l6ZSkge1xuICBpZiAob3B0X3NpemUgPT09IHVuZGVmaW5lZCkge1xuICAgIG9wdF9zaXplID0gWzAsIDBdO1xuICB9XG5cbiAgb3B0X3NpemVbMF0gPSBzaXplWzBdICogcmF0aW8gKyAwLjUgfCAwO1xuICBvcHRfc2l6ZVsxXSA9IHNpemVbMV0gKiByYXRpbyArIDAuNSB8IDA7XG4gIHJldHVybiBvcHRfc2l6ZTtcbn1cbi8qKlxuICogUmV0dXJucyBhbiBgU2l6ZWAgYXJyYXkgZm9yIHRoZSBwYXNzZWQgaW4gbnVtYmVyIChtZWFuaW5nOiBzcXVhcmUpIG9yXG4gKiBgU2l6ZWAgYXJyYXkuXG4gKiAobWVhbmluZzogbm9uLXNxdWFyZSksXG4gKiBAcGFyYW0ge251bWJlcnxTaXplfSBzaXplIFdpZHRoIGFuZCBoZWlnaHQuXG4gKiBAcGFyYW0ge1NpemU9fSBvcHRfc2l6ZSBPcHRpb25hbCByZXVzYWJsZSBzaXplIGFycmF5LlxuICogQHJldHVybiB7U2l6ZX0gU2l6ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9TaXplKHNpemUsIG9wdF9zaXplKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNpemUpKSB7XG4gICAgcmV0dXJuIHNpemU7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9wdF9zaXplID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG9wdF9zaXplID0gW3NpemUsIHNpemVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRfc2l6ZVswXSA9IHNpemU7XG4gICAgICBvcHRfc2l6ZVsxXSA9IHNpemU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9wdF9zaXplO1xuICB9XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9QbHVnZ2FibGVNYXBcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0LCB7IGdldENoYW5nZUV2ZW50VHlwZSB9IGZyb20gJy4vT2JqZWN0LmpzJztcbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gJy4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgQ29sbGVjdGlvbkV2ZW50VHlwZSBmcm9tICcuL0NvbGxlY3Rpb25FdmVudFR5cGUuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IExheWVyR3JvdXAgZnJvbSAnLi9sYXllci9Hcm91cC5qcyc7XG5pbXBvcnQgTWFwQnJvd3NlckV2ZW50IGZyb20gJy4vTWFwQnJvd3NlckV2ZW50LmpzJztcbmltcG9ydCBNYXBCcm93c2VyRXZlbnRIYW5kbGVyIGZyb20gJy4vTWFwQnJvd3NlckV2ZW50SGFuZGxlci5qcyc7XG5pbXBvcnQgTWFwQnJvd3NlckV2ZW50VHlwZSBmcm9tICcuL01hcEJyb3dzZXJFdmVudFR5cGUuanMnO1xuaW1wb3J0IE1hcEV2ZW50IGZyb20gJy4vTWFwRXZlbnQuanMnO1xuaW1wb3J0IE1hcEV2ZW50VHlwZSBmcm9tICcuL01hcEV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgTWFwUHJvcGVydHkgZnJvbSAnLi9NYXBQcm9wZXJ0eS5qcyc7XG5pbXBvcnQgT2JqZWN0RXZlbnRUeXBlIGZyb20gJy4vT2JqZWN0RXZlbnRUeXBlLmpzJztcbmltcG9ydCBQb2ludGVyRXZlbnRUeXBlIGZyb20gJy4vcG9pbnRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFJlbmRlckV2ZW50VHlwZSBmcm9tICcuL3JlbmRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGVRdWV1ZSwgeyBnZXRUaWxlUHJpb3JpdHkgfSBmcm9tICcuL1RpbGVRdWV1ZS5qcyc7XG5pbXBvcnQgVmlldyBmcm9tICcuL1ZpZXcuanMnO1xuaW1wb3J0IFZpZXdIaW50IGZyb20gJy4vVmlld0hpbnQuanMnO1xuaW1wb3J0IHsgREVWSUNFX1BJWEVMX1JBVElPLCBJTUFHRV9ERUNPREUsIFBBU1NJVkVfRVZFTlRfTElTVEVORVJTIH0gZnJvbSAnLi9oYXMuanMnO1xuaW1wb3J0IHsgVFJVRSB9IGZyb20gJy4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGFwcGx5IGFzIGFwcGx5VHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtIH0gZnJvbSAnLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGNsb25lLCBjcmVhdGVPclVwZGF0ZUVtcHR5LCBlcXVhbHMsIGdldEZvclZpZXdBbmRTaXplLCBpc0VtcHR5IH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZnJvbVVzZXJDb29yZGluYXRlLCB0b1VzZXJDb29yZGluYXRlIH0gZnJvbSAnLi9wcm9qLmpzJztcbmltcG9ydCB7IGhhc0FyZWEgfSBmcm9tICcuL3NpemUuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi9ldmVudHMuanMnO1xuaW1wb3J0IHsgcmVtb3ZlTm9kZSB9IGZyb20gJy4vZG9tLmpzJztcbi8qKlxuICogU3RhdGUgb2YgdGhlIGN1cnJlbnQgZnJhbWUuIE9ubHkgYHBpeGVsUmF0aW9gLCBgdGltZWAgYW5kIGB2aWV3U3RhdGVgIHNob3VsZFxuICogYmUgdXNlZCBpbiBhcHBsaWNhdGlvbnMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBGcmFtZVN0YXRlXG4gKiBAcHJvcGVydHkge251bWJlcn0gcGl4ZWxSYXRpbyBUaGUgcGl4ZWwgcmF0aW8gb2YgdGhlIGZyYW1lLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHRpbWUgVGhlIHRpbWUgd2hlbiByZW5kZXJpbmcgb2YgdGhlIGZyYW1lIHdhcyByZXF1ZXN0ZWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vVmlldy5qc1wiKS5TdGF0ZX0gdmlld1N0YXRlIFRoZSBzdGF0ZSBvZiB0aGUgY3VycmVudCB2aWV3LlxuICogQHByb3BlcnR5IHtib29sZWFufSBhbmltYXRlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwicmJ1c2hcIikuZGVmYXVsdH0gZGVjbHV0dGVyVHJlZVxuICogQHByb3BlcnR5IHtudWxsfGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50XG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5kZXhcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5TdGF0ZT59IGxheWVyU3RhdGVzQXJyYXlcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsYXllckluZGV4XG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gcGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm1cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8UG9zdFJlbmRlckZ1bmN0aW9uPn0gcG9zdFJlbmRlckZ1bmN0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZVxuICogQHByb3BlcnR5IHtUaWxlUXVldWV9IHRpbGVRdWV1ZVxuICogQHByb3BlcnR5IHshT2JqZWN0PHN0cmluZywgT2JqZWN0PHN0cmluZywgYm9vbGVhbj4+fSB1c2VkVGlsZXNcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gdmlld0hpbnRzXG4gKiBAcHJvcGVydHkgeyFPYmplY3Q8c3RyaW5nLCBPYmplY3Q8c3RyaW5nLCBib29sZWFuPj59IHdhbnRlZFRpbGVzXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oUGx1Z2dhYmxlTWFwLCA/RnJhbWVTdGF0ZSk6IGFueX0gUG9zdFJlbmRlckZ1bmN0aW9uXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBBdFBpeGVsT3B0aW9uc1xuICogQHByb3BlcnR5IHt1bmRlZmluZWR8ZnVuY3Rpb24oaW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0KTogYm9vbGVhbn0gW2xheWVyRmlsdGVyXSBMYXllciBmaWx0ZXJcbiAqIGZ1bmN0aW9uLiBUaGUgZmlsdGVyIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSBvbmUgYXJndW1lbnQsIHRoZVxuICoge0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllciBsYXllci1jYW5kaWRhdGV9IGFuZCBpdCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiB2YWx1ZS5cbiAqIE9ubHkgbGF5ZXJzIHdoaWNoIGFyZSB2aXNpYmxlIGFuZCBmb3Igd2hpY2ggdGhpcyBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYFxuICogd2lsbCBiZSB0ZXN0ZWQgZm9yIGZlYXR1cmVzLiBCeSBkZWZhdWx0LCBhbGwgdmlzaWJsZSBsYXllcnMgd2lsbCBiZSB0ZXN0ZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2hpdFRvbGVyYW5jZT0wXSBIaXQtZGV0ZWN0aW9uIHRvbGVyYW5jZSBpbiBjc3MgcGl4ZWxzLiBQaXhlbHNcbiAqIGluc2lkZSB0aGUgcmFkaXVzIGFyb3VuZCB0aGUgZ2l2ZW4gcG9zaXRpb24gd2lsbCBiZSBjaGVja2VkIGZvciBmZWF0dXJlcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2NoZWNrV3JhcHBlZD10cnVlXSBDaGVjay1XcmFwcGVkIFdpbGwgY2hlY2sgZm9yIGZvciB3cmFwcGVkIGdlb21ldHJpZXMgaW5zaWRlIHRoZSByYW5nZSBvZlxuICogICArLy0gMSB3b3JsZCB3aWR0aC4gV29ya3Mgb25seSBpZiBhIHByb2plY3Rpb24gaXMgdXNlZCB0aGF0IGNhbiBiZSB3cmFwcGVkLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gTWFwT3B0aW9uc0ludGVybmFsXG4gKiBAcHJvcGVydHkge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdD59IFtjb250cm9sc11cbiAqIEBwcm9wZXJ0eSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHQ+fSBbaW50ZXJhY3Rpb25zXVxuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxEb2N1bWVudH0ga2V5Ym9hcmRFdmVudFRhcmdldFxuICogQHByb3BlcnR5IHtDb2xsZWN0aW9uPGltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0Pn0gb3ZlcmxheXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0PHN0cmluZywgKj59IHZhbHVlc1xuICovXG5cbi8qKlxuICogT2JqZWN0IGxpdGVyYWwgd2l0aCBjb25maWcgb3B0aW9ucyBmb3IgdGhlIG1hcC5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IE1hcE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0PnxBcnJheTxpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0Pn0gW2NvbnRyb2xzXVxuICogQ29udHJvbHMgaW5pdGlhbGx5IGFkZGVkIHRvIHRoZSBtYXAuIElmIG5vdCBzcGVjaWZpZWQsXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2x+ZGVmYXVsdHN9IGlzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3BpeGVsUmF0aW89d2luZG93LmRldmljZVBpeGVsUmF0aW9dIFRoZSByYXRpbyBiZXR3ZWVuXG4gKiBwaHlzaWNhbCBwaXhlbHMgYW5kIGRldmljZS1pbmRlcGVuZGVudCBwaXhlbHMgKGRpcHMpIG9uIHRoZSBkZXZpY2UuXG4gKiBAcHJvcGVydHkge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0PnxBcnJheTxpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHQ+fSBbaW50ZXJhY3Rpb25zXVxuICogSW50ZXJhY3Rpb25zIHRoYXQgYXJlIGluaXRpYWxseSBhZGRlZCB0byB0aGUgbWFwLiBJZiBub3Qgc3BlY2lmaWVkLFxuICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbn5kZWZhdWx0c30gaXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8RG9jdW1lbnR8c3RyaW5nfSBba2V5Ym9hcmRFdmVudFRhcmdldF0gVGhlIGVsZW1lbnQgdG9cbiAqIGxpc3RlbiB0byBrZXlib2FyZCBldmVudHMgb24uIFRoaXMgZGV0ZXJtaW5lcyB3aGVuIHRoZSBgS2V5Ym9hcmRQYW5gIGFuZFxuICogYEtleWJvYXJkWm9vbWAgaW50ZXJhY3Rpb25zIHRyaWdnZXIuIEZvciBleGFtcGxlLCBpZiB0aGlzIG9wdGlvbiBpcyBzZXQgdG9cbiAqIGBkb2N1bWVudGAgdGhlIGtleWJvYXJkIGludGVyYWN0aW9ucyB3aWxsIGFsd2F5cyB0cmlnZ2VyLiBJZiB0aGlzIG9wdGlvbiBpc1xuICogbm90IHNwZWNpZmllZCwgdGhlIGVsZW1lbnQgdGhlIGxpYnJhcnkgbGlzdGVucyB0byBrZXlib2FyZCBldmVudHMgb24gaXMgdGhlXG4gKiBtYXAgdGFyZ2V0IChpLmUuIHRoZSB1c2VyLXByb3ZpZGVkIGRpdiBmb3IgdGhlIG1hcCkuIElmIHRoaXMgaXMgbm90XG4gKiBgZG9jdW1lbnRgLCB0aGUgdGFyZ2V0IGVsZW1lbnQgbmVlZHMgdG8gYmUgZm9jdXNlZCBmb3Iga2V5IGV2ZW50cyB0byBiZVxuICogZW1pdHRlZCwgcmVxdWlyaW5nIHRoYXQgdGhlIHRhcmdldCBlbGVtZW50IGhhcyBhIGB0YWJpbmRleGAgYXR0cmlidXRlLlxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuL2xheWVyL0Jhc2UuanNcIikuZGVmYXVsdD58Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2xheWVyL0Jhc2UuanNcIikuZGVmYXVsdD58TGF5ZXJHcm91cH0gW2xheWVyc11cbiAqIExheWVycy4gSWYgdGhpcyBpcyBub3QgZGVmaW5lZCwgYSBtYXAgd2l0aCBubyBsYXllcnMgd2lsbCBiZSByZW5kZXJlZC4gTm90ZVxuICogdGhhdCBsYXllcnMgYXJlIHJlbmRlcmVkIGluIHRoZSBvcmRlciBzdXBwbGllZCwgc28gaWYgeW91IHdhbnQsIGZvciBleGFtcGxlLFxuICogYSB2ZWN0b3IgbGF5ZXIgdG8gYXBwZWFyIG9uIHRvcCBvZiBhIHRpbGUgbGF5ZXIsIGl0IG11c3QgY29tZSBhZnRlciB0aGUgdGlsZVxuICogbGF5ZXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFRpbGVzTG9hZGluZz0xNl0gTWF4aW11bSBudW1iZXIgdGlsZXMgdG8gbG9hZFxuICogc2ltdWx0YW5lb3VzbHkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21vdmVUb2xlcmFuY2U9MV0gVGhlIG1pbmltdW0gZGlzdGFuY2UgaW4gcGl4ZWxzIHRoZVxuICogY3Vyc29yIG11c3QgbW92ZSB0byBiZSBkZXRlY3RlZCBhcyBhIG1hcCBtb3ZlIGV2ZW50IGluc3RlYWQgb2YgYSBjbGljay5cbiAqIEluY3JlYXNpbmcgdGhpcyB2YWx1ZSBjYW4gbWFrZSBpdCBlYXNpZXIgdG8gY2xpY2sgb24gdGhlIG1hcC5cbiAqIEBwcm9wZXJ0eSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL092ZXJsYXkuanNcIikuZGVmYXVsdD58QXJyYXk8aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHQ+fSBbb3ZlcmxheXNdXG4gKiBPdmVybGF5cyBpbml0aWFsbHkgYWRkZWQgdG8gdGhlIG1hcC4gQnkgZGVmYXVsdCwgbm8gb3ZlcmxheXMgYXJlIGFkZGVkLlxuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxzdHJpbmd9IFt0YXJnZXRdIFRoZSBjb250YWluZXIgZm9yIHRoZSBtYXAsIGVpdGhlciB0aGVcbiAqIGVsZW1lbnQgaXRzZWxmIG9yIHRoZSBgaWRgIG9mIHRoZSBlbGVtZW50LiBJZiBub3Qgc3BlY2lmaWVkIGF0IGNvbnN0cnVjdGlvblxuICogdGltZSwge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwI3NldFRhcmdldH0gbXVzdCBiZSBjYWxsZWQgZm9yIHRoZSBtYXAgdG8gYmVcbiAqIHJlbmRlcmVkLiBJZiBwYXNzZWQgYnkgZWxlbWVudCwgdGhlIGNvbnRhaW5lciBjYW4gYmUgaW4gYSBzZWNvbmRhcnkgZG9jdW1lbnQuXG4gKiBAcHJvcGVydHkge1ZpZXd9IFt2aWV3XSBUaGUgbWFwJ3Mgdmlldy4gIE5vIGxheWVyIHNvdXJjZXMgd2lsbCBiZVxuICogZmV0Y2hlZCB1bmxlc3MgdGhpcyBpcyBzcGVjaWZpZWQgYXQgY29uc3RydWN0aW9uIHRpbWUgb3IgdGhyb3VnaFxuICoge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwI3NldFZpZXd9LlxuICovXG5cbi8qKlxuICogQGZpcmVzIGltcG9ydChcIi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLk1hcEJyb3dzZXJFdmVudFxuICogQGZpcmVzIGltcG9ydChcIi4vTWFwRXZlbnQuanNcIikuTWFwRXZlbnRcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL3JlbmRlci9FdmVudC5qc1wiKS5kZWZhdWx0I3ByZWNvbXBvc2VcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL3JlbmRlci9FdmVudC5qc1wiKS5kZWZhdWx0I3Bvc3Rjb21wb3NlXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9yZW5kZXIvRXZlbnQuanNcIikuZGVmYXVsdCNyZW5kZXJjb21wbGV0ZVxuICogQGFwaVxuICovXG5cbnZhciBQbHVnZ2FibGVNYXAgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUGx1Z2dhYmxlTWFwLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtNYXBPcHRpb25zfSBvcHRpb25zIE1hcCBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFBsdWdnYWJsZU1hcChvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zSW50ZXJuYWwgPSBjcmVhdGVPcHRpb25zSW50ZXJuYWwob3B0aW9ucyk7XG4gICAgLyoqIEBwcml2YXRlICovXG5cbiAgICBfdGhpcy5ib3VuZEhhbmRsZUJyb3dzZXJFdmVudF8gPSBfdGhpcy5oYW5kbGVCcm93c2VyRXZlbnQuYmluZChfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4VGlsZXNMb2FkaW5nXyA9IG9wdGlvbnMubWF4VGlsZXNMb2FkaW5nICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heFRpbGVzTG9hZGluZyA6IDE2O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsUmF0aW9fID0gb3B0aW9ucy5waXhlbFJhdGlvICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnBpeGVsUmF0aW8gOiBERVZJQ0VfUElYRUxfUkFUSU87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Kn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBvc3RSZW5kZXJUaW1lb3V0SGFuZGxlXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5pbWF0aW9uRGVsYXlLZXlfO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5hbmltYXRpb25EZWxheV8gPVxuICAgIC8qKiBAdGhpcyB7UGx1Z2dhYmxlTWFwfSAqL1xuICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5yZW5kZXJGcmFtZV8oRGF0ZS5ub3coKSk7XG4gICAgfS5iaW5kKF90aGlzKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cblxuICAgIF90aGlzLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtXyA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtXyA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZyYW1lSW5kZXhfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/RnJhbWVTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmZyYW1lU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgZXh0ZW50IGF0IHRoZSBwcmV2aW91cyAnbW92ZWVuZCcgZXZlbnQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMucHJldmlvdXNFeHRlbnRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMudmlld1Byb3BlcnR5TGlzdGVuZXJLZXlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMudmlld0NoYW5nZUxpc3RlbmVyS2V5XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0FycmF5PGltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXllckdyb3VwUHJvcGVydHlMaXN0ZW5lcktleXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshSFRNTEVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy52aWV3cG9ydF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBfdGhpcy52aWV3cG9ydF8uY2xhc3NOYW1lID0gJ29sLXZpZXdwb3J0JyArICgnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cgPyAnIG9sLXRvdWNoJyA6ICcnKTtcbiAgICBfdGhpcy52aWV3cG9ydF8uc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIF90aGlzLnZpZXdwb3J0Xy5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIF90aGlzLnZpZXdwb3J0Xy5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBfdGhpcy52aWV3cG9ydF8uc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lcl8uc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJfLnN0eWxlLnpJbmRleCA9ICcwJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyXy5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyXy5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lcl8uc3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyXy5jbGFzc05hbWUgPSAnb2wtb3ZlcmxheWNvbnRhaW5lcic7XG5cbiAgICBfdGhpcy52aWV3cG9ydF8uYXBwZW5kQ2hpbGQoX3RoaXMub3ZlcmxheUNvbnRhaW5lcl8pO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFIVE1MRWxlbWVudH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50Xy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8uc3R5bGUuekluZGV4ID0gJzAnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICBfdGhpcy5vdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50Xy5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgIF90aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfLmNsYXNzTmFtZSA9ICdvbC1vdmVybGF5Y29udGFpbmVyLXN0b3BldmVudCc7XG5cbiAgICBfdGhpcy52aWV3cG9ydF8uYXBwZW5kQ2hpbGQoX3RoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8pO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge01hcEJyb3dzZXJFdmVudEhhbmRsZXJ9XG4gICAgICovXG5cblxuICAgIF90aGlzLm1hcEJyb3dzZXJFdmVudEhhbmRsZXJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tb3ZlVG9sZXJhbmNlXyA9IG9wdGlvbnMubW92ZVRvbGVyYW5jZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudHxEb2N1bWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLmtleWJvYXJkRXZlbnRUYXJnZXRfID0gb3B0aW9uc0ludGVybmFsLmtleWJvYXJkRXZlbnRUYXJnZXQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0FycmF5PGltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICovXG5cbiAgICBfdGhpcy5rZXlIYW5kbGVyS2V5c18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtDb2xsZWN0aW9uPGltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRyb2xzID0gb3B0aW9uc0ludGVybmFsLmNvbnRyb2xzIHx8IG5ldyBDb2xsZWN0aW9uKCk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICovXG5cbiAgICBfdGhpcy5pbnRlcmFjdGlvbnMgPSBvcHRpb25zSW50ZXJuYWwuaW50ZXJhY3Rpb25zIHx8IG5ldyBDb2xsZWN0aW9uKCk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5vdmVybGF5c18gPSBvcHRpb25zSW50ZXJuYWwub3ZlcmxheXM7XG4gICAgLyoqXG4gICAgICogQSBsb29rdXAgb2Ygb3ZlcmxheXMgYnkgaWQuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMub3ZlcmxheUlkSW5kZXhfID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vcmVuZGVyZXIvTWFwLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVyXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge3VuZGVmaW5lZHxmdW5jdGlvbihFdmVudCk6IHZvaWR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmhhbmRsZVJlc2l6ZV87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IUFycmF5PFBvc3RSZW5kZXJGdW5jdGlvbj59XG4gICAgICovXG5cbiAgICBfdGhpcy5wb3N0UmVuZGVyRnVuY3Rpb25zXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge1RpbGVRdWV1ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVRdWV1ZV8gPSBuZXcgVGlsZVF1ZXVlKF90aGlzLmdldFRpbGVQcmlvcml0eS5iaW5kKF90aGlzKSwgX3RoaXMuaGFuZGxlVGlsZUNoYW5nZV8uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoTWFwUHJvcGVydHkuTEFZRVJHUk9VUCksIF90aGlzLmhhbmRsZUxheWVyR3JvdXBDaGFuZ2VkXyk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShNYXBQcm9wZXJ0eS5WSUVXKSwgX3RoaXMuaGFuZGxlVmlld0NoYW5nZWRfKTtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKE1hcFByb3BlcnR5LlNJWkUpLCBfdGhpcy5oYW5kbGVTaXplQ2hhbmdlZF8pO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoTWFwUHJvcGVydHkuVEFSR0VUKSwgX3RoaXMuaGFuZGxlVGFyZ2V0Q2hhbmdlZF8pOyAvLyBzZXRQcm9wZXJ0aWVzIHdpbGwgdHJpZ2dlciB0aGUgcmVuZGVyaW5nIG9mIHRoZSBtYXAgaWYgdGhlIG1hcFxuICAgIC8vIGlzIFwiZGVmaW5lZFwiIGFscmVhZHkuXG5cblxuICAgIF90aGlzLnNldFByb3BlcnRpZXMob3B0aW9uc0ludGVybmFsLnZhbHVlcyk7XG5cbiAgICBfdGhpcy5jb250cm9scy5mb3JFYWNoKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdH0gY29udHJvbCBDb250cm9sLlxuICAgICAqIEB0aGlzIHtQbHVnZ2FibGVNYXB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gKGNvbnRyb2wpIHtcbiAgICAgIGNvbnRyb2wuc2V0TWFwKHRoaXMpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMuY29udHJvbHMuYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LmVsZW1lbnQuc2V0TWFwKHRoaXMpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMuY29udHJvbHMuYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LmVsZW1lbnQuc2V0TWFwKG51bGwpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMuaW50ZXJhY3Rpb25zLmZvckVhY2goXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHR9IGludGVyYWN0aW9uIEludGVyYWN0aW9uLlxuICAgICAqIEB0aGlzIHtQbHVnZ2FibGVNYXB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgICBpbnRlcmFjdGlvbi5zZXRNYXAodGhpcyk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5pbnRlcmFjdGlvbnMuYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LmVsZW1lbnQuc2V0TWFwKHRoaXMpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMuaW50ZXJhY3Rpb25zLmFkZEV2ZW50TGlzdGVuZXIoQ29sbGVjdGlvbkV2ZW50VHlwZS5SRU1PVkUsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbkV2ZW50fSBldmVudCBDb2xsZWN0aW9uRXZlbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICBldmVudC5lbGVtZW50LnNldE1hcChudWxsKTtcbiAgICB9LmJpbmQoX3RoaXMpKTtcblxuICAgIF90aGlzLm92ZXJsYXlzXy5mb3JFYWNoKF90aGlzLmFkZE92ZXJsYXlJbnRlcm5hbF8uYmluZChfdGhpcykpO1xuXG4gICAgX3RoaXMub3ZlcmxheXNfLmFkZEV2ZW50TGlzdGVuZXIoQ29sbGVjdGlvbkV2ZW50VHlwZS5BREQsXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbkV2ZW50fSBldmVudCBDb2xsZWN0aW9uRXZlbnQuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICB0aGlzLmFkZE92ZXJsYXlJbnRlcm5hbF8oXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZXZlbnQuZWxlbWVudCk7XG4gICAgfS5iaW5kKF90aGlzKSk7XG5cbiAgICBfdGhpcy5vdmVybGF5c18uYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5Db2xsZWN0aW9uRXZlbnR9IGV2ZW50IENvbGxlY3Rpb25FdmVudC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgIHZhciBvdmVybGF5ID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBldmVudC5lbGVtZW50O1xuICAgICAgdmFyIGlkID0gb3ZlcmxheS5nZXRJZCgpO1xuXG4gICAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWxldGUgdGhpcy5vdmVybGF5SWRJbmRleF9baWQudG9TdHJpbmcoKV07XG4gICAgICB9XG5cbiAgICAgIGV2ZW50LmVsZW1lbnQuc2V0TWFwKG51bGwpO1xuICAgIH0uYmluZChfdGhpcykpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9yZW5kZXJlci9NYXAuanNcIikuZGVmYXVsdH0gVGhlIG1hcCByZW5kZXJlclxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuY3JlYXRlUmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVc2UgYSBtYXAgdHlwZSB0aGF0IGhhcyBhIGNyZWF0ZVJlbmRlcmVyIG1ldGhvZCcpO1xuICB9O1xuICAvKipcbiAgICogQWRkIHRoZSBnaXZlbiBjb250cm9sIHRvIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdH0gY29udHJvbCBDb250cm9sLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5hZGRDb250cm9sID0gZnVuY3Rpb24gKGNvbnRyb2wpIHtcbiAgICB0aGlzLmdldENvbnRyb2xzKCkucHVzaChjb250cm9sKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZCB0aGUgZ2l2ZW4gaW50ZXJhY3Rpb24gdG8gdGhlIG1hcC4gSWYgeW91IHdhbnQgdG8gYWRkIGFuIGludGVyYWN0aW9uXG4gICAqIGF0IGFub3RoZXIgcG9pbnQgb2YgdGhlIGNvbGxlY3Rpb24gdXNlIGBnZXRJbnRlcmFjdGlvbigpYCBhbmQgdGhlIG1ldGhvZHNcbiAgICogYXZhaWxhYmxlIG9uIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufS4gVGhpcyBjYW4gYmUgdXNlZCB0b1xuICAgKiBzdG9wIHRoZSBldmVudCBwcm9wYWdhdGlvbiBmcm9tIHRoZSBoYW5kbGVFdmVudCBmdW5jdGlvbi4gVGhlIGludGVyYWN0aW9uc1xuICAgKiBnZXQgdG8gaGFuZGxlIHRoZSBldmVudHMgaW4gdGhlIHJldmVyc2Ugb3JkZXIgb2YgdGhpcyBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdH0gaW50ZXJhY3Rpb24gSW50ZXJhY3Rpb24gdG8gYWRkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5hZGRJbnRlcmFjdGlvbiA9IGZ1bmN0aW9uIChpbnRlcmFjdGlvbikge1xuICAgIHRoaXMuZ2V0SW50ZXJhY3Rpb25zKCkucHVzaChpbnRlcmFjdGlvbik7XG4gIH07XG4gIC8qKlxuICAgKiBBZGRzIHRoZSBnaXZlbiBsYXllciB0byB0aGUgdG9wIG9mIHRoaXMgbWFwLiBJZiB5b3Ugd2FudCB0byBhZGQgYSBsYXllclxuICAgKiBlbHNld2hlcmUgaW4gdGhlIHN0YWNrLCB1c2UgYGdldExheWVycygpYCBhbmQgdGhlIG1ldGhvZHMgYXZhaWxhYmxlIG9uXG4gICAqIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2xheWVyL0Jhc2UuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmFkZExheWVyID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgdmFyIGxheWVycyA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpLmdldExheWVycygpO1xuICAgIGxheWVycy5wdXNoKGxheWVyKTtcbiAgfTtcbiAgLyoqXG4gICAqIEFkZCB0aGUgZ2l2ZW4gb3ZlcmxheSB0byB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0fSBvdmVybGF5IE92ZXJsYXkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmFkZE92ZXJsYXkgPSBmdW5jdGlvbiAob3ZlcmxheSkge1xuICAgIHRoaXMuZ2V0T3ZlcmxheXMoKS5wdXNoKG92ZXJsYXkpO1xuICB9O1xuICAvKipcbiAgICogVGhpcyBkZWFscyB3aXRoIG1hcCdzIG92ZXJsYXkgY29sbGVjdGlvbiBjaGFuZ2VzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0fSBvdmVybGF5IE92ZXJsYXkuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5hZGRPdmVybGF5SW50ZXJuYWxfID0gZnVuY3Rpb24gKG92ZXJsYXkpIHtcbiAgICB2YXIgaWQgPSBvdmVybGF5LmdldElkKCk7XG5cbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5vdmVybGF5SWRJbmRleF9baWQudG9TdHJpbmcoKV0gPSBvdmVybGF5O1xuICAgIH1cblxuICAgIG92ZXJsYXkuc2V0TWFwKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICpcbiAgICogQ2xlYW4gdXAuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5kaXNwb3NlSW50ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRUYXJnZXQobnVsbCk7XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogRGV0ZWN0IGZlYXR1cmVzIHRoYXQgaW50ZXJzZWN0IGEgcGl4ZWwgb24gdGhlIHZpZXdwb3J0LCBhbmQgZXhlY3V0ZSBhXG4gICAqIGNhbGxiYWNrIHdpdGggZWFjaCBpbnRlcnNlY3RpbmcgZmVhdHVyZS4gTGF5ZXJzIGluY2x1ZGVkIGluIHRoZSBkZXRlY3Rpb24gY2FuXG4gICAqIGJlIGNvbmZpZ3VyZWQgdGhyb3VnaCB0aGUgYGxheWVyRmlsdGVyYCBvcHRpb24gaW4gYG9wdF9vcHRpb25zYC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2UsIGltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHQpOiBUfSBjYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLiBUaGUgY2FsbGJhY2sgd2lsbCBiZVxuICAgKiAgICAgY2FsbGVkIHdpdGggdHdvIGFyZ3VtZW50cy4gVGhlIGZpcnN0IGFyZ3VtZW50IGlzIG9uZVxuICAgKiAgICAge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlIGZlYXR1cmV9IG9yXG4gICAqICAgICB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9GZWF0dXJlIHJlbmRlciBmZWF0dXJlfSBhdCB0aGUgcGl4ZWwsIHRoZSBzZWNvbmQgaXNcbiAgICogICAgIHRoZSB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0xheWVyIGxheWVyfSBvZiB0aGUgZmVhdHVyZSBhbmQgd2lsbCBiZSBudWxsIGZvclxuICAgKiAgICAgdW5tYW5hZ2VkIGxheWVycy4gVG8gc3RvcCBkZXRlY3Rpb24sIGNhbGxiYWNrIGZ1bmN0aW9ucyBjYW4gcmV0dXJuIGFcbiAgICogICAgIHRydXRoeSB2YWx1ZS5cbiAgICogQHBhcmFtIHtBdFBpeGVsT3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbmFsIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQsIGkuZS4gdGhlIHJldHVybiB2YWx1ZSBvZiBsYXN0XG4gICAqIGNhbGxiYWNrIGV4ZWN1dGlvbiwgb3IgdGhlIGZpcnN0IHRydXRoeSBjYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqIEB0ZW1wbGF0ZSBTLFRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBjYWxsYmFjaywgb3B0X29wdGlvbnMpIHtcbiAgICBpZiAoIXRoaXMuZnJhbWVTdGF0ZV8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRpbmF0ZSA9IHRoaXMuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKHBpeGVsKTtcbiAgICBvcHRfb3B0aW9ucyA9IG9wdF9vcHRpb25zICE9PSB1bmRlZmluZWQgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBoaXRUb2xlcmFuY2UgPSBvcHRfb3B0aW9ucy5oaXRUb2xlcmFuY2UgIT09IHVuZGVmaW5lZCA/IG9wdF9vcHRpb25zLmhpdFRvbGVyYW5jZSA6IDA7XG4gICAgdmFyIGxheWVyRmlsdGVyID0gb3B0X29wdGlvbnMubGF5ZXJGaWx0ZXIgIT09IHVuZGVmaW5lZCA/IG9wdF9vcHRpb25zLmxheWVyRmlsdGVyIDogVFJVRTtcbiAgICB2YXIgY2hlY2tXcmFwcGVkID0gb3B0X29wdGlvbnMuY2hlY2tXcmFwcGVkICE9PSBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJlcl8uZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUoY29vcmRpbmF0ZSwgdGhpcy5mcmFtZVN0YXRlXywgaGl0VG9sZXJhbmNlLCBjaGVja1dyYXBwZWQsIGNhbGxiYWNrLCBudWxsLCBsYXllckZpbHRlciwgbnVsbCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYWxsIGZlYXR1cmVzIHRoYXQgaW50ZXJzZWN0IGEgcGl4ZWwgb24gdGhlIHZpZXdwb3J0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge0F0UGl4ZWxPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9uYWwgb3B0aW9ucy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gVGhlIGRldGVjdGVkIGZlYXR1cmVzIG9yXG4gICAqIGFuIGVtcHR5IGFycmF5IGlmIG5vbmUgd2VyZSBmb3VuZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0RmVhdHVyZXNBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBmZWF0dXJlcyA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaEZlYXR1cmVBdFBpeGVsKHBpeGVsLCBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgZmVhdHVyZXMucHVzaChmZWF0dXJlKTtcbiAgICB9LCBvcHRfb3B0aW9ucyk7XG4gICAgcmV0dXJuIGZlYXR1cmVzO1xuICB9O1xuICAvKipcbiAgICogRGV0ZWN0IGxheWVycyB0aGF0IGhhdmUgYSBjb2xvciB2YWx1ZSBhdCBhIHBpeGVsIG9uIHRoZSB2aWV3cG9ydCwgYW5kXG4gICAqIGV4ZWN1dGUgYSBjYWxsYmFjayB3aXRoIGVhY2ggbWF0Y2hpbmcgbGF5ZXIuIExheWVycyBpbmNsdWRlZCBpbiB0aGVcbiAgICogZGV0ZWN0aW9uIGNhbiBiZSBjb25maWd1cmVkIHRocm91Z2ggYG9wdF9sYXllckZpbHRlcmAuXG4gICAqXG4gICAqIE5vdGU6IHRoaXMgbWF5IGdpdmUgZmFsc2UgcG9zaXRpdmVzIHVubGVzcyB0aGUgbWFwIGxheWVycyBoYXZlIGhhZCBkaWZmZXJlbnQgYGNsYXNzTmFtZWBcbiAgICogcHJvcGVydGllcyBhc3NpZ25lZCB0byB0aGVtLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6IFMsIGltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdCwgKFVpbnQ4Q2xhbXBlZEFycmF5fFVpbnQ4QXJyYXkpKTogVH0gY2FsbGJhY2tcbiAgICogICAgIExheWVyIGNhbGxiYWNrLiBUaGlzIGNhbGxiYWNrIHdpbGwgcmVjZWl2ZSB0d28gYXJndW1lbnRzOiBmaXJzdCBpcyB0aGVcbiAgICogICAgIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvTGF5ZXIgbGF5ZXJ9LCBzZWNvbmQgYXJndW1lbnQgaXMgYW4gYXJyYXkgcmVwcmVzZW50aW5nXG4gICAqICAgICBbUiwgRywgQiwgQV0gcGl4ZWwgdmFsdWVzICgwIC0gMjU1KSBhbmQgd2lsbCBiZSBgbnVsbGAgZm9yIGxheWVyIHR5cGVzXG4gICAqICAgICB0aGF0IGRvIG5vdCBjdXJyZW50bHkgc3VwcG9ydCB0aGlzIGFyZ3VtZW50LiBUbyBzdG9wIGRldGVjdGlvbiwgY2FsbGJhY2tcbiAgICogICAgIGZ1bmN0aW9ucyBjYW4gcmV0dXJuIGEgdHJ1dGh5IHZhbHVlLlxuICAgKiBAcGFyYW0ge0F0UGl4ZWxPcHRpb25zPX0gb3B0X29wdGlvbnMgQ29uZmlndXJhdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LCBpLmUuIHRoZSByZXR1cm4gdmFsdWUgb2YgbGFzdFxuICAgKiBjYWxsYmFjayBleGVjdXRpb24sIG9yIHRoZSBmaXJzdCB0cnV0aHkgY2FsbGJhY2sgcmV0dXJuIHZhbHVlLlxuICAgKiBAdGVtcGxhdGUgUyxUXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmZvckVhY2hMYXllckF0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIGNhbGxiYWNrLCBvcHRfb3B0aW9ucykge1xuICAgIGlmICghdGhpcy5mcmFtZVN0YXRlXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgdmFyIGhpdFRvbGVyYW5jZSA9IG9wdGlvbnMuaGl0VG9sZXJhbmNlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmhpdFRvbGVyYW5jZSA6IDA7XG4gICAgdmFyIGxheWVyRmlsdGVyID0gb3B0aW9ucy5sYXllckZpbHRlciB8fCBUUlVFO1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyXy5mb3JFYWNoTGF5ZXJBdFBpeGVsKHBpeGVsLCB0aGlzLmZyYW1lU3RhdGVfLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBsYXllckZpbHRlcik7XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgZmVhdHVyZXMgaW50ZXJzZWN0IGEgcGl4ZWwgb24gdGhlIHZpZXdwb3J0LiBMYXllcnMgaW5jbHVkZWQgaW4gdGhlXG4gICAqIGRldGVjdGlvbiBjYW4gYmUgY29uZmlndXJlZCB0aHJvdWdoIGBvcHRfbGF5ZXJGaWx0ZXJgLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge0F0UGl4ZWxPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9uYWwgb3B0aW9ucy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgdGhlcmUgYSBmZWF0dXJlIGF0IHRoZSBnaXZlbiBwaXhlbD9cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFzRmVhdHVyZUF0UGl4ZWwgPSBmdW5jdGlvbiAocGl4ZWwsIG9wdF9vcHRpb25zKSB7XG4gICAgaWYgKCF0aGlzLmZyYW1lU3RhdGVfKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGNvb3JkaW5hdGUgPSB0aGlzLmdldENvb3JkaW5hdGVGcm9tUGl4ZWxJbnRlcm5hbChwaXhlbCk7XG4gICAgb3B0X29wdGlvbnMgPSBvcHRfb3B0aW9ucyAhPT0gdW5kZWZpbmVkID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgbGF5ZXJGaWx0ZXIgPSBvcHRfb3B0aW9ucy5sYXllckZpbHRlciAhPT0gdW5kZWZpbmVkID8gb3B0X29wdGlvbnMubGF5ZXJGaWx0ZXIgOiBUUlVFO1xuICAgIHZhciBoaXRUb2xlcmFuY2UgPSBvcHRfb3B0aW9ucy5oaXRUb2xlcmFuY2UgIT09IHVuZGVmaW5lZCA/IG9wdF9vcHRpb25zLmhpdFRvbGVyYW5jZSA6IDA7XG4gICAgdmFyIGNoZWNrV3JhcHBlZCA9IG9wdF9vcHRpb25zLmNoZWNrV3JhcHBlZCAhPT0gZmFsc2U7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXJfLmhhc0ZlYXR1cmVBdENvb3JkaW5hdGUoY29vcmRpbmF0ZSwgdGhpcy5mcmFtZVN0YXRlXywgaGl0VG9sZXJhbmNlLCBjaGVja1dyYXBwZWQsIGxheWVyRmlsdGVyLCBudWxsKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNvb3JkaW5hdGUgaW4gdXNlciBwcm9qZWN0aW9uIGZvciBhIGJyb3dzZXIgZXZlbnQuXG4gICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRFdmVudENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb29yZGluYXRlRnJvbVBpeGVsKHRoaXMuZ2V0RXZlbnRQaXhlbChldmVudCkpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29vcmRpbmF0ZSBpbiB2aWV3IHByb2plY3Rpb24gZm9yIGEgYnJvd3NlciBldmVudC5cbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudCBFdmVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRFdmVudENvb3JkaW5hdGVJbnRlcm5hbCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHJldHVybiB0aGlzLmdldENvb3JkaW5hdGVGcm9tUGl4ZWxJbnRlcm5hbCh0aGlzLmdldEV2ZW50UGl4ZWwoZXZlbnQpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG1hcCBwaXhlbCBwb3NpdGlvbiBmb3IgYSBicm93c2VyIGV2ZW50IHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydC5cbiAgICogQHBhcmFtIHtVSUV2ZW50fSBldmVudCBFdmVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gUGl4ZWwuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldEV2ZW50UGl4ZWwgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgdmlld3BvcnRQb3NpdGlvbiA9IHRoaXMudmlld3BvcnRfLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBldmVudFBvc2l0aW9uID0gLy9GSVhNRSBBcmUgd2UgcmVhbGx5IGNhbGxpbmcgdGhpcyB3aXRoIGEgVG91Y2hFdmVudCBhbnl3aGVyZT9cbiAgICAnY2hhbmdlZFRvdWNoZXMnIGluIGV2ZW50ID9cbiAgICAvKiogQHR5cGUge1RvdWNoRXZlbnR9ICovXG4gICAgZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF0gOlxuICAgIC8qKiBAdHlwZSB7TW91c2VFdmVudH0gKi9cbiAgICBldmVudDtcbiAgICByZXR1cm4gW2V2ZW50UG9zaXRpb24uY2xpZW50WCAtIHZpZXdwb3J0UG9zaXRpb24ubGVmdCwgZXZlbnRQb3NpdGlvbi5jbGllbnRZIC0gdmlld3BvcnRQb3NpdGlvbi50b3BdO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB0YXJnZXQgaW4gd2hpY2ggdGhpcyBtYXAgaXMgcmVuZGVyZWQuXG4gICAqIE5vdGUgdGhhdCB0aGlzIHJldHVybnMgd2hhdCBpcyBlbnRlcmVkIGFzIGFuIG9wdGlvbiBvciBpbiBzZXRUYXJnZXQ6XG4gICAqIGlmIHRoYXQgd2FzIGFuIGVsZW1lbnQsIGl0IHJldHVybnMgYW4gZWxlbWVudDsgaWYgYSBzdHJpbmcsIGl0IHJldHVybnMgdGhhdC5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR8c3RyaW5nfHVuZGVmaW5lZH0gVGhlIEVsZW1lbnQgb3IgaWQgb2YgdGhlIEVsZW1lbnQgdGhhdCB0aGVcbiAgICogICAgIG1hcCBpcyByZW5kZXJlZCBpbi5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0VGFyZ2V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge0hUTUxFbGVtZW50fHN0cmluZ3x1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChNYXBQcm9wZXJ0eS5UQVJHRVQpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgRE9NIGVsZW1lbnQgaW50byB3aGljaCB0aGlzIG1hcCBpcyByZW5kZXJlZC4gSW4gY29udHJhc3QgdG9cbiAgICogYGdldFRhcmdldGAgdGhpcyBtZXRob2QgYWx3YXlzIHJldHVybiBhbiBgRWxlbWVudGAsIG9yIGBudWxsYCBpZiB0aGVcbiAgICogbWFwIGhhcyBubyB0YXJnZXQuXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgZWxlbWVudCB0aGF0IHRoZSBtYXAgaXMgcmVuZGVyZWQgaW4uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldFRhcmdldEVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHRhcmdldCA9IHRoaXMuZ2V0VGFyZ2V0KCk7XG5cbiAgICBpZiAodGFyZ2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0eXBlb2YgdGFyZ2V0ID09PSAnc3RyaW5nJyA/IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldCkgOiB0YXJnZXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY29vcmRpbmF0ZSBmb3IgYSBnaXZlbiBwaXhlbC4gIFRoaXMgcmV0dXJucyBhIGNvb3JkaW5hdGUgaW4gdGhlXG4gICAqIHVzZXIgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbCBwb3NpdGlvbiBpbiB0aGUgbWFwIHZpZXdwb3J0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVGhlIGNvb3JkaW5hdGUgZm9yIHRoZSBwaXhlbCBwb3NpdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbCA9IGZ1bmN0aW9uIChwaXhlbCkge1xuICAgIHJldHVybiB0b1VzZXJDb29yZGluYXRlKHRoaXMuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKHBpeGVsKSwgdGhpcy5nZXRWaWV3KCkuZ2V0UHJvamVjdGlvbigpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY29vcmRpbmF0ZSBmb3IgYSBnaXZlbiBwaXhlbC4gIFRoaXMgcmV0dXJucyBhIGNvb3JkaW5hdGUgaW4gdGhlXG4gICAqIG1hcCB2aWV3IHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwgcG9zaXRpb24gaW4gdGhlIG1hcCB2aWV3cG9ydC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFRoZSBjb29yZGluYXRlIGZvciB0aGUgcGl4ZWwgcG9zaXRpb24uXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICB2YXIgZnJhbWVTdGF0ZSA9IHRoaXMuZnJhbWVTdGF0ZV87XG5cbiAgICBpZiAoIWZyYW1lU3RhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5waXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybSwgcGl4ZWwuc2xpY2UoKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgY29udHJvbHMuIE1vZGlmeWluZyB0aGlzIGNvbGxlY3Rpb24gY2hhbmdlcyB0aGUgY29udHJvbHNcbiAgICogYXNzb2NpYXRlZCB3aXRoIHRoZSBtYXAuXG4gICAqIEByZXR1cm4ge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9jb250cm9sL0NvbnRyb2wuanNcIikuZGVmYXVsdD59IENvbnRyb2xzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRDb250cm9scyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWFwIG92ZXJsYXlzLiBNb2RpZnlpbmcgdGhpcyBjb2xsZWN0aW9uIGNoYW5nZXMgdGhlIG92ZXJsYXlzXG4gICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFwLlxuICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9uPGltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0Pn0gT3ZlcmxheXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldE92ZXJsYXlzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXlzXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbiBvdmVybGF5IGJ5IGl0cyBpZGVudGlmaWVyICh0aGUgdmFsdWUgcmV0dXJuZWQgYnkgb3ZlcmxheS5nZXRJZCgpKS5cbiAgICogTm90ZSB0aGF0IHRoZSBpbmRleCB0cmVhdHMgc3RyaW5nIGFuZCBudW1lcmljIGlkZW50aWZpZXJzIGFzIHRoZSBzYW1lLiBTb1xuICAgKiBgbWFwLmdldE92ZXJsYXlCeUlkKDIpYCB3aWxsIHJldHVybiBhbiBvdmVybGF5IHdpdGggaWQgYCcyJ2Agb3IgYDJgLlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIE92ZXJsYXkgaWRlbnRpZmllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9PdmVybGF5LmpzXCIpLmRlZmF1bHR9IE92ZXJsYXkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldE92ZXJsYXlCeUlkID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgdmFyIG92ZXJsYXkgPSB0aGlzLm92ZXJsYXlJZEluZGV4X1tpZC50b1N0cmluZygpXTtcbiAgICByZXR1cm4gb3ZlcmxheSAhPT0gdW5kZWZpbmVkID8gb3ZlcmxheSA6IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hcCBpbnRlcmFjdGlvbnMuIE1vZGlmeWluZyB0aGlzIGNvbGxlY3Rpb24gY2hhbmdlcyB0aGUgaW50ZXJhY3Rpb25zXG4gICAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgbWFwLlxuICAgKlxuICAgKiBJbnRlcmFjdGlvbnMgYXJlIHVzZWQgZm9yIGUuZy4gcGFuLCB6b29tIGFuZCByb3RhdGUuXG4gICAqIEByZXR1cm4ge0NvbGxlY3Rpb248aW1wb3J0KFwiLi9pbnRlcmFjdGlvbi9JbnRlcmFjdGlvbi5qc1wiKS5kZWZhdWx0Pn0gSW50ZXJhY3Rpb25zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRJbnRlcmFjdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW50ZXJhY3Rpb25zO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsYXllcmdyb3VwIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1hcC5cbiAgICogQHJldHVybiB7TGF5ZXJHcm91cH0gQSBsYXllciBncm91cCBjb250YWluaW5nIHRoZSBsYXllcnMgaW4gdGhpcyBtYXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldExheWVyR3JvdXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7TGF5ZXJHcm91cH0gKi9cbiAgICAgIHRoaXMuZ2V0KE1hcFByb3BlcnR5LkxBWUVSR1JPVVApXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY29sbGVjdGlvbiBvZiBsYXllcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgbWFwLlxuICAgKiBAcmV0dXJuIHshQ29sbGVjdGlvbjxpbXBvcnQoXCIuL2xheWVyL0Jhc2UuanNcIikuZGVmYXVsdD59IExheWVycy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0TGF5ZXJzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXllcnMgPSB0aGlzLmdldExheWVyR3JvdXAoKS5nZXRMYXllcnMoKTtcbiAgICByZXR1cm4gbGF5ZXJzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gTGF5ZXJzIGhhdmUgc291cmNlcyB0aGF0IGFyZSBzdGlsbCBsb2FkaW5nLlxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0TG9hZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5ZXJTdGF0ZXNBcnJheSA9IHRoaXMuZ2V0TGF5ZXJHcm91cCgpLmdldExheWVyU3RhdGVzQXJyYXkoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxheWVyU3RhdGVzQXJyYXkubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGxheWVyID0gbGF5ZXJTdGF0ZXNBcnJheVtpXS5sYXllcjtcbiAgICAgIHZhciBzb3VyY2UgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBsYXllci5nZXRTb3VyY2UoKTtcblxuICAgICAgaWYgKHNvdXJjZSAmJiBzb3VyY2UubG9hZGluZykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHBpeGVsIGZvciBhIGNvb3JkaW5hdGUuICBUaGlzIHRha2VzIGEgY29vcmRpbmF0ZSBpbiB0aGUgdXNlclxuICAgKiBwcm9qZWN0aW9uIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHBpeGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIEEgbWFwIGNvb3JkaW5hdGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IEEgcGl4ZWwgcG9zaXRpb24gaW4gdGhlIG1hcCB2aWV3cG9ydC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgdmFyIHZpZXdDb29yZGluYXRlID0gZnJvbVVzZXJDb29yZGluYXRlKGNvb3JkaW5hdGUsIHRoaXMuZ2V0VmlldygpLmdldFByb2plY3Rpb24oKSk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZUludGVybmFsKHZpZXdDb29yZGluYXRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcGl4ZWwgZm9yIGEgY29vcmRpbmF0ZS4gIFRoaXMgdGFrZXMgYSBjb29yZGluYXRlIGluIHRoZSBtYXAgdmlld1xuICAgKiBwcm9qZWN0aW9uIGFuZCByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHBpeGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIEEgbWFwIGNvb3JkaW5hdGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IEEgcGl4ZWwgcG9zaXRpb24gaW4gdGhlIG1hcCB2aWV3cG9ydC5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldFBpeGVsRnJvbUNvb3JkaW5hdGVJbnRlcm5hbCA9IGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgdmFyIGZyYW1lU3RhdGUgPSB0aGlzLmZyYW1lU3RhdGVfO1xuXG4gICAgaWYgKCFmcmFtZVN0YXRlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0sIGNvb3JkaW5hdGUuc2xpY2UoMCwgMikpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWFwIHJlbmRlcmVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3JlbmRlcmVyL01hcC5qc1wiKS5kZWZhdWx0fSBSZW5kZXJlclxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0UmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyZXJfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzaXplIG9mIHRoaXMgbWFwLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZXx1bmRlZmluZWR9IFRoZSBzaXplIGluIHBpeGVscyBvZiB0aGUgbWFwIGluIHRoZSBET00uXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmdldFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoTWFwUHJvcGVydHkuU0laRSlcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB2aWV3IGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1hcC4gQSB2aWV3IG1hbmFnZXMgcHJvcGVydGllcyBzdWNoIGFzXG4gICAqIGNlbnRlciBhbmQgcmVzb2x1dGlvbi5cbiAgICogQHJldHVybiB7Vmlld30gVGhlIHZpZXcgdGhhdCBjb250cm9scyB0aGlzIG1hcC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0VmlldyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtWaWV3fSAqL1xuICAgICAgdGhpcy5nZXQoTWFwUHJvcGVydHkuVklFVylcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBlbGVtZW50IHRoYXQgc2VydmVzIGFzIHRoZSBtYXAgdmlld3BvcnQuXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBWaWV3cG9ydC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0Vmlld3BvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudmlld3BvcnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBlbGVtZW50IHRoYXQgc2VydmVzIGFzIHRoZSBjb250YWluZXIgZm9yIG92ZXJsYXlzLiAgRWxlbWVudHMgYWRkZWQgdG9cbiAgICogdGhpcyBjb250YWluZXIgd2lsbCBsZXQgbW91c2Vkb3duIGFuZCB0b3VjaHN0YXJ0IGV2ZW50cyB0aHJvdWdoIHRvIHRoZSBtYXAsXG4gICAqIHNvIGNsaWNrcyBhbmQgZ2VzdHVyZXMgb24gYW4gb3ZlcmxheSB3aWxsIHRyaWdnZXIge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fVxuICAgKiBldmVudHMuXG4gICAqIEByZXR1cm4geyFIVE1MRWxlbWVudH0gVGhlIG1hcCdzIG92ZXJsYXkgY29udGFpbmVyLlxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuZ2V0T3ZlcmxheUNvbnRhaW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vdmVybGF5Q29udGFpbmVyXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZWxlbWVudCB0aGF0IHNlcnZlcyBhcyBhIGNvbnRhaW5lciBmb3Igb3ZlcmxheXMgdGhhdCBkb24ndCBhbGxvd1xuICAgKiBldmVudCBwcm9wYWdhdGlvbi4gRWxlbWVudHMgYWRkZWQgdG8gdGhpcyBjb250YWluZXIgd29uJ3QgbGV0IG1vdXNlZG93biBhbmRcbiAgICogdG91Y2hzdGFydCBldmVudHMgdGhyb3VnaCB0byB0aGUgbWFwLCBzbyBjbGlja3MgYW5kIGdlc3R1cmVzIG9uIGFuIG92ZXJsYXlcbiAgICogZG9uJ3QgdHJpZ2dlciBhbnkge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fS5cbiAgICogQHJldHVybiB7IUhUTUxFbGVtZW50fSBUaGUgbWFwJ3Mgb3ZlcmxheSBjb250YWluZXIgdGhhdCBzdG9wcyBldmVudHMuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRPdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXlDb250YWluZXJTdG9wRXZlbnRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7IURvY3VtZW50fSBUaGUgZG9jdW1lbnQgd2hlcmUgdGhlIG1hcCBpcyBkaXNwbGF5ZWQuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRPd25lckRvY3VtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldFRhcmdldEVsZW1lbnQoKSA/IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudCgpLm93bmVyRG9jdW1lbnQgOiBkb2N1bWVudDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRpbGVTb3VyY2VLZXkgVGlsZSBzb3VyY2Uga2V5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSB0aWxlQ2VudGVyIFRpbGUgY2VudGVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdGlsZVJlc29sdXRpb24gVGlsZSByZXNvbHV0aW9uLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRpbGUgcHJpb3JpdHkuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5nZXRUaWxlUHJpb3JpdHkgPSBmdW5jdGlvbiAodGlsZSwgdGlsZVNvdXJjZUtleSwgdGlsZUNlbnRlciwgdGlsZVJlc29sdXRpb24pIHtcbiAgICByZXR1cm4gZ2V0VGlsZVByaW9yaXR5KHRoaXMuZnJhbWVTdGF0ZV8sIHRpbGUsIHRpbGVTb3VyY2VLZXksIHRpbGVDZW50ZXIsIHRpbGVSZXNvbHV0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VUlFdmVudH0gYnJvd3NlckV2ZW50IEJyb3dzZXIgZXZlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X3R5cGUgVHlwZS5cbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZUJyb3dzZXJFdmVudCA9IGZ1bmN0aW9uIChicm93c2VyRXZlbnQsIG9wdF90eXBlKSB7XG4gICAgdmFyIHR5cGUgPSBvcHRfdHlwZSB8fCBicm93c2VyRXZlbnQudHlwZTtcbiAgICB2YXIgbWFwQnJvd3NlckV2ZW50ID0gbmV3IE1hcEJyb3dzZXJFdmVudCh0eXBlLCB0aGlzLCBicm93c2VyRXZlbnQpO1xuICAgIHRoaXMuaGFuZGxlTWFwQnJvd3NlckV2ZW50KG1hcEJyb3dzZXJFdmVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge01hcEJyb3dzZXJFdmVudH0gbWFwQnJvd3NlckV2ZW50IFRoZSBldmVudCB0byBoYW5kbGUuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVNYXBCcm93c2VyRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmZyYW1lU3RhdGVfKSB7XG4gICAgICAvLyBXaXRoIG5vIHZpZXcgZGVmaW5lZCwgd2UgY2Fubm90IHRyYW5zbGF0ZSBwaXhlbHMgaW50byBnZW9ncmFwaGljYWxcbiAgICAgIC8vIGNvb3JkaW5hdGVzIHNvIGludGVyYWN0aW9ucyBjYW5ub3QgYmUgdXNlZC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gICAgLyoqIEB0eXBlIHtQb2ludGVyRXZlbnR9ICovXG4gICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gICAgdmFyIGV2ZW50VHlwZSA9IG9yaWdpbmFsRXZlbnQudHlwZTtcblxuICAgIGlmIChldmVudFR5cGUgPT09IFBvaW50ZXJFdmVudFR5cGUuUE9JTlRFUkRPV04gfHwgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuV0hFRUwgfHwgZXZlbnRUeXBlID09PSBFdmVudFR5cGUuS0VZRE9XTikge1xuICAgICAgdmFyIGRvYyA9IHRoaXMuZ2V0T3duZXJEb2N1bWVudCgpO1xuICAgICAgdmFyIHJvb3ROb2RlID0gdGhpcy52aWV3cG9ydF8uZ2V0Um9vdE5vZGUgPyB0aGlzLnZpZXdwb3J0Xy5nZXRSb290Tm9kZSgpIDogZG9jO1xuICAgICAgdmFyIHRhcmdldCA9ICdob3N0JyBpbiByb290Tm9kZSAvLyBTaGFkb3dSb290XG4gICAgICA/XG4gICAgICAvKiogQHR5cGUge1NoYWRvd1Jvb3R9ICovXG4gICAgICByb290Tm9kZS5lbGVtZW50RnJvbVBvaW50KG9yaWdpbmFsRXZlbnQuY2xpZW50WCwgb3JpZ2luYWxFdmVudC5jbGllbnRZKSA6XG4gICAgICAvKiogQHR5cGUge05vZGV9ICovXG4gICAgICBvcmlnaW5hbEV2ZW50LnRhcmdldDtcblxuICAgICAgaWYgKCAvLyBBYm9ydCBpZiB0aGUgdGFyZ2V0IGlzIGEgY2hpbGQgb2YgdGhlIGNvbnRhaW5lciBmb3IgZWxlbWVudHMgd2hvc2UgZXZlbnRzIGFyZSBub3QgbWVhbnRcbiAgICAgIC8vIHRvIGJlIGhhbmRsZWQgYnkgbWFwIGludGVyYWN0aW9ucy5cbiAgICAgIHRoaXMub3ZlcmxheUNvbnRhaW5lclN0b3BFdmVudF8uY29udGFpbnModGFyZ2V0KSB8fCAvLyBBYm9ydCBpZiB0aGUgZXZlbnQgdGFyZ2V0IGlzIGEgY2hpbGQgb2YgdGhlIGNvbnRhaW5lciB0aGF0IGlzIG5vIGxvbmdlciBpbiB0aGUgcGFnZS5cbiAgICAgIC8vIEl0J3MgcG9zc2libGUgZm9yIHRoZSB0YXJnZXQgdG8gbm8gbG9uZ2VyIGJlIGluIHRoZSBwYWdlIGlmIGl0IGhhcyBiZWVuIHJlbW92ZWQgaW4gYW5cbiAgICAgIC8vIGV2ZW50IGxpc3RlbmVyLCB0aGlzIG1pZ2h0IGhhcHBlbiBpbiBhIENvbnRyb2wgdGhhdCByZWNyZWF0ZXMgaXQncyBjb250ZW50IGJhc2VkIG9uXG4gICAgICAvLyB1c2VyIGludGVyYWN0aW9uIGVpdGhlciBtYW51YWxseSBvciB2aWEgYSByZW5kZXIgaW4gc29tZXRoaW5nIGxpa2UgaHR0cHM6Ly9yZWFjdGpzLm9yZy9cbiAgICAgICEocm9vdE5vZGUgPT09IGRvYyA/IGRvYy5kb2N1bWVudEVsZW1lbnQgOiByb290Tm9kZSkuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgbWFwQnJvd3NlckV2ZW50LmZyYW1lU3RhdGUgPSB0aGlzLmZyYW1lU3RhdGVfO1xuXG4gICAgaWYgKHRoaXMuZGlzcGF0Y2hFdmVudChtYXBCcm93c2VyRXZlbnQpICE9PSBmYWxzZSkge1xuICAgICAgdmFyIGludGVyYWN0aW9uc0FycmF5ID0gdGhpcy5nZXRJbnRlcmFjdGlvbnMoKS5nZXRBcnJheSgpLnNsaWNlKCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSBpbnRlcmFjdGlvbnNBcnJheS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB2YXIgaW50ZXJhY3Rpb24gPSBpbnRlcmFjdGlvbnNBcnJheVtpXTtcblxuICAgICAgICBpZiAoaW50ZXJhY3Rpb24uZ2V0TWFwKCkgIT09IHRoaXMgfHwgIWludGVyYWN0aW9uLmdldEFjdGl2ZSgpIHx8ICF0aGlzLmdldFRhcmdldEVsZW1lbnQoKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvbnQgPSBpbnRlcmFjdGlvbi5oYW5kbGVFdmVudChtYXBCcm93c2VyRXZlbnQpO1xuXG4gICAgICAgIGlmICghY29udCB8fCBtYXBCcm93c2VyRXZlbnQucHJvcGFnYXRpb25TdG9wcGVkKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVQb3N0UmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmcmFtZVN0YXRlID0gdGhpcy5mcmFtZVN0YXRlXzsgLy8gTWFuYWdlIHRoZSB0aWxlIHF1ZXVlXG4gICAgLy8gSW1hZ2UgbG9hZHMgYXJlIGV4cGVuc2l2ZSBhbmQgYSBsaW1pdGVkIHJlc291cmNlLCBzbyB0cnkgdG8gdXNlIHRoZW1cbiAgICAvLyBlZmZpY2llbnRseTpcbiAgICAvLyAqIFdoZW4gdGhlIHZpZXcgaXMgc3RhdGljIHdlIGFsbG93IGEgbGFyZ2UgbnVtYmVyIG9mIHBhcmFsbGVsIHRpbGUgbG9hZHNcbiAgICAvLyAgIHRvIGNvbXBsZXRlIHRoZSBmcmFtZSBhcyBxdWlja2x5IGFzIHBvc3NpYmxlLlxuICAgIC8vICogV2hlbiBhbmltYXRpbmcgb3IgaW50ZXJhY3RpbmcsIGltYWdlIGxvYWRzIGNhbiBjYXVzZSBqYW5rcywgc28gd2UgcmVkdWNlXG4gICAgLy8gICB0aGUgbWF4aW11bSBudW1iZXIgb2YgbG9hZHMgcGVyIGZyYW1lIGFuZCBsaW1pdCB0aGUgbnVtYmVyIG9mIHBhcmFsbGVsXG4gICAgLy8gICB0aWxlIGxvYWRzIHRvIHJlbWFpbiByZWFjdGl2ZSB0byB2aWV3IGNoYW5nZXMgYW5kIHRvIHJlZHVjZSB0aGUgY2hhbmNlIG9mXG4gICAgLy8gICBsb2FkaW5nIHRpbGVzIHRoYXQgd2lsbCBxdWlja2x5IGRpc2FwcGVhciBmcm9tIHZpZXcuXG5cbiAgICB2YXIgdGlsZVF1ZXVlID0gdGhpcy50aWxlUXVldWVfO1xuXG4gICAgaWYgKCF0aWxlUXVldWUuaXNFbXB0eSgpKSB7XG4gICAgICB2YXIgbWF4VG90YWxMb2FkaW5nID0gdGhpcy5tYXhUaWxlc0xvYWRpbmdfO1xuICAgICAgdmFyIG1heE5ld0xvYWRzID0gbWF4VG90YWxMb2FkaW5nO1xuXG4gICAgICBpZiAoZnJhbWVTdGF0ZSkge1xuICAgICAgICB2YXIgaGludHMgPSBmcmFtZVN0YXRlLnZpZXdIaW50cztcblxuICAgICAgICBpZiAoaGludHNbVmlld0hpbnQuQU5JTUFUSU5HXSB8fCBoaW50c1tWaWV3SGludC5JTlRFUkFDVElOR10pIHtcbiAgICAgICAgICB2YXIgbG93T25GcmFtZUJ1ZGdldCA9ICFJTUFHRV9ERUNPREUgJiYgRGF0ZS5ub3coKSAtIGZyYW1lU3RhdGUudGltZSA+IDg7XG4gICAgICAgICAgbWF4VG90YWxMb2FkaW5nID0gbG93T25GcmFtZUJ1ZGdldCA/IDAgOiA4O1xuICAgICAgICAgIG1heE5ld0xvYWRzID0gbG93T25GcmFtZUJ1ZGdldCA/IDAgOiAyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0aWxlUXVldWUuZ2V0VGlsZXNMb2FkaW5nKCkgPCBtYXhUb3RhbExvYWRpbmcpIHtcbiAgICAgICAgdGlsZVF1ZXVlLnJlcHJpb3JpdGl6ZSgpOyAvLyBGSVhNRSBvbmx5IGNhbGwgaWYgdmlldyBoYXMgY2hhbmdlZFxuXG4gICAgICAgIHRpbGVRdWV1ZS5sb2FkTW9yZVRpbGVzKG1heFRvdGFsTG9hZGluZywgbWF4TmV3TG9hZHMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChmcmFtZVN0YXRlICYmIHRoaXMuaGFzTGlzdGVuZXIoUmVuZGVyRXZlbnRUeXBlLlJFTkRFUkNPTVBMRVRFKSAmJiAhZnJhbWVTdGF0ZS5hbmltYXRlICYmICF0aGlzLnRpbGVRdWV1ZV8uZ2V0VGlsZXNMb2FkaW5nKCkgJiYgIXRoaXMuZ2V0TG9hZGluZygpKSB7XG4gICAgICB0aGlzLnJlbmRlcmVyXy5kaXNwYXRjaFJlbmRlckV2ZW50KFJlbmRlckV2ZW50VHlwZS5SRU5ERVJDT01QTEVURSwgZnJhbWVTdGF0ZSk7XG4gICAgfVxuXG4gICAgdmFyIHBvc3RSZW5kZXJGdW5jdGlvbnMgPSB0aGlzLnBvc3RSZW5kZXJGdW5jdGlvbnNfO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcG9zdFJlbmRlckZ1bmN0aW9ucy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBwb3N0UmVuZGVyRnVuY3Rpb25zW2ldKHRoaXMsIGZyYW1lU3RhdGUpO1xuICAgIH1cblxuICAgIHBvc3RSZW5kZXJGdW5jdGlvbnMubGVuZ3RoID0gMDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVTaXplQ2hhbmdlZF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuZ2V0VmlldygpICYmICF0aGlzLmdldFZpZXcoKS5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgdGhpcy5nZXRWaWV3KCkucmVzb2x2ZUNvbnN0cmFpbnRzKDApO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFuZGxlVGFyZ2V0Q2hhbmdlZF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gdGFyZ2V0IG1heSBiZSB1bmRlZmluZWQsIG51bGwsIGEgc3RyaW5nIG9yIGFuIEVsZW1lbnQuXG4gICAgLy8gSWYgaXQncyBhIHN0cmluZyB3ZSBjb252ZXJ0IGl0IHRvIGFuIEVsZW1lbnQgYmVmb3JlIHByb2NlZWRpbmcuXG4gICAgLy8gSWYgaXQncyBub3Qgbm93IGFuIEVsZW1lbnQgd2UgcmVtb3ZlIHRoZSB2aWV3cG9ydCBmcm9tIHRoZSBET00uXG4gICAgLy8gSWYgaXQncyBhbiBFbGVtZW50IHdlIGFwcGVuZCB0aGUgdmlld3BvcnQgZWxlbWVudCB0byBpdC5cbiAgICB2YXIgdGFyZ2V0RWxlbWVudDtcblxuICAgIGlmICh0aGlzLmdldFRhcmdldCgpKSB7XG4gICAgICB0YXJnZXRFbGVtZW50ID0gdGhpcy5nZXRUYXJnZXRFbGVtZW50KCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWFwQnJvd3NlckV2ZW50SGFuZGxlcl8pIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMua2V5SGFuZGxlcktleXNfLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLmtleUhhbmRsZXJLZXlzX1tpXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMua2V5SGFuZGxlcktleXNfID0gbnVsbDtcbiAgICAgIHRoaXMudmlld3BvcnRfLnJlbW92ZUV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNPTlRFWFRNRU5VLCB0aGlzLmJvdW5kSGFuZGxlQnJvd3NlckV2ZW50Xyk7XG4gICAgICB0aGlzLnZpZXdwb3J0Xy5yZW1vdmVFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5XSEVFTCwgdGhpcy5ib3VuZEhhbmRsZUJyb3dzZXJFdmVudF8pO1xuXG4gICAgICBpZiAodGhpcy5oYW5kbGVSZXNpemVfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuUkVTSVpFLCB0aGlzLmhhbmRsZVJlc2l6ZV8sIGZhbHNlKTtcbiAgICAgICAgdGhpcy5oYW5kbGVSZXNpemVfID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm1hcEJyb3dzZXJFdmVudEhhbmRsZXJfLmRpc3Bvc2UoKTtcbiAgICAgIHRoaXMubWFwQnJvd3NlckV2ZW50SGFuZGxlcl8gPSBudWxsO1xuICAgICAgcmVtb3ZlTm9kZSh0aGlzLnZpZXdwb3J0Xyk7XG4gICAgfVxuXG4gICAgaWYgKCF0YXJnZXRFbGVtZW50KSB7XG4gICAgICBpZiAodGhpcy5yZW5kZXJlcl8pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucG9zdFJlbmRlclRpbWVvdXRIYW5kbGVfKTtcbiAgICAgICAgdGhpcy5wb3N0UmVuZGVyVGltZW91dEhhbmRsZV8gPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMucG9zdFJlbmRlckZ1bmN0aW9uc18ubGVuZ3RoID0gMDtcbiAgICAgICAgdGhpcy5yZW5kZXJlcl8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnJlbmRlcmVyXyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFuaW1hdGlvbkRlbGF5S2V5Xykge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkRlbGF5S2V5Xyk7XG4gICAgICAgIHRoaXMuYW5pbWF0aW9uRGVsYXlLZXlfID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXRFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudmlld3BvcnRfKTtcblxuICAgICAgaWYgKCF0aGlzLnJlbmRlcmVyXykge1xuICAgICAgICB0aGlzLnJlbmRlcmVyXyA9IHRoaXMuY3JlYXRlUmVuZGVyZXIoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5tYXBCcm93c2VyRXZlbnRIYW5kbGVyXyA9IG5ldyBNYXBCcm93c2VyRXZlbnRIYW5kbGVyKHRoaXMsIHRoaXMubW92ZVRvbGVyYW5jZV8pO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gTWFwQnJvd3NlckV2ZW50VHlwZSkge1xuICAgICAgICB0aGlzLm1hcEJyb3dzZXJFdmVudEhhbmRsZXJfLmFkZEV2ZW50TGlzdGVuZXIoTWFwQnJvd3NlckV2ZW50VHlwZVtrZXldLCB0aGlzLmhhbmRsZU1hcEJyb3dzZXJFdmVudC5iaW5kKHRoaXMpKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy52aWV3cG9ydF8uYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ09OVEVYVE1FTlUsIHRoaXMuYm91bmRIYW5kbGVCcm93c2VyRXZlbnRfLCBmYWxzZSk7XG4gICAgICB0aGlzLnZpZXdwb3J0Xy5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5XSEVFTCwgdGhpcy5ib3VuZEhhbmRsZUJyb3dzZXJFdmVudF8sIFBBU1NJVkVfRVZFTlRfTElTVEVORVJTID8ge1xuICAgICAgICBwYXNzaXZlOiBmYWxzZVxuICAgICAgfSA6IGZhbHNlKTtcbiAgICAgIHZhciBrZXlib2FyZEV2ZW50VGFyZ2V0ID0gIXRoaXMua2V5Ym9hcmRFdmVudFRhcmdldF8gPyB0YXJnZXRFbGVtZW50IDogdGhpcy5rZXlib2FyZEV2ZW50VGFyZ2V0XztcbiAgICAgIHRoaXMua2V5SGFuZGxlcktleXNfID0gW2xpc3RlbihrZXlib2FyZEV2ZW50VGFyZ2V0LCBFdmVudFR5cGUuS0VZRE9XTiwgdGhpcy5oYW5kbGVCcm93c2VyRXZlbnQsIHRoaXMpLCBsaXN0ZW4oa2V5Ym9hcmRFdmVudFRhcmdldCwgRXZlbnRUeXBlLktFWVBSRVNTLCB0aGlzLmhhbmRsZUJyb3dzZXJFdmVudCwgdGhpcyldO1xuXG4gICAgICBpZiAoIXRoaXMuaGFuZGxlUmVzaXplXykge1xuICAgICAgICB0aGlzLmhhbmRsZVJlc2l6ZV8gPSB0aGlzLnVwZGF0ZVNpemUuYmluZCh0aGlzKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLlJFU0laRSwgdGhpcy5oYW5kbGVSZXNpemVfLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVTaXplKCk7IC8vIHVwZGF0ZVNpemUgY2FsbHMgc2V0U2l6ZSwgc28gbm8gbmVlZCB0byBjYWxsIHRoaXMucmVuZGVyXG4gICAgLy8gb3Vyc2VsdmVzIGhlcmUuXG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuaGFuZGxlVGlsZUNoYW5nZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5oYW5kbGVWaWV3UHJvcGVydHlDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnJlbmRlcigpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZVZpZXdDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy52aWV3UHJvcGVydHlMaXN0ZW5lcktleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy52aWV3UHJvcGVydHlMaXN0ZW5lcktleV8pO1xuICAgICAgdGhpcy52aWV3UHJvcGVydHlMaXN0ZW5lcktleV8gPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZpZXdDaGFuZ2VMaXN0ZW5lcktleV8pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy52aWV3Q2hhbmdlTGlzdGVuZXJLZXlfKTtcbiAgICAgIHRoaXMudmlld0NoYW5nZUxpc3RlbmVyS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIHZpZXcgPSB0aGlzLmdldFZpZXcoKTtcblxuICAgIGlmICh2aWV3KSB7XG4gICAgICB0aGlzLnVwZGF0ZVZpZXdwb3J0U2l6ZV8oKTtcbiAgICAgIHRoaXMudmlld1Byb3BlcnR5TGlzdGVuZXJLZXlfID0gbGlzdGVuKHZpZXcsIE9iamVjdEV2ZW50VHlwZS5QUk9QRVJUWUNIQU5HRSwgdGhpcy5oYW5kbGVWaWV3UHJvcGVydHlDaGFuZ2VkXywgdGhpcyk7XG4gICAgICB0aGlzLnZpZXdDaGFuZ2VMaXN0ZW5lcktleV8gPSBsaXN0ZW4odmlldywgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVWaWV3UHJvcGVydHlDaGFuZ2VkXywgdGhpcyk7XG4gICAgICB2aWV3LnJlc29sdmVDb25zdHJhaW50cygwKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLmhhbmRsZUxheWVyR3JvdXBDaGFuZ2VkXyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5sYXllckdyb3VwUHJvcGVydHlMaXN0ZW5lcktleXNfKSB7XG4gICAgICB0aGlzLmxheWVyR3JvdXBQcm9wZXJ0eUxpc3RlbmVyS2V5c18uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICAgIHRoaXMubGF5ZXJHcm91cFByb3BlcnR5TGlzdGVuZXJLZXlzXyA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGxheWVyR3JvdXAgPSB0aGlzLmdldExheWVyR3JvdXAoKTtcblxuICAgIGlmIChsYXllckdyb3VwKSB7XG4gICAgICB0aGlzLmxheWVyR3JvdXBQcm9wZXJ0eUxpc3RlbmVyS2V5c18gPSBbbGlzdGVuKGxheWVyR3JvdXAsIE9iamVjdEV2ZW50VHlwZS5QUk9QRVJUWUNIQU5HRSwgdGhpcy5yZW5kZXIsIHRoaXMpLCBsaXN0ZW4obGF5ZXJHcm91cCwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5yZW5kZXIsIHRoaXMpXTtcbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcigpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5pc1JlbmRlcmVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhIXRoaXMuZnJhbWVTdGF0ZV87XG4gIH07XG4gIC8qKlxuICAgKiBSZXF1ZXN0cyBhbiBpbW1lZGlhdGUgcmVuZGVyIGluIGEgc3luY2hyb25vdXMgbWFubmVyLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW5kZXJTeW5jID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmFuaW1hdGlvbkRlbGF5S2V5Xykge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRpb25EZWxheUtleV8pO1xuICAgIH1cblxuICAgIHRoaXMuYW5pbWF0aW9uRGVsYXlfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWRyYXdzIGFsbCB0ZXh0IGFmdGVyIG5ldyBmb250cyBoYXZlIGxvYWRlZFxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUucmVkcmF3VGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5ZXJTdGF0ZXMgPSB0aGlzLmdldExheWVyR3JvdXAoKS5nZXRMYXllclN0YXRlc0FycmF5KCk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllclN0YXRlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgbGF5ZXIgPSBsYXllclN0YXRlc1tpXS5sYXllcjtcblxuICAgICAgaWYgKGxheWVyLmhhc1JlbmRlcmVyKCkpIHtcbiAgICAgICAgbGF5ZXIuZ2V0UmVuZGVyZXIoKS5oYW5kbGVGb250c0NoYW5nZWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZXF1ZXN0IGEgbWFwIHJlbmRlcmluZyAoYXQgdGhlIG5leHQgYW5pbWF0aW9uIGZyYW1lKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnJlbmRlcmVyXyAmJiB0aGlzLmFuaW1hdGlvbkRlbGF5S2V5XyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmFuaW1hdGlvbkRlbGF5S2V5XyA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkRlbGF5Xyk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIHRoZSBnaXZlbiBjb250cm9sIGZyb20gdGhlIG1hcC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0fSBjb250cm9sIENvbnRyb2wuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29udHJvbC9Db250cm9sLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBUaGUgcmVtb3ZlZCBjb250cm9sIChvciB1bmRlZmluZWRcbiAgICogICAgIGlmIHRoZSBjb250cm9sIHdhcyBub3QgZm91bmQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW1vdmVDb250cm9sID0gZnVuY3Rpb24gKGNvbnRyb2wpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb250cm9scygpLnJlbW92ZShjb250cm9sKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZ2l2ZW4gaW50ZXJhY3Rpb24gZnJvbSB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdH0gaW50ZXJhY3Rpb24gSW50ZXJhY3Rpb24gdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBUaGUgcmVtb3ZlZCBpbnRlcmFjdGlvbiAob3JcbiAgICogICAgIHVuZGVmaW5lZCBpZiB0aGUgaW50ZXJhY3Rpb24gd2FzIG5vdCBmb3VuZCkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnJlbW92ZUludGVyYWN0aW9uID0gZnVuY3Rpb24gKGludGVyYWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW50ZXJhY3Rpb25zKCkucmVtb3ZlKGludGVyYWN0aW9uKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdpdmVuIGxheWVyIGZyb20gdGhlIG1hcC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2xheWVyL0Jhc2UuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vbGF5ZXIvQmFzZS5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH0gVGhlIHJlbW92ZWQgbGF5ZXIgKG9yIHVuZGVmaW5lZCBpZiB0aGVcbiAgICogICAgIGxheWVyIHdhcyBub3QgZm91bmQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5yZW1vdmVMYXllciA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgIHZhciBsYXllcnMgPSB0aGlzLmdldExheWVyR3JvdXAoKS5nZXRMYXllcnMoKTtcbiAgICByZXR1cm4gbGF5ZXJzLnJlbW92ZShsYXllcik7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGdpdmVuIG92ZXJsYXkgZnJvbSB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0fSBvdmVybGF5IE92ZXJsYXkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vT3ZlcmxheS5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH0gVGhlIHJlbW92ZWQgb3ZlcmxheSAob3IgdW5kZWZpbmVkXG4gICAqICAgICBpZiB0aGUgb3ZlcmxheSB3YXMgbm90IGZvdW5kKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUucmVtb3ZlT3ZlcmxheSA9IGZ1bmN0aW9uIChvdmVybGF5KSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T3ZlcmxheXMoKS5yZW1vdmUob3ZlcmxheSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdGltZSBUaW1lLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUucmVuZGVyRnJhbWVfID0gZnVuY3Rpb24gKHRpbWUpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIHNpemUgPSB0aGlzLmdldFNpemUoKTtcbiAgICB2YXIgdmlldyA9IHRoaXMuZ2V0VmlldygpO1xuICAgIHZhciBwcmV2aW91c0ZyYW1lU3RhdGUgPSB0aGlzLmZyYW1lU3RhdGVfO1xuICAgIC8qKiBAdHlwZSB7P0ZyYW1lU3RhdGV9ICovXG5cbiAgICB2YXIgZnJhbWVTdGF0ZSA9IG51bGw7XG5cbiAgICBpZiAoc2l6ZSAhPT0gdW5kZWZpbmVkICYmIGhhc0FyZWEoc2l6ZSkgJiYgdmlldyAmJiB2aWV3LmlzRGVmKCkpIHtcbiAgICAgIHZhciB2aWV3SGludHMgPSB2aWV3LmdldEhpbnRzKHRoaXMuZnJhbWVTdGF0ZV8gPyB0aGlzLmZyYW1lU3RhdGVfLnZpZXdIaW50cyA6IHVuZGVmaW5lZCk7XG4gICAgICB2YXIgdmlld1N0YXRlID0gdmlldy5nZXRTdGF0ZSgpO1xuICAgICAgZnJhbWVTdGF0ZSA9IHtcbiAgICAgICAgYW5pbWF0ZTogZmFsc2UsXG4gICAgICAgIGNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtOiB0aGlzLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtXyxcbiAgICAgICAgZGVjbHV0dGVyVHJlZTogbnVsbCxcbiAgICAgICAgZXh0ZW50OiBnZXRGb3JWaWV3QW5kU2l6ZSh2aWV3U3RhdGUuY2VudGVyLCB2aWV3U3RhdGUucmVzb2x1dGlvbiwgdmlld1N0YXRlLnJvdGF0aW9uLCBzaXplKSxcbiAgICAgICAgaW5kZXg6IHRoaXMuZnJhbWVJbmRleF8rKyxcbiAgICAgICAgbGF5ZXJJbmRleDogMCxcbiAgICAgICAgbGF5ZXJTdGF0ZXNBcnJheTogdGhpcy5nZXRMYXllckdyb3VwKCkuZ2V0TGF5ZXJTdGF0ZXNBcnJheSgpLFxuICAgICAgICBwaXhlbFJhdGlvOiB0aGlzLnBpeGVsUmF0aW9fLFxuICAgICAgICBwaXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybTogdGhpcy5waXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybV8sXG4gICAgICAgIHBvc3RSZW5kZXJGdW5jdGlvbnM6IFtdLFxuICAgICAgICBzaXplOiBzaXplLFxuICAgICAgICB0aWxlUXVldWU6IHRoaXMudGlsZVF1ZXVlXyxcbiAgICAgICAgdGltZTogdGltZSxcbiAgICAgICAgdXNlZFRpbGVzOiB7fSxcbiAgICAgICAgdmlld1N0YXRlOiB2aWV3U3RhdGUsXG4gICAgICAgIHZpZXdIaW50czogdmlld0hpbnRzLFxuICAgICAgICB3YW50ZWRUaWxlczoge31cbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5mcmFtZVN0YXRlXyA9IGZyYW1lU3RhdGU7XG4gICAgdGhpcy5yZW5kZXJlcl8ucmVuZGVyRnJhbWUoZnJhbWVTdGF0ZSk7XG5cbiAgICBpZiAoZnJhbWVTdGF0ZSkge1xuICAgICAgaWYgKGZyYW1lU3RhdGUuYW5pbWF0ZSkge1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfVxuXG4gICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLnBvc3RSZW5kZXJGdW5jdGlvbnNfLCBmcmFtZVN0YXRlLnBvc3RSZW5kZXJGdW5jdGlvbnMpO1xuXG4gICAgICBpZiAocHJldmlvdXNGcmFtZVN0YXRlKSB7XG4gICAgICAgIHZhciBtb3ZlU3RhcnQgPSAhdGhpcy5wcmV2aW91c0V4dGVudF8gfHwgIWlzRW1wdHkodGhpcy5wcmV2aW91c0V4dGVudF8pICYmICFlcXVhbHMoZnJhbWVTdGF0ZS5leHRlbnQsIHRoaXMucHJldmlvdXNFeHRlbnRfKTtcblxuICAgICAgICBpZiAobW92ZVN0YXJ0KSB7XG4gICAgICAgICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBNYXBFdmVudChNYXBFdmVudFR5cGUuTU9WRVNUQVJULCB0aGlzLCBwcmV2aW91c0ZyYW1lU3RhdGUpKTtcbiAgICAgICAgICB0aGlzLnByZXZpb3VzRXh0ZW50XyA9IGNyZWF0ZU9yVXBkYXRlRW1wdHkodGhpcy5wcmV2aW91c0V4dGVudF8pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBpZGxlID0gdGhpcy5wcmV2aW91c0V4dGVudF8gJiYgIWZyYW1lU3RhdGUudmlld0hpbnRzW1ZpZXdIaW50LkFOSU1BVElOR10gJiYgIWZyYW1lU3RhdGUudmlld0hpbnRzW1ZpZXdIaW50LklOVEVSQUNUSU5HXSAmJiAhZXF1YWxzKGZyYW1lU3RhdGUuZXh0ZW50LCB0aGlzLnByZXZpb3VzRXh0ZW50Xyk7XG5cbiAgICAgIGlmIChpZGxlKSB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgTWFwRXZlbnQoTWFwRXZlbnRUeXBlLk1PVkVFTkQsIHRoaXMsIGZyYW1lU3RhdGUpKTtcbiAgICAgICAgY2xvbmUoZnJhbWVTdGF0ZS5leHRlbnQsIHRoaXMucHJldmlvdXNFeHRlbnRfKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IE1hcEV2ZW50KE1hcEV2ZW50VHlwZS5QT1NUUkVOREVSLCB0aGlzLCBmcmFtZVN0YXRlKSk7XG5cbiAgICBpZiAoIXRoaXMucG9zdFJlbmRlclRpbWVvdXRIYW5kbGVfKSB7XG4gICAgICB0aGlzLnBvc3RSZW5kZXJUaW1lb3V0SGFuZGxlXyA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBfdGhpcy5wb3N0UmVuZGVyVGltZW91dEhhbmRsZV8gPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgX3RoaXMuaGFuZGxlUG9zdFJlbmRlcigpO1xuICAgICAgfSwgMCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0cyB0aGUgbGF5ZXJncm91cCBvZiB0aGlzIG1hcC5cbiAgICogQHBhcmFtIHtMYXllckdyb3VwfSBsYXllckdyb3VwIEEgbGF5ZXIgZ3JvdXAgY29udGFpbmluZyB0aGUgbGF5ZXJzIGluIHRoaXMgbWFwLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5zZXRMYXllckdyb3VwID0gZnVuY3Rpb24gKGxheWVyR3JvdXApIHtcbiAgICB0aGlzLnNldChNYXBQcm9wZXJ0eS5MQVlFUkdST1VQLCBsYXllckdyb3VwKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgc2l6ZSBvZiB0aGlzIG1hcC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZXx1bmRlZmluZWR9IHNpemUgVGhlIHNpemUgaW4gcGl4ZWxzIG9mIHRoZSBtYXAgaW4gdGhlIERPTS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBsdWdnYWJsZU1hcC5wcm90b3R5cGUuc2V0U2l6ZSA9IGZ1bmN0aW9uIChzaXplKSB7XG4gICAgdGhpcy5zZXQoTWFwUHJvcGVydHkuU0laRSwgc2l6ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHRhcmdldCBlbGVtZW50IHRvIHJlbmRlciB0aGlzIG1hcCBpbnRvLlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHN0cmluZ3x1bmRlZmluZWR9IHRhcmdldCBUaGUgRWxlbWVudCBvciBpZCBvZiB0aGUgRWxlbWVudFxuICAgKiAgICAgdGhhdCB0aGUgbWFwIGlzIHJlbmRlcmVkIGluLlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS5zZXRUYXJnZXQgPSBmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgdGhpcy5zZXQoTWFwUHJvcGVydHkuVEFSR0VULCB0YXJnZXQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB2aWV3IGZvciB0aGlzIG1hcC5cbiAgICogQHBhcmFtIHtWaWV3fSB2aWV3IFRoZSB2aWV3IHRoYXQgY29udHJvbHMgdGhpcyBtYXAuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnNldFZpZXcgPSBmdW5jdGlvbiAodmlldykge1xuICAgIHRoaXMuc2V0KE1hcFByb3BlcnR5LlZJRVcsIHZpZXcpO1xuICB9O1xuICAvKipcbiAgICogRm9yY2UgYSByZWNhbGN1bGF0aW9uIG9mIHRoZSBtYXAgdmlld3BvcnQgc2l6ZS4gIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCB3aGVuXG4gICAqIHRoaXJkLXBhcnR5IGNvZGUgY2hhbmdlcyB0aGUgc2l6ZSBvZiB0aGUgbWFwIHZpZXdwb3J0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUGx1Z2dhYmxlTWFwLnByb3RvdHlwZS51cGRhdGVTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0YXJnZXRFbGVtZW50ID0gdGhpcy5nZXRUYXJnZXRFbGVtZW50KCk7XG5cbiAgICBpZiAoIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuc2V0U2l6ZSh1bmRlZmluZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY29tcHV0ZWRTdHlsZSA9IGdldENvbXB1dGVkU3R5bGUodGFyZ2V0RWxlbWVudCk7XG4gICAgICB0aGlzLnNldFNpemUoW3RhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGggLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ2JvcmRlckxlZnRXaWR0aCddKSAtIHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZVsncGFkZGluZ0xlZnQnXSkgLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ3BhZGRpbmdSaWdodCddKSAtIHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZVsnYm9yZGVyUmlnaHRXaWR0aCddKSwgdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQgLSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGVbJ2JvcmRlclRvcFdpZHRoJ10pIC0gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlWydwYWRkaW5nVG9wJ10pIC0gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlWydwYWRkaW5nQm90dG9tJ10pIC0gcGFyc2VGbG9hdChjb21wdXRlZFN0eWxlWydib3JkZXJCb3R0b21XaWR0aCddKV0pO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlVmlld3BvcnRTaXplXygpO1xuICB9O1xuICAvKipcbiAgICogUmVjb21wdXRlcyB0aGUgdmlld3BvcnQgc2l6ZSBhbmQgc2F2ZSBpdCBvbiB0aGUgdmlldyBvYmplY3QgKGlmIGFueSlcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQbHVnZ2FibGVNYXAucHJvdG90eXBlLnVwZGF0ZVZpZXdwb3J0U2l6ZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZpZXcgPSB0aGlzLmdldFZpZXcoKTtcblxuICAgIGlmICh2aWV3KSB7XG4gICAgICB2YXIgc2l6ZSA9IHVuZGVmaW5lZDtcbiAgICAgIHZhciBjb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLnZpZXdwb3J0Xyk7XG5cbiAgICAgIGlmIChjb21wdXRlZFN0eWxlLndpZHRoICYmIGNvbXB1dGVkU3R5bGUuaGVpZ2h0KSB7XG4gICAgICAgIHNpemUgPSBbcGFyc2VJbnQoY29tcHV0ZWRTdHlsZS53aWR0aCwgMTApLCBwYXJzZUludChjb21wdXRlZFN0eWxlLmhlaWdodCwgMTApXTtcbiAgICAgIH1cblxuICAgICAgdmlldy5zZXRWaWV3cG9ydFNpemUoc2l6ZSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBQbHVnZ2FibGVNYXA7XG59KEJhc2VPYmplY3QpO1xuLyoqXG4gKiBAcGFyYW0ge01hcE9wdGlvbnN9IG9wdGlvbnMgTWFwIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtNYXBPcHRpb25zSW50ZXJuYWx9IEludGVybmFsIG1hcCBvcHRpb25zLlxuICovXG5cblxuZnVuY3Rpb24gY3JlYXRlT3B0aW9uc0ludGVybmFsKG9wdGlvbnMpIHtcbiAgLyoqXG4gICAqIEB0eXBlIHtIVE1MRWxlbWVudHxEb2N1bWVudH1cbiAgICovXG4gIHZhciBrZXlib2FyZEV2ZW50VGFyZ2V0ID0gbnVsbDtcblxuICBpZiAob3B0aW9ucy5rZXlib2FyZEV2ZW50VGFyZ2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBrZXlib2FyZEV2ZW50VGFyZ2V0ID0gdHlwZW9mIG9wdGlvbnMua2V5Ym9hcmRFdmVudFRhcmdldCA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChvcHRpb25zLmtleWJvYXJkRXZlbnRUYXJnZXQpIDogb3B0aW9ucy5rZXlib2FyZEV2ZW50VGFyZ2V0O1xuICB9XG4gIC8qKlxuICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgKj59XG4gICAqL1xuXG5cbiAgdmFyIHZhbHVlcyA9IHt9O1xuICB2YXIgbGF5ZXJHcm91cCA9IG9wdGlvbnMubGF5ZXJzICYmIHR5cGVvZlxuICAvKiogQHR5cGUgez99ICovXG4gIG9wdGlvbnMubGF5ZXJzLmdldExheWVycyA9PT0gJ2Z1bmN0aW9uJyA/XG4gIC8qKiBAdHlwZSB7TGF5ZXJHcm91cH0gKi9cbiAgb3B0aW9ucy5sYXllcnMgOiBuZXcgTGF5ZXJHcm91cCh7XG4gICAgbGF5ZXJzOlxuICAgIC8qKiBAdHlwZSB7Q29sbGVjdGlvbn0gKi9cbiAgICBvcHRpb25zLmxheWVyc1xuICB9KTtcbiAgdmFsdWVzW01hcFByb3BlcnR5LkxBWUVSR1JPVVBdID0gbGF5ZXJHcm91cDtcbiAgdmFsdWVzW01hcFByb3BlcnR5LlRBUkdFVF0gPSBvcHRpb25zLnRhcmdldDtcbiAgdmFsdWVzW01hcFByb3BlcnR5LlZJRVddID0gb3B0aW9ucy52aWV3ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnZpZXcgOiBuZXcgVmlldygpO1xuICB2YXIgY29udHJvbHM7XG5cbiAgaWYgKG9wdGlvbnMuY29udHJvbHMgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuY29udHJvbHMpKSB7XG4gICAgICBjb250cm9scyA9IG5ldyBDb2xsZWN0aW9uKG9wdGlvbnMuY29udHJvbHMuc2xpY2UoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydCh0eXBlb2ZcbiAgICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICAgIG9wdGlvbnMuY29udHJvbHMuZ2V0QXJyYXkgPT09ICdmdW5jdGlvbicsIDQ3KTsgLy8gRXhwZWN0ZWQgYGNvbnRyb2xzYCB0byBiZSBhbiBhcnJheSBvciBhbiBgaW1wb3J0KFwiLi9Db2xsZWN0aW9uLmpzXCIpLkNvbGxlY3Rpb25gXG5cbiAgICAgIGNvbnRyb2xzID1cbiAgICAgIC8qKiBAdHlwZSB7Q29sbGVjdGlvbn0gKi9cbiAgICAgIG9wdGlvbnMuY29udHJvbHM7XG4gICAgfVxuICB9XG5cbiAgdmFyIGludGVyYWN0aW9ucztcblxuICBpZiAob3B0aW9ucy5pbnRlcmFjdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuaW50ZXJhY3Rpb25zKSkge1xuICAgICAgaW50ZXJhY3Rpb25zID0gbmV3IENvbGxlY3Rpb24ob3B0aW9ucy5pbnRlcmFjdGlvbnMuc2xpY2UoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydCh0eXBlb2ZcbiAgICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICAgIG9wdGlvbnMuaW50ZXJhY3Rpb25zLmdldEFycmF5ID09PSAnZnVuY3Rpb24nLCA0OCk7IC8vIEV4cGVjdGVkIGBpbnRlcmFjdGlvbnNgIHRvIGJlIGFuIGFycmF5IG9yIGFuIGBpbXBvcnQoXCIuL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbmBcblxuICAgICAgaW50ZXJhY3Rpb25zID1cbiAgICAgIC8qKiBAdHlwZSB7Q29sbGVjdGlvbn0gKi9cbiAgICAgIG9wdGlvbnMuaW50ZXJhY3Rpb25zO1xuICAgIH1cbiAgfVxuXG4gIHZhciBvdmVybGF5cztcblxuICBpZiAob3B0aW9ucy5vdmVybGF5cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5vdmVybGF5cykpIHtcbiAgICAgIG92ZXJsYXlzID0gbmV3IENvbGxlY3Rpb24ob3B0aW9ucy5vdmVybGF5cy5zbGljZSgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0KHR5cGVvZlxuICAgICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgICAgb3B0aW9ucy5vdmVybGF5cy5nZXRBcnJheSA9PT0gJ2Z1bmN0aW9uJywgNDkpOyAvLyBFeHBlY3RlZCBgb3ZlcmxheXNgIHRvIGJlIGFuIGFycmF5IG9yIGFuIGBpbXBvcnQoXCIuL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbmBcblxuICAgICAgb3ZlcmxheXMgPSBvcHRpb25zLm92ZXJsYXlzO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBvdmVybGF5cyA9IG5ldyBDb2xsZWN0aW9uKCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbnRyb2xzOiBjb250cm9scyxcbiAgICBpbnRlcmFjdGlvbnM6IGludGVyYWN0aW9ucyxcbiAgICBrZXlib2FyZEV2ZW50VGFyZ2V0OiBrZXlib2FyZEV2ZW50VGFyZ2V0LFxuICAgIG92ZXJsYXlzOiBvdmVybGF5cyxcbiAgICB2YWx1ZXM6IHZhbHVlc1xuICB9O1xufVxuXG5leHBvcnQgZGVmYXVsdCBQbHVnZ2FibGVNYXA7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9jb250cm9sL0NvbnRyb2xcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgTWFwRXZlbnRUeXBlIGZyb20gJy4uL01hcEV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBWT0lEIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4uL2V2ZW50cy5qcyc7XG5pbXBvcnQgeyByZW1vdmVOb2RlIH0gZnJvbSAnLi4vZG9tLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gW2VsZW1lbnRdIFRoZSBlbGVtZW50IGlzIHRoZSBjb250cm9sJ3NcbiAqIGNvbnRhaW5lciBlbGVtZW50LiBUaGlzIG9ubHkgbmVlZHMgdG8gYmUgc3BlY2lmaWVkIGlmIHlvdSdyZSBkZXZlbG9waW5nXG4gKiBhIGN1c3RvbSBjb250cm9sLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbihpbXBvcnQoXCIuLi9NYXBFdmVudC5qc1wiKS5kZWZhdWx0KTp2b2lkfSBbcmVuZGVyXSBGdW5jdGlvbiBjYWxsZWQgd2hlblxuICogdGhlIGNvbnRyb2wgc2hvdWxkIGJlIHJlLXJlbmRlcmVkLiBUaGlzIGlzIGNhbGxlZCBpbiBhIGByZXF1ZXN0QW5pbWF0aW9uRnJhbWVgXG4gKiBjYWxsYmFjay5cbiAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR8c3RyaW5nfSBbdGFyZ2V0XSBTcGVjaWZ5IGEgdGFyZ2V0IGlmIHlvdSB3YW50XG4gKiB0aGUgY29udHJvbCB0byBiZSByZW5kZXJlZCBvdXRzaWRlIG9mIHRoZSBtYXAncyB2aWV3cG9ydC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgY29udHJvbCBpcyBhIHZpc2libGUgd2lkZ2V0IHdpdGggYSBET00gZWxlbWVudCBpbiBhIGZpeGVkIHBvc2l0aW9uIG9uIHRoZVxuICogc2NyZWVuLiBUaGV5IGNhbiBpbnZvbHZlIHVzZXIgaW5wdXQgKGJ1dHRvbnMpLCBvciBiZSBpbmZvcm1hdGlvbmFsIG9ubHk7XG4gKiB0aGUgcG9zaXRpb24gaXMgZGV0ZXJtaW5lZCB1c2luZyBDU1MuIEJ5IGRlZmF1bHQgdGhlc2UgYXJlIHBsYWNlZCBpbiB0aGVcbiAqIGNvbnRhaW5lciB3aXRoIENTUyBjbGFzcyBuYW1lIGBvbC1vdmVybGF5Y29udGFpbmVyLXN0b3BldmVudGAsIGJ1dCBjYW4gdXNlXG4gKiBhbnkgb3V0c2lkZSBET00gZWxlbWVudC5cbiAqXG4gKiBUaGlzIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBjb250cm9scy4gWW91IGNhbiB1c2UgaXQgZm9yIHNpbXBsZSBjdXN0b21cbiAqIGNvbnRyb2xzIGJ5IGNyZWF0aW5nIHRoZSBlbGVtZW50IHdpdGggbGlzdGVuZXJzLCBjcmVhdGluZyBhbiBpbnN0YW5jZTpcbiAqIGBgYGpzXG4gKiB2YXIgbXlDb250cm9sID0gbmV3IENvbnRyb2woe2VsZW1lbnQ6IG15RWxlbWVudH0pO1xuICogYGBgXG4gKiBhbmQgdGhlbiBhZGRpbmcgdGhpcyB0byB0aGUgbWFwLlxuICpcbiAqIFRoZSBtYWluIGFkdmFudGFnZSBvZiBoYXZpbmcgdGhpcyBhcyBhIGNvbnRyb2wgcmF0aGVyIHRoYW4gYSBzaW1wbGUgc2VwYXJhdGVcbiAqIERPTSBlbGVtZW50IGlzIHRoYXQgcHJldmVudGluZyBwcm9wYWdhdGlvbiBpcyBoYW5kbGVkIGZvciB5b3UuIENvbnRyb2xzXG4gKiB3aWxsIGFsc28gYmUgb2JqZWN0cyBpbiBhIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufSwgc28geW91IGNhbiB1c2UgdGhlaXIgbWV0aG9kcy5cbiAqXG4gKiBZb3UgY2FuIGFsc28gZXh0ZW5kIHRoaXMgYmFzZSBmb3IgeW91ciBvd24gY29udHJvbCBjbGFzcy4gU2VlXG4gKiBleGFtcGxlcy9jdXN0b20tY29udHJvbHMgZm9yIGFuIGV4YW1wbGUgb2YgaG93IHRvIGRvIHRoaXMuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBDb250cm9sID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENvbnRyb2wsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgQ29udHJvbCBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENvbnRyb2wob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgZWxlbWVudCA9IG9wdGlvbnMuZWxlbWVudDtcblxuICAgIGlmIChlbGVtZW50ICYmICFvcHRpb25zLnRhcmdldCAmJiAhZWxlbWVudC5zdHlsZS5wb2ludGVyRXZlbnRzKSB7XG4gICAgICBlbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnYXV0byc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmVsZW1lbnQgPSBlbGVtZW50ID8gZWxlbWVudCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy50YXJnZXRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLm1hcF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7IUFycmF5PGltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fVxuICAgICAqL1xuXG4gICAgX3RoaXMubGlzdGVuZXJLZXlzID0gW107XG5cbiAgICBpZiAob3B0aW9ucy5yZW5kZXIpIHtcbiAgICAgIF90aGlzLnJlbmRlciA9IG9wdGlvbnMucmVuZGVyO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnRhcmdldCkge1xuICAgICAgX3RoaXMuc2V0VGFyZ2V0KG9wdGlvbnMudGFyZ2V0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIENvbnRyb2wucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZW1vdmVOb2RlKHRoaXMuZWxlbWVudCk7XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udHJvbC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IE1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbnRyb2wucHJvdG90eXBlLmdldE1hcCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXBfO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIHRoZSBjb250cm9sIGZyb20gaXRzIGN1cnJlbnQgbWFwIGFuZCBhdHRhY2ggaXQgdG8gdGhlIG5ldyBtYXAuXG4gICAqIFN1YmNsYXNzZXMgbWF5IHNldCB1cCBldmVudCBoYW5kbGVycyB0byBnZXQgbm90aWZpZWQgYWJvdXQgY2hhbmdlcyB0b1xuICAgKiB0aGUgbWFwIGhlcmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDb250cm9sLnByb3RvdHlwZS5zZXRNYXAgPSBmdW5jdGlvbiAobWFwKSB7XG4gICAgaWYgKHRoaXMubWFwXykge1xuICAgICAgcmVtb3ZlTm9kZSh0aGlzLmVsZW1lbnQpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMubGlzdGVuZXJLZXlzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy5saXN0ZW5lcktleXNbaV0pO1xuICAgIH1cblxuICAgIHRoaXMubGlzdGVuZXJLZXlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5tYXBfID0gbWFwO1xuXG4gICAgaWYgKHRoaXMubWFwXykge1xuICAgICAgdmFyIHRhcmdldCA9IHRoaXMudGFyZ2V0XyA/IHRoaXMudGFyZ2V0XyA6IG1hcC5nZXRPdmVybGF5Q29udGFpbmVyU3RvcEV2ZW50KCk7XG4gICAgICB0YXJnZXQuYXBwZW5kQ2hpbGQodGhpcy5lbGVtZW50KTtcblxuICAgICAgaWYgKHRoaXMucmVuZGVyICE9PSBWT0lEKSB7XG4gICAgICAgIHRoaXMubGlzdGVuZXJLZXlzLnB1c2gobGlzdGVuKG1hcCwgTWFwRXZlbnRUeXBlLlBPU1RSRU5ERVIsIHRoaXMucmVuZGVyLCB0aGlzKSk7XG4gICAgICB9XG5cbiAgICAgIG1hcC5yZW5kZXIoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXJzIHRoZSBjb250cm9sLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEV2ZW50IE1hcCBldmVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENvbnRyb2wucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIChtYXBFdmVudCkge307XG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gc2V0IGEgdGFyZ2V0IGVsZW1lbnQgZm9yIHRoZSBjb250cm9sLiBJdCBoYXMgbm9cbiAgICogZWZmZWN0IGlmIGl0IGlzIGNhbGxlZCBhZnRlciB0aGUgY29udHJvbCBoYXMgYmVlbiBhZGRlZCB0byB0aGUgbWFwIChpLmUuXG4gICAqIGFmdGVyIGBzZXRNYXBgIGlzIGNhbGxlZCBvbiB0aGUgY29udHJvbCkuIElmIG5vIGB0YXJnZXRgIGlzIHNldCBpbiB0aGVcbiAgICogb3B0aW9ucyBwYXNzZWQgdG8gdGhlIGNvbnRyb2wgY29uc3RydWN0b3IgYW5kIGlmIGBzZXRUYXJnZXRgIGlzIG5vdCBjYWxsZWRcbiAgICogdGhlbiB0aGUgY29udHJvbCBpcyBhZGRlZCB0byB0aGUgbWFwJ3Mgb3ZlcmxheSBjb250YWluZXIuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8c3RyaW5nfSB0YXJnZXQgVGFyZ2V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ29udHJvbC5wcm90b3R5cGUuc2V0VGFyZ2V0ID0gZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIHRoaXMudGFyZ2V0XyA9IHR5cGVvZiB0YXJnZXQgPT09ICdzdHJpbmcnID8gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0KSA6IHRhcmdldDtcbiAgfTtcblxuICByZXR1cm4gQ29udHJvbDtcbn0oQmFzZU9iamVjdCk7XG5cbmV4cG9ydCBkZWZhdWx0IENvbnRyb2w7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9jb250cm9sL0F0dHJpYnV0aW9uXG4gKi9cblxuXG5pbXBvcnQgQ29udHJvbCBmcm9tICcuL0NvbnRyb2wuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IENMQVNTX0NPTExBUFNFRCwgQ0xBU1NfQ09OVFJPTCwgQ0xBU1NfVU5TRUxFQ1RBQkxFIH0gZnJvbSAnLi4vY3NzLmpzJztcbmltcG9ydCB7IGVxdWFscyB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGluVmlldyB9IGZyb20gJy4uL2xheWVyL0xheWVyLmpzJztcbmltcG9ydCB7IHJlbW92ZUNoaWxkcmVuLCByZXBsYWNlTm9kZSB9IGZyb20gJy4uL2RvbS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY2xhc3NOYW1lPSdvbC1hdHRyaWJ1dGlvbiddIENTUyBjbGFzcyBuYW1lLlxuICogQHByb3BlcnR5IHtIVE1MRWxlbWVudHxzdHJpbmd9IFt0YXJnZXRdIFNwZWNpZnkgYSB0YXJnZXQgaWYgeW91XG4gKiB3YW50IHRoZSBjb250cm9sIHRvIGJlIHJlbmRlcmVkIG91dHNpZGUgb2YgdGhlIG1hcCdzXG4gKiB2aWV3cG9ydC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2NvbGxhcHNpYmxlXSBTcGVjaWZ5IGlmIGF0dHJpYnV0aW9ucyBjYW5cbiAqIGJlIGNvbGxhcHNlZC4gSWYgbm90IHNwZWNpZmllZCwgc291cmNlcyBjb250cm9sIHRoaXMgYmVoYXZpb3Igd2l0aCB0aGVpclxuICogYGF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlYCBzZXR0aW5nLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbY29sbGFwc2VkPXRydWVdIFNwZWNpZnkgaWYgYXR0cmlidXRpb25zIHNob3VsZFxuICogYmUgY29sbGFwc2VkIGF0IHN0YXJ0dXAuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3RpcExhYmVsPSdBdHRyaWJ1dGlvbnMnXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIGJ1dHRvbiB0aXAuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2xhYmVsPSdpJ10gVGV4dCBsYWJlbCB0byB1c2UgZm9yIHRoZVxuICogY29sbGFwc2VkIGF0dHJpYnV0aW9ucyBidXR0b24uXG4gKiBJbnN0ZWFkIG9mIHRleHQsIGFsc28gYW4gZWxlbWVudCAoZS5nLiBhIGBzcGFuYCBlbGVtZW50KSBjYW4gYmUgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZXhwYW5kQ2xhc3NOYW1lPWNsYXNzTmFtZSArICctZXhwYW5kJ10gQ1NTIGNsYXNzIG5hbWUgZm9yIHRoZVxuICogY29sbGFwc2VkIGF0dHJpYnV0aW9ucyBidXR0b24uXG4gKiBAcHJvcGVydHkge3N0cmluZ3xIVE1MRWxlbWVudH0gW2NvbGxhcHNlTGFiZWw9J8K7J10gVGV4dCBsYWJlbCB0byB1c2VcbiAqIGZvciB0aGUgZXhwYW5kZWQgYXR0cmlidXRpb25zIGJ1dHRvbi5cbiAqIEluc3RlYWQgb2YgdGV4dCwgYWxzbyBhbiBlbGVtZW50IChlLmcuIGEgYHNwYW5gIGVsZW1lbnQpIGNhbiBiZSB1c2VkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb2xsYXBzZUNsYXNzTmFtZT1jbGFzc05hbWUgKyAnLWNvbGxhcHNlJ10gQ1NTIGNsYXNzIG5hbWUgZm9yIHRoZVxuICogZXhwYW5kZWQgYXR0cmlidXRpb25zIGJ1dHRvbi5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwRXZlbnQuanNcIikuZGVmYXVsdCk6dm9pZH0gW3JlbmRlcl0gRnVuY3Rpb24gY2FsbGVkIHdoZW5cbiAqIHRoZSBjb250cm9sIHNob3VsZCBiZSByZS1yZW5kZXJlZC4gVGhpcyBpcyBjYWxsZWQgaW4gYSBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYFxuICogY2FsbGJhY2suXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBDb250cm9sIHRvIHNob3cgYWxsIHRoZSBhdHRyaWJ1dGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBsYXllciBzb3VyY2VzXG4gKiBpbiB0aGUgbWFwLiBUaGlzIGNvbnRyb2wgaXMgb25lIG9mIHRoZSBkZWZhdWx0IGNvbnRyb2xzIGluY2x1ZGVkIGluIG1hcHMuXG4gKiBCeSBkZWZhdWx0IGl0IHdpbGwgc2hvdyBpbiB0aGUgYm90dG9tIHJpZ2h0IHBvcnRpb24gb2YgdGhlIG1hcCwgYnV0IHRoaXMgY2FuXG4gKiBiZSBjaGFuZ2VkIGJ5IHVzaW5nIGEgY3NzIHNlbGVjdG9yIGZvciBgLm9sLWF0dHJpYnV0aW9uYC5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIEF0dHJpYnV0aW9uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEF0dHJpYnV0aW9uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgQXR0cmlidXRpb24gb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBBdHRyaWJ1dGlvbihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGVsZW1lbnQ6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgcmVuZGVyOiBvcHRpb25zLnJlbmRlcixcbiAgICAgIHRhcmdldDogb3B0aW9ucy50YXJnZXRcbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMudWxFbGVtZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbGxhcHNlZF8gPSBvcHRpb25zLmNvbGxhcHNlZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb2xsYXBzZWQgOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy51c2VyQ29sbGFwc2VkXyA9IF90aGlzLmNvbGxhcHNlZF87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLm92ZXJyaWRlQ29sbGFwc2libGVfID0gb3B0aW9ucy5jb2xsYXBzaWJsZSAhPT0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5jb2xsYXBzaWJsZV8gPSBvcHRpb25zLmNvbGxhcHNpYmxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbGxhcHNpYmxlIDogdHJ1ZTtcblxuICAgIGlmICghX3RoaXMuY29sbGFwc2libGVfKSB7XG4gICAgICBfdGhpcy5jb2xsYXBzZWRfID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGNsYXNzTmFtZSA9IG9wdGlvbnMuY2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsYXNzTmFtZSA6ICdvbC1hdHRyaWJ1dGlvbic7XG4gICAgdmFyIHRpcExhYmVsID0gb3B0aW9ucy50aXBMYWJlbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy50aXBMYWJlbCA6ICdBdHRyaWJ1dGlvbnMnO1xuICAgIHZhciBleHBhbmRDbGFzc05hbWUgPSBvcHRpb25zLmV4cGFuZENsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5leHBhbmRDbGFzc05hbWUgOiBjbGFzc05hbWUgKyAnLWV4cGFuZCc7XG4gICAgdmFyIGNvbGxhcHNlTGFiZWwgPSBvcHRpb25zLmNvbGxhcHNlTGFiZWwgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29sbGFwc2VMYWJlbCA6IFwiXFx4QkJcIjtcbiAgICB2YXIgY29sbGFwc2VDbGFzc05hbWUgPSBvcHRpb25zLmNvbGxhcHNlQ2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbGxhcHNlQ2xhc3NOYW1lIDogY2xhc3NOYW1lICsgJy1jb2xscGFzZSc7XG5cbiAgICBpZiAodHlwZW9mIGNvbGxhcHNlTGFiZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAvKipcbiAgICAgICAqIEBwcml2YXRlXG4gICAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICAgKi9cbiAgICAgIF90aGlzLmNvbGxhcHNlTGFiZWxfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgX3RoaXMuY29sbGFwc2VMYWJlbF8udGV4dENvbnRlbnQgPSBjb2xsYXBzZUxhYmVsO1xuICAgICAgX3RoaXMuY29sbGFwc2VMYWJlbF8uY2xhc3NOYW1lID0gY29sbGFwc2VDbGFzc05hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIF90aGlzLmNvbGxhcHNlTGFiZWxfID0gY29sbGFwc2VMYWJlbDtcbiAgICB9XG5cbiAgICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmxhYmVsIDogJ2knO1xuXG4gICAgaWYgKHR5cGVvZiBsYWJlbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8qKlxuICAgICAgICogQHByaXZhdGVcbiAgICAgICAqIEB0eXBlIHtIVE1MRWxlbWVudH1cbiAgICAgICAqL1xuICAgICAgX3RoaXMubGFiZWxfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgX3RoaXMubGFiZWxfLnRleHRDb250ZW50ID0gbGFiZWw7XG4gICAgICBfdGhpcy5sYWJlbF8uY2xhc3NOYW1lID0gZXhwYW5kQ2xhc3NOYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5sYWJlbF8gPSBsYWJlbDtcbiAgICB9XG5cbiAgICB2YXIgYWN0aXZlTGFiZWwgPSBfdGhpcy5jb2xsYXBzaWJsZV8gJiYgIV90aGlzLmNvbGxhcHNlZF8gPyBfdGhpcy5jb2xsYXBzZUxhYmVsXyA6IF90aGlzLmxhYmVsXztcbiAgICB2YXIgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgYnV0dG9uLnNldEF0dHJpYnV0ZSgndHlwZScsICdidXR0b24nKTtcbiAgICBidXR0b24udGl0bGUgPSB0aXBMYWJlbDtcbiAgICBidXR0b24uYXBwZW5kQ2hpbGQoYWN0aXZlTGFiZWwpO1xuICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DTElDSywgX3RoaXMuaGFuZGxlQ2xpY2tfLmJpbmQoX3RoaXMpLCBmYWxzZSk7XG4gICAgdmFyIGNzc0NsYXNzZXMgPSBjbGFzc05hbWUgKyAnICcgKyBDTEFTU19VTlNFTEVDVEFCTEUgKyAnICcgKyBDTEFTU19DT05UUk9MICsgKF90aGlzLmNvbGxhcHNlZF8gJiYgX3RoaXMuY29sbGFwc2libGVfID8gJyAnICsgQ0xBU1NfQ09MTEFQU0VEIDogJycpICsgKF90aGlzLmNvbGxhcHNpYmxlXyA/ICcnIDogJyBvbC11bmNvbGxhcHNpYmxlJyk7XG4gICAgdmFyIGVsZW1lbnQgPSBfdGhpcy5lbGVtZW50O1xuICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY3NzQ2xhc3NlcztcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKF90aGlzLnVsRWxlbWVudF8pO1xuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoYnV0dG9uKTtcbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgY3VycmVudGx5IHJlbmRlcmVkIHJlc29sdXRpb25zLlxuICAgICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZEF0dHJpYnV0aW9uc18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRWaXNpYmxlXyA9IHRydWU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDb2xsZWN0IGEgbGlzdCBvZiB2aXNpYmxlIGF0dHJpYnV0aW9ucyBhbmQgc2V0IHRoZSBjb2xsYXBzaWJsZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gQXR0cmlidXRpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5jb2xsZWN0U291cmNlQXR0cmlidXRpb25zXyA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgLyoqXG4gICAgICogVXNlZCB0byBkZXRlcm1pbmUgaWYgYW4gYXR0cmlidXRpb24gYWxyZWFkeSBleGlzdHMuXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBib29sZWFuPn1cbiAgICAgKi9cbiAgICB2YXIgbG9va3VwID0ge307XG4gICAgLyoqXG4gICAgICogQSBsaXN0IG9mIHZpc2libGUgYXR0cmlidXRpb25zLlxuICAgICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuXG4gICAgdmFyIHZpc2libGVBdHRyaWJ1dGlvbnMgPSBbXTtcbiAgICB2YXIgY29sbGFwc2libGUgPSB0cnVlO1xuICAgIHZhciBsYXllclN0YXRlc0FycmF5ID0gZnJhbWVTdGF0ZS5sYXllclN0YXRlc0FycmF5O1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGF5ZXJTdGF0ZXNBcnJheS5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgbGF5ZXJTdGF0ZSA9IGxheWVyU3RhdGVzQXJyYXlbaV07XG5cbiAgICAgIGlmICghaW5WaWV3KGxheWVyU3RhdGUsIGZyYW1lU3RhdGUudmlld1N0YXRlKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNvdXJjZSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBsYXllclN0YXRlLmxheWVyLmdldFNvdXJjZSgpO1xuXG4gICAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgdmFyIGF0dHJpYnV0aW9uR2V0dGVyID0gc291cmNlLmdldEF0dHJpYnV0aW9ucygpO1xuXG4gICAgICBpZiAoIWF0dHJpYnV0aW9uR2V0dGVyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgYXR0cmlidXRpb25zID0gYXR0cmlidXRpb25HZXR0ZXIoZnJhbWVTdGF0ZSk7XG5cbiAgICAgIGlmICghYXR0cmlidXRpb25zKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb2xsYXBzaWJsZSA9IGNvbGxhcHNpYmxlICYmIHNvdXJjZS5nZXRBdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSgpICE9PSBmYWxzZTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXR0cmlidXRpb25zKSkge1xuICAgICAgICBmb3IgKHZhciBqID0gMCwgamogPSBhdHRyaWJ1dGlvbnMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgIGlmICghKGF0dHJpYnV0aW9uc1tqXSBpbiBsb29rdXApKSB7XG4gICAgICAgICAgICB2aXNpYmxlQXR0cmlidXRpb25zLnB1c2goYXR0cmlidXRpb25zW2pdKTtcbiAgICAgICAgICAgIGxvb2t1cFthdHRyaWJ1dGlvbnNbal1dID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghKGF0dHJpYnV0aW9ucyBpbiBsb29rdXApKSB7XG4gICAgICAgICAgdmlzaWJsZUF0dHJpYnV0aW9ucy5wdXNoKGF0dHJpYnV0aW9ucyk7XG4gICAgICAgICAgbG9va3VwW2F0dHJpYnV0aW9uc10gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm92ZXJyaWRlQ29sbGFwc2libGVfKSB7XG4gICAgICB0aGlzLnNldENvbGxhcHNpYmxlKGNvbGxhcHNpYmxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmlzaWJsZUF0dHJpYnV0aW9ucztcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7P2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS51cGRhdGVFbGVtZW50XyA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgaWYgKCFmcmFtZVN0YXRlKSB7XG4gICAgICBpZiAodGhpcy5yZW5kZXJlZFZpc2libGVfKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB0aGlzLnJlbmRlcmVkVmlzaWJsZV8gPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdHRyaWJ1dGlvbnMgPSB0aGlzLmNvbGxlY3RTb3VyY2VBdHRyaWJ1dGlvbnNfKGZyYW1lU3RhdGUpO1xuICAgIHZhciB2aXNpYmxlID0gYXR0cmlidXRpb25zLmxlbmd0aCA+IDA7XG5cbiAgICBpZiAodGhpcy5yZW5kZXJlZFZpc2libGVfICE9IHZpc2libGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA/ICcnIDogJ25vbmUnO1xuICAgICAgdGhpcy5yZW5kZXJlZFZpc2libGVfID0gdmlzaWJsZTtcbiAgICB9XG5cbiAgICBpZiAoZXF1YWxzKGF0dHJpYnV0aW9ucywgdGhpcy5yZW5kZXJlZEF0dHJpYnV0aW9uc18pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmVtb3ZlQ2hpbGRyZW4odGhpcy51bEVsZW1lbnRfKTsgLy8gYXBwZW5kIHRoZSBhdHRyaWJ1dGlvbnNcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGF0dHJpYnV0aW9ucy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJyk7XG4gICAgICBlbGVtZW50LmlubmVySFRNTCA9IGF0dHJpYnV0aW9uc1tpXTtcbiAgICAgIHRoaXMudWxFbGVtZW50Xy5hcHBlbmRDaGlsZChlbGVtZW50KTtcbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcmVkQXR0cmlidXRpb25zXyA9IGF0dHJpYnV0aW9ucztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGhhbmRsZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5oYW5kbGVDbGlja18gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuaGFuZGxlVG9nZ2xlXygpO1xuICAgIHRoaXMudXNlckNvbGxhcHNlZF8gPSB0aGlzLmNvbGxhcHNlZF87XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEF0dHJpYnV0aW9uLnByb3RvdHlwZS5oYW5kbGVUb2dnbGVfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKENMQVNTX0NPTExBUFNFRCk7XG5cbiAgICBpZiAodGhpcy5jb2xsYXBzZWRfKSB7XG4gICAgICByZXBsYWNlTm9kZSh0aGlzLmNvbGxhcHNlTGFiZWxfLCB0aGlzLmxhYmVsXyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcGxhY2VOb2RlKHRoaXMubGFiZWxfLCB0aGlzLmNvbGxhcHNlTGFiZWxfKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvbGxhcHNlZF8gPSAhdGhpcy5jb2xsYXBzZWRfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgYXR0cmlidXRpb24gaXMgY29sbGFwc2libGUsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSB3aWRnZXQgaXMgY29sbGFwc2libGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBBdHRyaWJ1dGlvbi5wcm90b3R5cGUuZ2V0Q29sbGFwc2libGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGFwc2libGVfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHdoZXRoZXIgdGhlIGF0dHJpYnV0aW9uIHNob3VsZCBiZSBjb2xsYXBzaWJsZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBjb2xsYXBzaWJsZSBUcnVlIGlmIHRoZSB3aWRnZXQgaXMgY29sbGFwc2libGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBBdHRyaWJ1dGlvbi5wcm90b3R5cGUuc2V0Q29sbGFwc2libGUgPSBmdW5jdGlvbiAoY29sbGFwc2libGUpIHtcbiAgICBpZiAodGhpcy5jb2xsYXBzaWJsZV8gPT09IGNvbGxhcHNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5jb2xsYXBzaWJsZV8gPSBjb2xsYXBzaWJsZTtcbiAgICB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZSgnb2wtdW5jb2xsYXBzaWJsZScpO1xuXG4gICAgaWYgKHRoaXMudXNlckNvbGxhcHNlZF8pIHtcbiAgICAgIHRoaXMuaGFuZGxlVG9nZ2xlXygpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIENvbGxhcHNlIG9yIGV4cGFuZCB0aGUgYXR0cmlidXRpb24gYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgcGFyYW1ldGVyLiBXaWxsXG4gICAqIG5vdCBkbyBhbnl0aGluZyBpZiB0aGUgYXR0cmlidXRpb24gaXNuJ3QgY29sbGFwc2libGUgb3IgaWYgdGhlIGN1cnJlbnRcbiAgICogY29sbGFwc2VkIHN0YXRlIGlzIGFscmVhZHkgdGhlIG9uZSByZXF1ZXN0ZWQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY29sbGFwc2VkIFRydWUgaWYgdGhlIHdpZGdldCBpcyBjb2xsYXBzZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBBdHRyaWJ1dGlvbi5wcm90b3R5cGUuc2V0Q29sbGFwc2VkID0gZnVuY3Rpb24gKGNvbGxhcHNlZCkge1xuICAgIHRoaXMudXNlckNvbGxhcHNlZF8gPSBjb2xsYXBzZWQ7XG5cbiAgICBpZiAoIXRoaXMuY29sbGFwc2libGVfIHx8IHRoaXMuY29sbGFwc2VkXyA9PT0gY29sbGFwc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVUb2dnbGVfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gYHRydWVgIHdoZW4gdGhlIGF0dHJpYnV0aW9uIGlzIGN1cnJlbnRseSBjb2xsYXBzZWQgb3IgYGZhbHNlYFxuICAgKiBvdGhlcndpc2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIHdpZGdldCBpcyBjb2xsYXBzZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBBdHRyaWJ1dGlvbi5wcm90b3R5cGUuZ2V0Q29sbGFwc2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbGxhcHNlZF87XG4gIH07XG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGF0dHJpYnV0aW9uIGVsZW1lbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwRXZlbnQgTWFwIGV2ZW50LlxuICAgKiBAb3ZlcnJpZGVcbiAgICovXG5cblxuICBBdHRyaWJ1dGlvbi5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gKG1hcEV2ZW50KSB7XG4gICAgdGhpcy51cGRhdGVFbGVtZW50XyhtYXBFdmVudC5mcmFtZVN0YXRlKTtcbiAgfTtcblxuICByZXR1cm4gQXR0cmlidXRpb247XG59KENvbnRyb2wpO1xuXG5leHBvcnQgZGVmYXVsdCBBdHRyaWJ1dGlvbjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2NvbnRyb2wvUm90YXRlXG4gKi9cblxuXG5pbXBvcnQgQ29udHJvbCBmcm9tICcuL0NvbnRyb2wuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IENMQVNTX0NPTlRST0wsIENMQVNTX0hJRERFTiwgQ0xBU1NfVU5TRUxFQ1RBQkxFIH0gZnJvbSAnLi4vY3NzLmpzJztcbmltcG9ydCB7IGVhc2VPdXQgfSBmcm9tICcuLi9lYXNpbmcuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtcm90YXRlJ10gQ1NTIGNsYXNzIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ3xIVE1MRWxlbWVudH0gW2xhYmVsPSfih6cnXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIHJvdGF0ZSBidXR0b24uXG4gKiBJbnN0ZWFkIG9mIHRleHQsIGFsc28gYW4gZWxlbWVudCAoZS5nLiBhIGBzcGFuYCBlbGVtZW50KSBjYW4gYmUgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdGlwTGFiZWw9J1Jlc2V0IHJvdGF0aW9uJ10gVGV4dCBsYWJlbCB0byB1c2UgZm9yIHRoZSByb3RhdGUgdGlwLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb21wYXNzQ2xhc3NOYW1lPSdvbC1jb21wYXNzJ10gQ1NTIGNsYXNzIG5hbWUgZm9yIHRoZSBjb21wYXNzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthdXRvSGlkZT10cnVlXSBIaWRlIHRoZSBjb250cm9sIHdoZW4gcm90YXRpb24gaXMgMC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwRXZlbnQuanNcIikuZGVmYXVsdCk6dm9pZH0gW3JlbmRlcl0gRnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIGNvbnRyb2wgc2hvdWxkXG4gKiBiZSByZS1yZW5kZXJlZC4gVGhpcyBpcyBjYWxsZWQgaW4gYSBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYCBjYWxsYmFjay5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTp2b2lkfSBbcmVzZXROb3J0aF0gRnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIGNvbnRyb2wgaXMgY2xpY2tlZC5cbiAqIFRoaXMgd2lsbCBvdmVycmlkZSB0aGUgZGVmYXVsdCBgcmVzZXROb3J0aGAuXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fHN0cmluZ30gW3RhcmdldF0gU3BlY2lmeSBhIHRhcmdldCBpZiB5b3Ugd2FudCB0aGUgY29udHJvbCB0byBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGUgbWFwJ3Mgdmlld3BvcnQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIGJ1dHRvbiBjb250cm9sIHRvIHJlc2V0IHJvdGF0aW9uIHRvIDAuXG4gKiBUbyBzdHlsZSB0aGlzIGNvbnRyb2wgdXNlIGNzcyBzZWxlY3RvciBgLm9sLXJvdGF0ZWAuIEEgYC5vbC1oaWRkZW5gIGNzc1xuICogc2VsZWN0b3IgaXMgYWRkZWQgdG8gdGhlIGJ1dHRvbiB3aGVuIHRoZSByb3RhdGlvbiBpcyAwLlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgUm90YXRlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFJvdGF0ZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFJvdGF0ZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFJvdGF0ZShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGVsZW1lbnQ6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgcmVuZGVyOiBvcHRpb25zLnJlbmRlcixcbiAgICAgIHRhcmdldDogb3B0aW9ucy50YXJnZXRcbiAgICB9KSB8fCB0aGlzO1xuICAgIHZhciBjbGFzc05hbWUgPSBvcHRpb25zLmNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbGFzc05hbWUgOiAnb2wtcm90YXRlJztcbiAgICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmxhYmVsIDogXCJcXHUyMUU3XCI7XG4gICAgdmFyIGNvbXBhc3NDbGFzc05hbWUgPSBvcHRpb25zLmNvbXBhc3NDbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29tcGFzc0NsYXNzTmFtZSA6ICdvbC1jb21wYXNzJztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmxhYmVsXyA9IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJykge1xuICAgICAgX3RoaXMubGFiZWxfID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgX3RoaXMubGFiZWxfLmNsYXNzTmFtZSA9IGNvbXBhc3NDbGFzc05hbWU7XG4gICAgICBfdGhpcy5sYWJlbF8udGV4dENvbnRlbnQgPSBsYWJlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMubGFiZWxfID0gbGFiZWw7XG5cbiAgICAgIF90aGlzLmxhYmVsXy5jbGFzc0xpc3QuYWRkKGNvbXBhc3NDbGFzc05hbWUpO1xuICAgIH1cblxuICAgIHZhciB0aXBMYWJlbCA9IG9wdGlvbnMudGlwTGFiZWwgPyBvcHRpb25zLnRpcExhYmVsIDogJ1Jlc2V0IHJvdGF0aW9uJztcbiAgICB2YXIgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnV0dG9uJyk7XG4gICAgYnV0dG9uLmNsYXNzTmFtZSA9IGNsYXNzTmFtZSArICctcmVzZXQnO1xuICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnYnV0dG9uJyk7XG4gICAgYnV0dG9uLnRpdGxlID0gdGlwTGFiZWw7XG4gICAgYnV0dG9uLmFwcGVuZENoaWxkKF90aGlzLmxhYmVsXyk7XG4gICAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNMSUNLLCBfdGhpcy5oYW5kbGVDbGlja18uYmluZChfdGhpcyksIGZhbHNlKTtcbiAgICB2YXIgY3NzQ2xhc3NlcyA9IGNsYXNzTmFtZSArICcgJyArIENMQVNTX1VOU0VMRUNUQUJMRSArICcgJyArIENMQVNTX0NPTlRST0w7XG4gICAgdmFyIGVsZW1lbnQgPSBfdGhpcy5lbGVtZW50O1xuICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY3NzQ2xhc3NlcztcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGJ1dHRvbik7XG4gICAgX3RoaXMuY2FsbFJlc2V0Tm9ydGhfID0gb3B0aW9ucy5yZXNldE5vcnRoID8gb3B0aW9ucy5yZXNldE5vcnRoIDogdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmR1cmF0aW9uXyA9IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAyNTA7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmF1dG9IaWRlXyA9IG9wdGlvbnMuYXV0b0hpZGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYXV0b0hpZGUgOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yb3RhdGlvbl8gPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAoX3RoaXMuYXV0b0hpZGVfKSB7XG4gICAgICBfdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfSElEREVOKTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGhhbmRsZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFJvdGF0ZS5wcm90b3R5cGUuaGFuZGxlQ2xpY2tfID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICh0aGlzLmNhbGxSZXNldE5vcnRoXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmNhbGxSZXNldE5vcnRoXygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlc2V0Tm9ydGhfKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBSb3RhdGUucHJvdG90eXBlLnJlc2V0Tm9ydGhfID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtYXAgPSB0aGlzLmdldE1hcCgpO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmICghdmlldykge1xuICAgICAgLy8gdGhlIG1hcCBkb2VzIG5vdCBoYXZlIGEgdmlldywgc28gd2UgY2FuJ3QgYWN0XG4gICAgICAvLyB1cG9uIGl0XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJvdGF0aW9uID0gdmlldy5nZXRSb3RhdGlvbigpO1xuXG4gICAgaWYgKHJvdGF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICh0aGlzLmR1cmF0aW9uXyA+IDAgJiYgcm90YXRpb24gJSAoMiAqIE1hdGguUEkpICE9PSAwKSB7XG4gICAgICAgIHZpZXcuYW5pbWF0ZSh7XG4gICAgICAgICAgcm90YXRpb246IDAsXG4gICAgICAgICAgZHVyYXRpb246IHRoaXMuZHVyYXRpb25fLFxuICAgICAgICAgIGVhc2luZzogZWFzZU91dFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpZXcuc2V0Um90YXRpb24oMCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogVXBkYXRlIHRoZSByb3RhdGUgY29udHJvbCBlbGVtZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEV2ZW50IE1hcCBldmVudC5cbiAgICogQG92ZXJyaWRlXG4gICAqL1xuXG5cbiAgUm90YXRlLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAobWFwRXZlbnQpIHtcbiAgICB2YXIgZnJhbWVTdGF0ZSA9IG1hcEV2ZW50LmZyYW1lU3RhdGU7XG5cbiAgICBpZiAoIWZyYW1lU3RhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcm90YXRpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yb3RhdGlvbjtcblxuICAgIGlmIChyb3RhdGlvbiAhPSB0aGlzLnJvdGF0aW9uXykge1xuICAgICAgdmFyIHRyYW5zZm9ybSA9ICdyb3RhdGUoJyArIHJvdGF0aW9uICsgJ3JhZCknO1xuXG4gICAgICBpZiAodGhpcy5hdXRvSGlkZV8pIHtcbiAgICAgICAgdmFyIGNvbnRhaW5zID0gdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19ISURERU4pO1xuXG4gICAgICAgIGlmICghY29udGFpbnMgJiYgcm90YXRpb24gPT09IDApIHtcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19ISURERU4pO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbnRhaW5zICYmIHJvdGF0aW9uICE9PSAwKSB7XG4gICAgICAgICAgdGhpcy5lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfSElEREVOKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmxhYmVsXy5zdHlsZS50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgfVxuXG4gICAgdGhpcy5yb3RhdGlvbl8gPSByb3RhdGlvbjtcbiAgfTtcblxuICByZXR1cm4gUm90YXRlO1xufShDb250cm9sKTtcblxuZXhwb3J0IGRlZmF1bHQgUm90YXRlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvY29udHJvbC9ab29tXG4gKi9cblxuXG5pbXBvcnQgQ29udHJvbCBmcm9tICcuL0NvbnRyb2wuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCB7IENMQVNTX0NPTlRST0wsIENMQVNTX1VOU0VMRUNUQUJMRSB9IGZyb20gJy4uL2Nzcy5qcyc7XG5pbXBvcnQgeyBlYXNlT3V0IH0gZnJvbSAnLi4vZWFzaW5nLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtem9vbSddIENTUyBjbGFzcyBuYW1lLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt6b29tSW5DbGFzc05hbWU9Y2xhc3NOYW1lICsgJy1pbiddIENTUyBjbGFzcyBuYW1lIGZvciB0aGUgem9vbS1pbiBidXR0b24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3pvb21PdXRDbGFzc05hbWU9Y2xhc3NOYW1lICsgJy1vdXQnXSBDU1MgY2xhc3MgbmFtZSBmb3IgdGhlIHpvb20tb3V0IGJ1dHRvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfEhUTUxFbGVtZW50fSBbem9vbUluTGFiZWw9JysnXSBUZXh0IGxhYmVsIHRvIHVzZSBmb3IgdGhlIHpvb20taW5cbiAqIGJ1dHRvbi4gSW5zdGVhZCBvZiB0ZXh0LCBhbHNvIGFuIGVsZW1lbnQgKGUuZy4gYSBgc3BhbmAgZWxlbWVudCkgY2FuIGJlIHVzZWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ3xIVE1MRWxlbWVudH0gW3pvb21PdXRMYWJlbD0nLSddIFRleHQgbGFiZWwgdG8gdXNlIGZvciB0aGUgem9vbS1vdXQgYnV0dG9uLlxuICogSW5zdGVhZCBvZiB0ZXh0LCBhbHNvIGFuIGVsZW1lbnQgKGUuZy4gYSBgc3BhbmAgZWxlbWVudCkgY2FuIGJlIHVzZWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3pvb21JblRpcExhYmVsPSdab29tIGluJ10gVGV4dCBsYWJlbCB0byB1c2UgZm9yIHRoZSBidXR0b24gdGlwLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt6b29tT3V0VGlwTGFiZWw9J1pvb20gb3V0J10gVGV4dCBsYWJlbCB0byB1c2UgZm9yIHRoZSBidXR0b24gdGlwLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YT0xXSBUaGUgem9vbSBkZWx0YSBhcHBsaWVkIG9uIGVhY2ggY2xpY2suXG4gKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fHN0cmluZ30gW3RhcmdldF0gU3BlY2lmeSBhIHRhcmdldCBpZiB5b3Ugd2FudCB0aGUgY29udHJvbCB0byBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGUgbWFwJ3Mgdmlld3BvcnQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBIGNvbnRyb2wgd2l0aCAyIGJ1dHRvbnMsIG9uZSBmb3Igem9vbSBpbiBhbmQgb25lIGZvciB6b29tIG91dC5cbiAqIFRoaXMgY29udHJvbCBpcyBvbmUgb2YgdGhlIGRlZmF1bHQgY29udHJvbHMgb2YgYSBtYXAuIFRvIHN0eWxlIHRoaXMgY29udHJvbFxuICogdXNlIGNzcyBzZWxlY3RvcnMgYC5vbC16b29tLWluYCBhbmQgYC5vbC16b29tLW91dGAuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBab29tID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFpvb20sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBab29tIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gWm9vbShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGVsZW1lbnQ6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpLFxuICAgICAgdGFyZ2V0OiBvcHRpb25zLnRhcmdldFxuICAgIH0pIHx8IHRoaXM7XG4gICAgdmFyIGNsYXNzTmFtZSA9IG9wdGlvbnMuY2xhc3NOYW1lICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsYXNzTmFtZSA6ICdvbC16b29tJztcbiAgICB2YXIgZGVsdGEgPSBvcHRpb25zLmRlbHRhICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmRlbHRhIDogMTtcbiAgICB2YXIgem9vbUluQ2xhc3NOYW1lID0gb3B0aW9ucy56b29tSW5DbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbUluQ2xhc3NOYW1lIDogY2xhc3NOYW1lICsgJy1pbic7XG4gICAgdmFyIHpvb21PdXRDbGFzc05hbWUgPSBvcHRpb25zLnpvb21PdXRDbGFzc05hbWUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuem9vbU91dENsYXNzTmFtZSA6IGNsYXNzTmFtZSArICctb3V0JztcbiAgICB2YXIgem9vbUluTGFiZWwgPSBvcHRpb25zLnpvb21JbkxhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb21JbkxhYmVsIDogJysnO1xuICAgIHZhciB6b29tT3V0TGFiZWwgPSBvcHRpb25zLnpvb21PdXRMYWJlbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy56b29tT3V0TGFiZWwgOiBcIlxcdTIyMTJcIjtcbiAgICB2YXIgem9vbUluVGlwTGFiZWwgPSBvcHRpb25zLnpvb21JblRpcExhYmVsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb21JblRpcExhYmVsIDogJ1pvb20gaW4nO1xuICAgIHZhciB6b29tT3V0VGlwTGFiZWwgPSBvcHRpb25zLnpvb21PdXRUaXBMYWJlbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy56b29tT3V0VGlwTGFiZWwgOiAnWm9vbSBvdXQnO1xuICAgIHZhciBpbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBpbkVsZW1lbnQuY2xhc3NOYW1lID0gem9vbUluQ2xhc3NOYW1lO1xuICAgIGluRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnYnV0dG9uJyk7XG4gICAgaW5FbGVtZW50LnRpdGxlID0gem9vbUluVGlwTGFiZWw7XG4gICAgaW5FbGVtZW50LmFwcGVuZENoaWxkKHR5cGVvZiB6b29tSW5MYWJlbCA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh6b29tSW5MYWJlbCkgOiB6b29tSW5MYWJlbCk7XG4gICAgaW5FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNMSUNLLCBfdGhpcy5oYW5kbGVDbGlja18uYmluZChfdGhpcywgZGVsdGEpLCBmYWxzZSk7XG4gICAgdmFyIG91dEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdidXR0b24nKTtcbiAgICBvdXRFbGVtZW50LmNsYXNzTmFtZSA9IHpvb21PdXRDbGFzc05hbWU7XG4gICAgb3V0RWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAnYnV0dG9uJyk7XG4gICAgb3V0RWxlbWVudC50aXRsZSA9IHpvb21PdXRUaXBMYWJlbDtcbiAgICBvdXRFbGVtZW50LmFwcGVuZENoaWxkKHR5cGVvZiB6b29tT3V0TGFiZWwgPT09ICdzdHJpbmcnID8gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoem9vbU91dExhYmVsKSA6IHpvb21PdXRMYWJlbCk7XG4gICAgb3V0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DTElDSywgX3RoaXMuaGFuZGxlQ2xpY2tfLmJpbmQoX3RoaXMsIC1kZWx0YSksIGZhbHNlKTtcbiAgICB2YXIgY3NzQ2xhc3NlcyA9IGNsYXNzTmFtZSArICcgJyArIENMQVNTX1VOU0VMRUNUQUJMRSArICcgJyArIENMQVNTX0NPTlRST0w7XG4gICAgdmFyIGVsZW1lbnQgPSBfdGhpcy5lbGVtZW50O1xuICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY3NzQ2xhc3NlcztcbiAgICBlbGVtZW50LmFwcGVuZENoaWxkKGluRWxlbWVudCk7XG4gICAgZWxlbWVudC5hcHBlbmRDaGlsZChvdXRFbGVtZW50KTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMjUwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhIFpvb20gZGVsdGEuXG4gICAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGhhbmRsZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFpvb20ucHJvdG90eXBlLmhhbmRsZUNsaWNrXyA9IGZ1bmN0aW9uIChkZWx0YSwgZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuem9vbUJ5RGVsdGFfKGRlbHRhKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSBab29tIGRlbHRhLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFpvb20ucHJvdG90eXBlLnpvb21CeURlbHRhXyA9IGZ1bmN0aW9uIChkZWx0YSkge1xuICAgIHZhciBtYXAgPSB0aGlzLmdldE1hcCgpO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmICghdmlldykge1xuICAgICAgLy8gdGhlIG1hcCBkb2VzIG5vdCBoYXZlIGEgdmlldywgc28gd2UgY2FuJ3QgYWN0XG4gICAgICAvLyB1cG9uIGl0XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGN1cnJlbnRab29tID0gdmlldy5nZXRab29tKCk7XG5cbiAgICBpZiAoY3VycmVudFpvb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIG5ld1pvb20gPSB2aWV3LmdldENvbnN0cmFpbmVkWm9vbShjdXJyZW50Wm9vbSArIGRlbHRhKTtcblxuICAgICAgaWYgKHRoaXMuZHVyYXRpb25fID4gMCkge1xuICAgICAgICBpZiAodmlldy5nZXRBbmltYXRpbmcoKSkge1xuICAgICAgICAgIHZpZXcuY2FuY2VsQW5pbWF0aW9ucygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmlldy5hbmltYXRlKHtcbiAgICAgICAgICB6b29tOiBuZXdab29tLFxuICAgICAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uXyxcbiAgICAgICAgICBlYXNpbmc6IGVhc2VPdXRcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2aWV3LnNldFpvb20obmV3Wm9vbSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBab29tO1xufShDb250cm9sKTtcblxuZXhwb3J0IGRlZmF1bHQgWm9vbTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvY29udHJvbFxuICovXG5pbXBvcnQgQXR0cmlidXRpb24gZnJvbSAnLi9jb250cm9sL0F0dHJpYnV0aW9uLmpzJztcbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gJy4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgUm90YXRlIGZyb20gJy4vY29udHJvbC9Sb3RhdGUuanMnO1xuaW1wb3J0IFpvb20gZnJvbSAnLi9jb250cm9sL1pvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBBdHRyaWJ1dGlvbiB9IGZyb20gJy4vY29udHJvbC9BdHRyaWJ1dGlvbi5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIENvbnRyb2wgfSBmcm9tICcuL2NvbnRyb2wvQ29udHJvbC5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIEZ1bGxTY3JlZW4gfSBmcm9tICcuL2NvbnRyb2wvRnVsbFNjcmVlbi5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIE1vdXNlUG9zaXRpb24gfSBmcm9tICcuL2NvbnRyb2wvTW91c2VQb3NpdGlvbi5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIE92ZXJ2aWV3TWFwIH0gZnJvbSAnLi9jb250cm9sL092ZXJ2aWV3TWFwLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgUm90YXRlIH0gZnJvbSAnLi9jb250cm9sL1JvdGF0ZS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFNjYWxlTGluZSB9IGZyb20gJy4vY29udHJvbC9TY2FsZUxpbmUuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBab29tIH0gZnJvbSAnLi9jb250cm9sL1pvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBab29tU2xpZGVyIH0gZnJvbSAnLi9jb250cm9sL1pvb21TbGlkZXIuanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBab29tVG9FeHRlbnQgfSBmcm9tICcuL2NvbnRyb2wvWm9vbVRvRXh0ZW50LmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRGVmYXVsdHNPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthdHRyaWJ1dGlvbj10cnVlXSBJbmNsdWRlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvQXR0cmlidXRpb25+QXR0cmlidXRpb259LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2NvbnRyb2wvQXR0cmlidXRpb24uanNcIikuT3B0aW9uc30gW2F0dHJpYnV0aW9uT3B0aW9uc11cbiAqIE9wdGlvbnMgZm9yIHtAbGluayBtb2R1bGU6b2wvY29udHJvbC9BdHRyaWJ1dGlvbn5BdHRyaWJ1dGlvbn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtyb3RhdGU9dHJ1ZV0gSW5jbHVkZVxuICoge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1JvdGF0ZX5Sb3RhdGV9LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2NvbnRyb2wvUm90YXRlLmpzXCIpLk9wdGlvbnN9IFtyb3RhdGVPcHRpb25zXSBPcHRpb25zXG4gKiBmb3Ige0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1JvdGF0ZX5Sb3RhdGV9LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbem9vbV0gSW5jbHVkZSB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvWm9vbX5ab29tfS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb250cm9sL1pvb20uanNcIikuT3B0aW9uc30gW3pvb21PcHRpb25zXSBPcHRpb25zIGZvclxuICoge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1pvb21+Wm9vbX0uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBTZXQgb2YgY29udHJvbHMgaW5jbHVkZWQgaW4gbWFwcyBieSBkZWZhdWx0LiBVbmxlc3MgY29uZmlndXJlZCBvdGhlcndpc2UsXG4gKiB0aGlzIHJldHVybnMgYSBjb2xsZWN0aW9uIGNvbnRhaW5pbmcgYW4gaW5zdGFuY2Ugb2YgZWFjaCBvZiB0aGUgZm9sbG93aW5nXG4gKiBjb250cm9sczpcbiAqICoge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1pvb21+Wm9vbX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1JvdGF0ZX5Sb3RhdGV9XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvY29udHJvbC9BdHRyaWJ1dGlvbn5BdHRyaWJ1dGlvbn1cbiAqXG4gKiBAcGFyYW0ge0RlZmF1bHRzT3B0aW9ucz19IG9wdF9vcHRpb25zXG4gKiBEZWZhdWx0cyBvcHRpb25zLlxuICogQHJldHVybiB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuL2NvbnRyb2wvQ29udHJvbC5qc1wiKS5kZWZhdWx0Pn1cbiAqIENvbnRyb2xzLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0cyhvcHRfb3B0aW9ucykge1xuICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgdmFyIGNvbnRyb2xzID0gbmV3IENvbGxlY3Rpb24oKTtcbiAgdmFyIHpvb21Db250cm9sID0gb3B0aW9ucy56b29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnpvb20gOiB0cnVlO1xuXG4gIGlmICh6b29tQ29udHJvbCkge1xuICAgIGNvbnRyb2xzLnB1c2gobmV3IFpvb20ob3B0aW9ucy56b29tT3B0aW9ucykpO1xuICB9XG5cbiAgdmFyIHJvdGF0ZUNvbnRyb2wgPSBvcHRpb25zLnJvdGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGUgOiB0cnVlO1xuXG4gIGlmIChyb3RhdGVDb250cm9sKSB7XG4gICAgY29udHJvbHMucHVzaChuZXcgUm90YXRlKG9wdGlvbnMucm90YXRlT3B0aW9ucykpO1xuICB9XG5cbiAgdmFyIGF0dHJpYnV0aW9uQ29udHJvbCA9IG9wdGlvbnMuYXR0cmlidXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYXR0cmlidXRpb24gOiB0cnVlO1xuXG4gIGlmIChhdHRyaWJ1dGlvbkNvbnRyb2wpIHtcbiAgICBjb250cm9scy5wdXNoKG5ldyBBdHRyaWJ1dGlvbihvcHRpb25zLmF0dHJpYnV0aW9uT3B0aW9ucykpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRyb2xzO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9Qcm9wZXJ0eVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBBQ1RJVkU6ICdhY3RpdmUnXG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb25cbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0IGZyb20gJy4uL09iamVjdC5qcyc7XG5pbXBvcnQgSW50ZXJhY3Rpb25Qcm9wZXJ0eSBmcm9tICcuL1Byb3BlcnR5LmpzJztcbmltcG9ydCB7IGVhc2VPdXQsIGxpbmVhciB9IGZyb20gJy4uL2Vhc2luZy5qcyc7XG4vKipcbiAqIE9iamVjdCBsaXRlcmFsIHdpdGggY29uZmlnIG9wdGlvbnMgZm9yIGludGVyYWN0aW9ucy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IEludGVyYWN0aW9uT3B0aW9uc1xuICogQHByb3BlcnR5IHtmdW5jdGlvbihpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdCk6Ym9vbGVhbn0gaGFuZGxlRXZlbnRcbiAqIE1ldGhvZCBjYWxsZWQgYnkgdGhlIG1hcCB0byBub3RpZnkgdGhlIGludGVyYWN0aW9uIHRoYXQgYSBicm93c2VyIGV2ZW50IHdhc1xuICogZGlzcGF0Y2hlZCB0byB0aGUgbWFwLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIGZhbHN5IHZhbHVlLCBwcm9wYWdhdGlvbiBvZlxuICogdGhlIGV2ZW50IHRvIG90aGVyIGludGVyYWN0aW9ucyBpbiB0aGUgbWFwJ3MgaW50ZXJhY3Rpb25zIGNoYWluIHdpbGwgYmVcbiAqIHByZXZlbnRlZCAodGhpcyBpbmNsdWRlcyBmdW5jdGlvbnMgd2l0aCBubyBleHBsaWNpdCByZXR1cm4pLiBUaGUgaW50ZXJhY3Rpb25zXG4gKiBhcmUgdHJhdmVyc2VkIGluIHJldmVyc2Ugb3JkZXIgb2YgdGhlIGludGVyYWN0aW9ucyBjb2xsZWN0aW9uIG9mIHRoZSBtYXAuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzOyBub3JtYWxseSBvbmx5IHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdFxuICogaW5zdGFudGlhdGVkIGluIGFwcHMuXG4gKiBVc2VyIGFjdGlvbnMgdGhhdCBjaGFuZ2UgdGhlIHN0YXRlIG9mIHRoZSBtYXAuIFNvbWUgYXJlIHNpbWlsYXIgdG8gY29udHJvbHMsXG4gKiBidXQgYXJlIG5vdCBhc3NvY2lhdGVkIHdpdGggYSBET00gZWxlbWVudC5cbiAqIEZvciBleGFtcGxlLCB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbX5LZXlib2FyZFpvb219IGlzXG4gKiBmdW5jdGlvbmFsbHkgdGhlIHNhbWUgYXMge0BsaW5rIG1vZHVsZTpvbC9jb250cm9sL1pvb21+Wm9vbX0sIGJ1dCB0cmlnZ2VyZWRcbiAqIGJ5IGEga2V5Ym9hcmQgZXZlbnQgbm90IGEgYnV0dG9uIGVsZW1lbnQgZXZlbnQuXG4gKiBBbHRob3VnaCBpbnRlcmFjdGlvbnMgZG8gbm90IGhhdmUgYSBET00gZWxlbWVudCwgc29tZSBvZiB0aGVtIGRvIHJlbmRlclxuICogdmVjdG9ycyBhbmQgc28gYXJlIHZpc2libGUgb24gdGhlIHNjcmVlbi5cbiAqIEBhcGlcbiAqL1xuXG52YXIgSW50ZXJhY3Rpb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSW50ZXJhY3Rpb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0ludGVyYWN0aW9uT3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gSW50ZXJhY3Rpb24ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgaWYgKG9wdF9vcHRpb25zICYmIG9wdF9vcHRpb25zLmhhbmRsZUV2ZW50KSB7XG4gICAgICBfdGhpcy5oYW5kbGVFdmVudCA9IG9wdF9vcHRpb25zLmhhbmRsZUV2ZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMubWFwXyA9IG51bGw7XG5cbiAgICBfdGhpcy5zZXRBY3RpdmUodHJ1ZSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybiB3aGV0aGVyIHRoZSBpbnRlcmFjdGlvbiBpcyBjdXJyZW50bHkgYWN0aXZlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGludGVyYWN0aW9uIGlzIGFjdGl2ZSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0QWN0aXZlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovXG4gICAgICB0aGlzLmdldChJbnRlcmFjdGlvblByb3BlcnR5LkFDVElWRSlcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtYXAgYXNzb2NpYXRlZCB3aXRoIHRoaXMgaW50ZXJhY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBNYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0TWFwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1hcF87XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudCBtYXAgYnJvd3NlciBldmVudH0uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYGZhbHNlYCB0byBzdG9wIGV2ZW50IHByb3BhZ2F0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuICAvKipcbiAgICogQWN0aXZhdGUgb3IgZGVhY3RpdmF0ZSB0aGUgaW50ZXJhY3Rpb24uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYWN0aXZlIEFjdGl2ZS5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEludGVyYWN0aW9uLnByb3RvdHlwZS5zZXRBY3RpdmUgPSBmdW5jdGlvbiAoYWN0aXZlKSB7XG4gICAgdGhpcy5zZXQoSW50ZXJhY3Rpb25Qcm9wZXJ0eS5BQ1RJVkUsIGFjdGl2ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGludGVyYWN0aW9uIGZyb20gaXRzIGN1cnJlbnQgbWFwIGFuZCBhdHRhY2ggaXQgdG8gdGhlIG5ldyBtYXAuXG4gICAqIFN1YmNsYXNzZXMgbWF5IHNldCB1cCBldmVudCBoYW5kbGVycyB0byBnZXQgbm90aWZpZWQgYWJvdXQgY2hhbmdlcyB0b1xuICAgKiB0aGUgbWFwIGhlcmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAqL1xuXG5cbiAgSW50ZXJhY3Rpb24ucHJvdG90eXBlLnNldE1hcCA9IGZ1bmN0aW9uIChtYXApIHtcbiAgICB0aGlzLm1hcF8gPSBtYXA7XG4gIH07XG5cbiAgcmV0dXJuIEludGVyYWN0aW9uO1xufShCYXNlT2JqZWN0KTtcbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9WaWV3LmpzXCIpLmRlZmF1bHR9IHZpZXcgVmlldy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBkZWx0YSBEZWx0YS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2R1cmF0aW9uIER1cmF0aW9uLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHBhbih2aWV3LCBkZWx0YSwgb3B0X2R1cmF0aW9uKSB7XG4gIHZhciBjdXJyZW50Q2VudGVyID0gdmlldy5nZXRDZW50ZXJJbnRlcm5hbCgpO1xuXG4gIGlmIChjdXJyZW50Q2VudGVyKSB7XG4gICAgdmFyIGNlbnRlciA9IFtjdXJyZW50Q2VudGVyWzBdICsgZGVsdGFbMF0sIGN1cnJlbnRDZW50ZXJbMV0gKyBkZWx0YVsxXV07XG4gICAgdmlldy5hbmltYXRlSW50ZXJuYWwoe1xuICAgICAgZHVyYXRpb246IG9wdF9kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0X2R1cmF0aW9uIDogMjUwLFxuICAgICAgZWFzaW5nOiBsaW5lYXIsXG4gICAgICBjZW50ZXI6IHZpZXcuZ2V0Q29uc3RyYWluZWRDZW50ZXIoY2VudGVyKVxuICAgIH0pO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVmlldy5qc1wiKS5kZWZhdWx0fSB2aWV3IFZpZXcuXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGEgRGVsdGEgZnJvbSBwcmV2aW91cyB6b29tIGxldmVsLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIEFuY2hvciBjb29yZGluYXRlIGluIHRoZSB1c2VyIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9kdXJhdGlvbiBEdXJhdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gem9vbUJ5RGVsdGEodmlldywgZGVsdGEsIG9wdF9hbmNob3IsIG9wdF9kdXJhdGlvbikge1xuICB2YXIgY3VycmVudFpvb20gPSB2aWV3LmdldFpvb20oKTtcblxuICBpZiAoY3VycmVudFpvb20gPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBuZXdab29tID0gdmlldy5nZXRDb25zdHJhaW5lZFpvb20oY3VycmVudFpvb20gKyBkZWx0YSk7XG4gIHZhciBuZXdSZXNvbHV0aW9uID0gdmlldy5nZXRSZXNvbHV0aW9uRm9yWm9vbShuZXdab29tKTtcblxuICBpZiAodmlldy5nZXRBbmltYXRpbmcoKSkge1xuICAgIHZpZXcuY2FuY2VsQW5pbWF0aW9ucygpO1xuICB9XG5cbiAgdmlldy5hbmltYXRlKHtcbiAgICByZXNvbHV0aW9uOiBuZXdSZXNvbHV0aW9uLFxuICAgIGFuY2hvcjogb3B0X2FuY2hvcixcbiAgICBkdXJhdGlvbjogb3B0X2R1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRfZHVyYXRpb24gOiAyNTAsXG4gICAgZWFzaW5nOiBlYXNlT3V0XG4gIH0pO1xufVxuZXhwb3J0IGRlZmF1bHQgSW50ZXJhY3Rpb247IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9Eb3VibGVDbGlja1pvb21cbiAqL1xuXG5cbmltcG9ydCBJbnRlcmFjdGlvbiwgeyB6b29tQnlEZWx0YSB9IGZyb20gJy4vSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudFR5cGUgZnJvbSAnLi4vTWFwQnJvd3NlckV2ZW50VHlwZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MjUwXSBBbmltYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YT0xXSBUaGUgem9vbSBkZWx0YSBhcHBsaWVkIG9uIGVhY2ggZG91YmxlIGNsaWNrLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWxsb3dzIHRoZSB1c2VyIHRvIHpvb20gYnkgZG91YmxlLWNsaWNraW5nIG9uIHRoZSBtYXAuXG4gKiBAYXBpXG4gKi9cblxudmFyIERvdWJsZUNsaWNrWm9vbSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEb3VibGVDbGlja1pvb20sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIERvdWJsZUNsaWNrWm9vbShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWx0YV8gPSBvcHRpb25zLmRlbHRhID8gb3B0aW9ucy5kZWx0YSA6IDE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDI1MDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50IG1hcCBicm93c2VyIGV2ZW50fSAoaWYgaXQgd2FzIGFcbiAgICogZG91YmxlY2xpY2spIGFuZCBldmVudHVhbGx5IHpvb21zIHRoZSBtYXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYGZhbHNlYCB0byBzdG9wIGV2ZW50IHByb3BhZ2F0aW9uLlxuICAgKi9cblxuXG4gIERvdWJsZUNsaWNrWm9vbS5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIHN0b3BFdmVudCA9IGZhbHNlO1xuXG4gICAgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuREJMQ0xJQ0spIHtcbiAgICAgIHZhciBicm93c2VyRXZlbnQgPVxuICAgICAgLyoqIEB0eXBlIHtNb3VzZUV2ZW50fSAqL1xuICAgICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIHZhciBhbmNob3IgPSBtYXBCcm93c2VyRXZlbnQuY29vcmRpbmF0ZTtcbiAgICAgIHZhciBkZWx0YSA9IGJyb3dzZXJFdmVudC5zaGlmdEtleSA/IC10aGlzLmRlbHRhXyA6IHRoaXMuZGVsdGFfO1xuICAgICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuICAgICAgem9vbUJ5RGVsdGEodmlldywgZGVsdGEsIGFuY2hvciwgdGhpcy5kdXJhdGlvbl8pO1xuICAgICAgYnJvd3NlckV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBzdG9wRXZlbnQgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiAhc3RvcEV2ZW50O1xuICB9O1xuXG4gIHJldHVybiBEb3VibGVDbGlja1pvb207XG59KEludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgRG91YmxlQ2xpY2tab29tOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vUG9pbnRlclxuICovXG5cblxuaW1wb3J0IEludGVyYWN0aW9uIGZyb20gJy4vSW50ZXJhY3Rpb24uanMnO1xuaW1wb3J0IE1hcEJyb3dzZXJFdmVudFR5cGUgZnJvbSAnLi4vTWFwQnJvd3NlckV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBnZXRWYWx1ZXMgfSBmcm9tICcuLi9vYmouanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTpib29sZWFufSBbaGFuZGxlRG93bkV2ZW50XVxuICogRnVuY3Rpb24gaGFuZGxpbmcgXCJkb3duXCIgZXZlbnRzLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBgdHJ1ZWAgdGhlbiBhIGRyYWdcbiAqIHNlcXVlbmNlIGlzIHN0YXJ0ZWQuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTp2b2lkfSBbaGFuZGxlRHJhZ0V2ZW50XVxuICogRnVuY3Rpb24gaGFuZGxpbmcgXCJkcmFnXCIgZXZlbnRzLiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbiBcIm1vdmVcIiBldmVudHNcbiAqIGR1cmluZyBhIGRyYWcgc2VxdWVuY2UuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTpib29sZWFufSBbaGFuZGxlRXZlbnRdXG4gKiBNZXRob2QgY2FsbGVkIGJ5IHRoZSBtYXAgdG8gbm90aWZ5IHRoZSBpbnRlcmFjdGlvbiB0aGF0IGEgYnJvd3NlciBldmVudCB3YXNcbiAqIGRpc3BhdGNoZWQgdG8gdGhlIG1hcC4gVGhlIGZ1bmN0aW9uIG1heSByZXR1cm4gYGZhbHNlYCB0byBwcmV2ZW50IHRoZVxuICogcHJvcGFnYXRpb24gb2YgdGhlIGV2ZW50IHRvIG90aGVyIGludGVyYWN0aW9ucyBpbiB0aGUgbWFwJ3MgaW50ZXJhY3Rpb25zXG4gKiBjaGFpbi5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOnZvaWR9IFtoYW5kbGVNb3ZlRXZlbnRdXG4gKiBGdW5jdGlvbiBoYW5kbGluZyBcIm1vdmVcIiBldmVudHMuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIFwibW92ZVwiIGV2ZW50cy5cbiAqIFRoaXMgZnVuY3Rpb25zIGlzIGFsc28gY2FsbGVkIGR1cmluZyBhIGRyYWcgc2VxdWVuY2UsIHNvIGR1cmluZyBhIGRyYWdcbiAqIHNlcXVlbmNlIGJvdGggdGhlIGBoYW5kbGVEcmFnRXZlbnRgIGZ1bmN0aW9uIGFuZCB0aGlzIGZ1bmN0aW9uIGFyZSBjYWxsZWQuXG4gKiBJZiBgaGFuZGxlRG93bkV2ZW50YCBpcyBkZWZpbmVkIGFuZCBpdCByZXR1cm5zIHRydWUgdGhpcyBmdW5jdGlvbiB3aWxsIG5vdFxuICogYmUgY2FsbGVkIGR1cmluZyBhIGRyYWcgc2VxdWVuY2UuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTpib29sZWFufSBbaGFuZGxlVXBFdmVudF1cbiAqICBGdW5jdGlvbiBoYW5kbGluZyBcInVwXCIgZXZlbnRzLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBgZmFsc2VgIHRoZW4gdGhlXG4gKiBjdXJyZW50IGRyYWcgc2VxdWVuY2UgaXMgc3RvcHBlZC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oYm9vbGVhbik6Ym9vbGVhbn0gW3N0b3BEb3duXVxuICogU2hvdWxkIHRoZSBkb3duIGV2ZW50IGJlIHByb3BhZ2F0ZWQgdG8gb3RoZXIgaW50ZXJhY3Rpb25zLCBvciBzaG91bGQgYmVcbiAqIHN0b3BwZWQ/XG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBCYXNlIGNsYXNzIHRoYXQgY2FsbHMgdXNlci1kZWZpbmVkIGZ1bmN0aW9ucyBvbiBgZG93bmAsIGBtb3ZlYCBhbmQgYHVwYFxuICogZXZlbnRzLiBUaGlzIGNsYXNzIGFsc28gbWFuYWdlcyBcImRyYWcgc2VxdWVuY2VzXCIuXG4gKlxuICogV2hlbiB0aGUgYGhhbmRsZURvd25FdmVudGAgdXNlciBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYCBhIGRyYWcgc2VxdWVuY2UgaXNcbiAqIHN0YXJ0ZWQuIER1cmluZyBhIGRyYWcgc2VxdWVuY2UgdGhlIGBoYW5kbGVEcmFnRXZlbnRgIHVzZXIgZnVuY3Rpb24gaXNcbiAqIGNhbGxlZCBvbiBgbW92ZWAgZXZlbnRzLiBUaGUgZHJhZyBzZXF1ZW5jZSBlbmRzIHdoZW4gdGhlIGBoYW5kbGVVcEV2ZW50YFxuICogdXNlciBmdW5jdGlvbiBpcyBjYWxsZWQgYW5kIHJldHVybnMgYGZhbHNlYC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgUG9pbnRlckludGVyYWN0aW9uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFBvaW50ZXJJbnRlcmFjdGlvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUG9pbnRlckludGVyYWN0aW9uKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcyxcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vSW50ZXJhY3Rpb24uanNcIikuSW50ZXJhY3Rpb25PcHRpb25zfSAqL1xuICAgIG9wdGlvbnMpIHx8IHRoaXM7XG5cbiAgICBpZiAob3B0aW9ucy5oYW5kbGVEb3duRXZlbnQpIHtcbiAgICAgIF90aGlzLmhhbmRsZURvd25FdmVudCA9IG9wdGlvbnMuaGFuZGxlRG93bkV2ZW50O1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmhhbmRsZURyYWdFdmVudCkge1xuICAgICAgX3RoaXMuaGFuZGxlRHJhZ0V2ZW50ID0gb3B0aW9ucy5oYW5kbGVEcmFnRXZlbnQ7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuaGFuZGxlTW92ZUV2ZW50KSB7XG4gICAgICBfdGhpcy5oYW5kbGVNb3ZlRXZlbnQgPSBvcHRpb25zLmhhbmRsZU1vdmVFdmVudDtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5oYW5kbGVVcEV2ZW50KSB7XG4gICAgICBfdGhpcy5oYW5kbGVVcEV2ZW50ID0gb3B0aW9ucy5oYW5kbGVVcEV2ZW50O1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnN0b3BEb3duKSB7XG4gICAgICBfdGhpcy5zdG9wRG93biA9IG9wdGlvbnMuc3RvcERvd247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuaGFuZGxpbmdEb3duVXBTZXF1ZW5jZSA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgUG9pbnRlckV2ZW50Pn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhY2tlZFBvaW50ZXJzXyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxQb2ludGVyRXZlbnQ+fVxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKi9cblxuICAgIF90aGlzLnRhcmdldFBvaW50ZXJzID0gW107XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IG51bWJlciBvZiBwb2ludGVycyBpbnZvbHZlZCBpbiB0aGUgaW50ZXJhY3Rpb24sXG4gICAqIGUuZy4gYDJgIHdoZW4gdHdvIGZpbmdlcnMgYXJlIHVzZWQuXG4gICAqIEByZXR1cm4ge251bWJlcn0gVGhlIG51bWJlciBvZiBwb2ludGVycy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFBvaW50ZXJJbnRlcmFjdGlvbi5wcm90b3R5cGUuZ2V0UG9pbnRlckNvdW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aDtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRvd24gZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZURvd25FdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkcmFnIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgUG9pbnRlckludGVyYWN0aW9uLnByb3RvdHlwZS5oYW5kbGVEcmFnRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7fTtcbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50IG1hcCBicm93c2VyIGV2ZW50fSBhbmQgbWF5IGNhbGwgaW50b1xuICAgKiBvdGhlciBmdW5jdGlvbnMsIGlmIGV2ZW50IHNlcXVlbmNlcyBsaWtlIGUuZy4gJ2RyYWcnIG9yICdkb3duLXVwJyBldGMuIGFyZVxuICAgKiBkZXRlY3RlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgZmFsc2VgIHRvIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICghbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBzdG9wRXZlbnQgPSBmYWxzZTtcbiAgICB0aGlzLnVwZGF0ZVRyYWNrZWRQb2ludGVyc18obWFwQnJvd3NlckV2ZW50KTtcblxuICAgIGlmICh0aGlzLmhhbmRsaW5nRG93blVwU2VxdWVuY2UpIHtcbiAgICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJEUkFHKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlRHJhZ0V2ZW50KG1hcEJyb3dzZXJFdmVudCk7IC8vIHByZXZlbnQgcGFnZSBzY3JvbGxpbmcgZHVyaW5nIGRyYWdnaW5nXG5cbiAgICAgICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSBpZiAobWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSVVApIHtcbiAgICAgICAgdmFyIGhhbmRsZWRVcCA9IHRoaXMuaGFuZGxlVXBFdmVudChtYXBCcm93c2VyRXZlbnQpO1xuICAgICAgICB0aGlzLmhhbmRsaW5nRG93blVwU2VxdWVuY2UgPSBoYW5kbGVkVXAgJiYgdGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPiAwO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRE9XTikge1xuICAgICAgICB2YXIgaGFuZGxlZCA9IHRoaXMuaGFuZGxlRG93bkV2ZW50KG1hcEJyb3dzZXJFdmVudCk7XG4gICAgICAgIHRoaXMuaGFuZGxpbmdEb3duVXBTZXF1ZW5jZSA9IGhhbmRsZWQ7XG4gICAgICAgIHN0b3BFdmVudCA9IHRoaXMuc3RvcERvd24oaGFuZGxlZCk7XG4gICAgICB9IGVsc2UgaWYgKG1hcEJyb3dzZXJFdmVudC50eXBlID09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUk1PVkUpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVNb3ZlRXZlbnQobWFwQnJvd3NlckV2ZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gIXN0b3BFdmVudDtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIG1vdmUgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZU1vdmVFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHt9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLmhhbmRsZVVwRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGRldGVybWluZSBpZiBcImRvd25cIiBldmVudHMgc2hvdWxkIGJlIHByb3BhZ2F0ZWRcbiAgICogdG8gb3RoZXIgaW50ZXJhY3Rpb25zIG9yIHNob3VsZCBiZSBzdG9wcGVkLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGhhbmRsZWQgV2FzIHRoZSBldmVudCBoYW5kbGVkIGJ5IHRoZSBpbnRlcmFjdGlvbj9cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gU2hvdWxkIHRoZSBgZG93bmAgZXZlbnQgYmUgc3RvcHBlZD9cbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLnN0b3BEb3duID0gZnVuY3Rpb24gKGhhbmRsZWQpIHtcbiAgICByZXR1cm4gaGFuZGxlZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBQb2ludGVySW50ZXJhY3Rpb24ucHJvdG90eXBlLnVwZGF0ZVRyYWNrZWRQb2ludGVyc18gPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKGlzUG9pbnRlckRyYWdnaW5nRXZlbnQobWFwQnJvd3NlckV2ZW50KSkge1xuICAgICAgdmFyIGV2ZW50XzEgPSBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICAgIHZhciBpZCA9IGV2ZW50XzEucG9pbnRlcklkLnRvU3RyaW5nKCk7XG5cbiAgICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUCkge1xuICAgICAgICBkZWxldGUgdGhpcy50cmFja2VkUG9pbnRlcnNfW2lkXTtcbiAgICAgIH0gZWxzZSBpZiAobWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRE9XTikge1xuICAgICAgICB0aGlzLnRyYWNrZWRQb2ludGVyc19baWRdID0gZXZlbnRfMTtcbiAgICAgIH0gZWxzZSBpZiAoaWQgaW4gdGhpcy50cmFja2VkUG9pbnRlcnNfKSB7XG4gICAgICAgIC8vIHVwZGF0ZSBvbmx5IHdoZW4gdGhlcmUgd2FzIGEgcG9pbnRlcmRvd24gZXZlbnQgZm9yIHRoaXMgcG9pbnRlclxuICAgICAgICB0aGlzLnRyYWNrZWRQb2ludGVyc19baWRdID0gZXZlbnRfMTtcbiAgICAgIH1cblxuICAgICAgdGhpcy50YXJnZXRQb2ludGVycyA9IGdldFZhbHVlcyh0aGlzLnRyYWNrZWRQb2ludGVyc18pO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gUG9pbnRlckludGVyYWN0aW9uO1xufShJbnRlcmFjdGlvbik7XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnRlckV2ZW50Pn0gcG9pbnRlckV2ZW50cyBMaXN0IG9mIGV2ZW50cy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBDZW50cm9pZCBwaXhlbC5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjZW50cm9pZChwb2ludGVyRXZlbnRzKSB7XG4gIHZhciBsZW5ndGggPSBwb2ludGVyRXZlbnRzLmxlbmd0aDtcbiAgdmFyIGNsaWVudFggPSAwO1xuICB2YXIgY2xpZW50WSA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGNsaWVudFggKz0gcG9pbnRlckV2ZW50c1tpXS5jbGllbnRYO1xuICAgIGNsaWVudFkgKz0gcG9pbnRlckV2ZW50c1tpXS5jbGllbnRZO1xuICB9XG5cbiAgcmV0dXJuIFtjbGllbnRYIC8gbGVuZ3RoLCBjbGllbnRZIC8gbGVuZ3RoXTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gV2hldGhlciB0aGUgZXZlbnQgaXMgYSBwb2ludGVyZG93biwgcG9pbnRlcmRyYWdcbiAqICAgICBvciBwb2ludGVydXAgZXZlbnQuXG4gKi9cblxuZnVuY3Rpb24gaXNQb2ludGVyRHJhZ2dpbmdFdmVudChtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIHR5cGUgPSBtYXBCcm93c2VyRXZlbnQudHlwZTtcbiAgcmV0dXJuIHR5cGUgPT09IE1hcEJyb3dzZXJFdmVudFR5cGUuUE9JTlRFUkRPV04gfHwgdHlwZSA9PT0gTWFwQnJvd3NlckV2ZW50VHlwZS5QT0lOVEVSRFJBRyB8fCB0eXBlID09PSBNYXBCcm93c2VyRXZlbnRUeXBlLlBPSU5URVJVUDtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUG9pbnRlckludGVyYWN0aW9uOyIsIi8qKlxuICogQG1vZHVsZSBvbC9ldmVudHMvY29uZGl0aW9uXG4gKi9cbmltcG9ydCBNYXBCcm93c2VyRXZlbnRUeXBlIGZyb20gJy4uL01hcEJyb3dzZXJFdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgRkFMU0UsIFRSVUUgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgTUFDLCBXRUJLSVQgfSBmcm9tICcuLi9oYXMuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYVxuICogYHtib29sZWFufWAuIElmIHRoZSBjb25kaXRpb24gaXMgbWV0LCB0cnVlIHNob3VsZCBiZSByZXR1cm5lZC5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24odGhpczogPywgaW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHQpOiBib29sZWFufSBDb25kaXRpb25cbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjb25kaXRpb24gZnVuY3Rpb24gdGhhdCBwYXNzZXMgd2hlbiBhbGwgcHJvdmlkZWQgY29uZGl0aW9ucyBwYXNzLlxuICogQHBhcmFtIHsuLi5Db25kaXRpb259IHZhcl9hcmdzIENvbmRpdGlvbnMgdG8gY2hlY2suXG4gKiBAcmV0dXJuIHtDb25kaXRpb259IENvbmRpdGlvbiBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWxsKHZhcl9hcmdzKSB7XG4gIHZhciBjb25kaXRpb25zID0gYXJndW1lbnRzO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEFsbCBjb25kaXRpb25zIHBhc3NlZC5cbiAgICovXG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciBwYXNzID0gdHJ1ZTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvbmRpdGlvbnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgcGFzcyA9IHBhc3MgJiYgY29uZGl0aW9uc1tpXShldmVudCk7XG5cbiAgICAgIGlmICghcGFzcykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFzcztcbiAgfTtcbn1cbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiBvbmx5IHRoZSBhbHQta2V5IGlzIHByZXNzZWQsIGBmYWxzZWAgb3RoZXJ3aXNlIChlLmcuIHdoZW5cbiAqIGFkZGl0aW9uYWxseSB0aGUgc2hpZnQta2V5IGlzIHByZXNzZWQpLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgb25seSB0aGUgYWx0IGtleSBpcyBwcmVzc2VkLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgYWx0S2V5T25seSA9IGZ1bmN0aW9uIGFsdEtleU9ubHkobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBvcmlnaW5hbEV2ZW50ID1cbiAgLyoqIEB0eXBlIHtLZXlib2FyZEV2ZW50fE1vdXNlRXZlbnR8VG91Y2hFdmVudH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIHJldHVybiBvcmlnaW5hbEV2ZW50LmFsdEtleSAmJiAhKG9yaWdpbmFsRXZlbnQubWV0YUtleSB8fCBvcmlnaW5hbEV2ZW50LmN0cmxLZXkpICYmICFvcmlnaW5hbEV2ZW50LnNoaWZ0S2V5O1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiBvbmx5IHRoZSBhbHQta2V5IGFuZCBzaGlmdC1rZXkgaXMgcHJlc3NlZCwgYGZhbHNlYCBvdGhlcndpc2VcbiAqIChlLmcuIHdoZW4gYWRkaXRpb25hbGx5IHRoZSBwbGF0Zm9ybS1tb2RpZmllci1rZXkgaXMgcHJlc3NlZCkuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBvbmx5IHRoZSBhbHQgYW5kIHNoaWZ0IGtleXMgYXJlIHByZXNzZWQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBhbHRTaGlmdEtleXNPbmx5ID0gZnVuY3Rpb24gYWx0U2hpZnRLZXlzT25seShtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPVxuICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR8TW91c2VFdmVudHxUb3VjaEV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgcmV0dXJuIG9yaWdpbmFsRXZlbnQuYWx0S2V5ICYmICEob3JpZ2luYWxFdmVudC5tZXRhS2V5IHx8IG9yaWdpbmFsRXZlbnQuY3RybEtleSkgJiYgb3JpZ2luYWxFdmVudC5zaGlmdEtleTtcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIG1hcCBoYXMgdGhlIGZvY3VzLiBUaGlzIGNvbmRpdGlvbiByZXF1aXJlcyBhIG1hcCB0YXJnZXRcbiAqIGVsZW1lbnQgd2l0aCBhIGB0YWJpbmRleGAgYXR0cmlidXRlLCBlLmcuIGA8ZGl2IGlkPVwibWFwXCIgdGFiaW5kZXg9XCIxXCI+YC5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBtYXAgaGFzIHRoZSBmb2N1cy5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIGZvY3VzID0gZnVuY3Rpb24gZm9jdXMoZXZlbnQpIHtcbiAgcmV0dXJuIGV2ZW50LnRhcmdldC5nZXRUYXJnZXRFbGVtZW50KCkuY29udGFpbnMoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCk7XG59O1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBtYXAgaGFzIHRoZSBmb2N1cyBvciBubyAndGFiaW5kZXgnIGF0dHJpYnV0ZSBzZXQuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gZXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgbWFwIGNvbnRhaW5lciBoYXMgdGhlIGZvY3VzIG9yIG5vICd0YWJpbmRleCcgYXR0cmlidXRlLlxuICovXG5cbmV4cG9ydCB2YXIgZm9jdXNXaXRoVGFiaW5kZXggPSBmdW5jdGlvbiBmb2N1c1dpdGhUYWJpbmRleChldmVudCkge1xuICByZXR1cm4gZXZlbnQubWFwLmdldFRhcmdldEVsZW1lbnQoKS5oYXNBdHRyaWJ1dGUoJ3RhYmluZGV4JykgPyBmb2N1cyhldmVudCkgOiB0cnVlO1xufTtcbi8qKlxuICogUmV0dXJuIGFsd2F5cyB0cnVlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBhbHdheXMgPSBUUlVFO1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBldmVudCBpcyBhIGBjbGlja2AgZXZlbnQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IGlzIGEgbWFwIGBjbGlja2AgZXZlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBjbGljayA9IGZ1bmN0aW9uIGNsaWNrKG1hcEJyb3dzZXJFdmVudCkge1xuICByZXR1cm4gbWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5DTElDSztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IGhhcyBhbiBcImFjdGlvblwiLXByb2R1Y2luZyBtb3VzZSBidXR0b24uXG4gKlxuICogQnkgZGVmaW5pdGlvbiwgdGhpcyBpbmNsdWRlcyBsZWZ0LWNsaWNrIG9uIHdpbmRvd3MvbGludXgsIGFuZCBsZWZ0LWNsaWNrXG4gKiB3aXRob3V0IHRoZSBjdHJsIGtleSBvbiBNYWNzLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSByZXN1bHQuXG4gKi9cblxuZXhwb3J0IHZhciBtb3VzZUFjdGlvbkJ1dHRvbiA9IGZ1bmN0aW9uIG1vdXNlQWN0aW9uQnV0dG9uKG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gIC8qKiBAdHlwZSB7TW91c2VFdmVudH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIHJldHVybiBvcmlnaW5hbEV2ZW50LmJ1dHRvbiA9PSAwICYmICEoV0VCS0lUICYmIE1BQyAmJiBvcmlnaW5hbEV2ZW50LmN0cmxLZXkpO1xufTtcbi8qKlxuICogUmV0dXJuIGFsd2F5cyBmYWxzZS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBGYWxzZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIG5ldmVyID0gRkFMU0U7XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGJyb3dzZXIgZXZlbnQgaXMgYSBgcG9pbnRlcm1vdmVgIGV2ZW50LCBgZmFsc2VgXG4gKiBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgYnJvd3NlciBldmVudCBpcyBhIGBwb2ludGVybW92ZWAgZXZlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBwb2ludGVyTW92ZSA9IGZ1bmN0aW9uIHBvaW50ZXJNb3ZlKG1hcEJyb3dzZXJFdmVudCkge1xuICByZXR1cm4gbWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gJ3BvaW50ZXJtb3ZlJztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IGlzIGEgbWFwIGBzaW5nbGVjbGlja2AgZXZlbnQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IGlzIGEgbWFwIGBzaW5nbGVjbGlja2AgZXZlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBzaW5nbGVDbGljayA9IGZ1bmN0aW9uIHNpbmdsZUNsaWNrKG1hcEJyb3dzZXJFdmVudCkge1xuICByZXR1cm4gbWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5TSU5HTEVDTElDSztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IGlzIGEgbWFwIGBkYmxjbGlja2AgZXZlbnQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IGlzIGEgbWFwIGBkYmxjbGlja2AgZXZlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHZhciBkb3VibGVDbGljayA9IGZ1bmN0aW9uIGRvdWJsZUNsaWNrKG1hcEJyb3dzZXJFdmVudCkge1xuICByZXR1cm4gbWFwQnJvd3NlckV2ZW50LnR5cGUgPT0gTWFwQnJvd3NlckV2ZW50VHlwZS5EQkxDTElDSztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgbm8gbW9kaWZpZXIga2V5IChhbHQtLCBzaGlmdC0gb3IgcGxhdGZvcm0tbW9kaWZpZXIta2V5KSBpc1xuICogcHJlc3NlZC5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIG9ubHkgaWYgdGhlcmUgbm8gbW9kaWZpZXIga2V5cyBhcmUgcHJlc3NlZC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIG5vTW9kaWZpZXJLZXlzID0gZnVuY3Rpb24gbm9Nb2RpZmllcktleXMobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBvcmlnaW5hbEV2ZW50ID1cbiAgLyoqIEB0eXBlIHtLZXlib2FyZEV2ZW50fE1vdXNlRXZlbnR8VG91Y2hFdmVudH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIHJldHVybiAhb3JpZ2luYWxFdmVudC5hbHRLZXkgJiYgIShvcmlnaW5hbEV2ZW50Lm1ldGFLZXkgfHwgb3JpZ2luYWxFdmVudC5jdHJsS2V5KSAmJiAhb3JpZ2luYWxFdmVudC5zaGlmdEtleTtcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgb25seSB0aGUgcGxhdGZvcm0tbW9kaWZpZXIta2V5ICh0aGUgbWV0YS1rZXkgb24gTWFjLFxuICogY3RybC1rZXkgb3RoZXJ3aXNlKSBpcyBwcmVzc2VkLCBgZmFsc2VgIG90aGVyd2lzZSAoZS5nLiB3aGVuIGFkZGl0aW9uYWxseVxuICogdGhlIHNoaWZ0LWtleSBpcyBwcmVzc2VkKS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG9ubHkgdGhlIHBsYXRmb3JtIG1vZGlmaWVyIGtleSBpcyBwcmVzc2VkLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgcGxhdGZvcm1Nb2RpZmllcktleU9ubHkgPSBmdW5jdGlvbiBwbGF0Zm9ybU1vZGlmaWVyS2V5T25seShtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPVxuICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR8TW91c2VFdmVudHxUb3VjaEV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgcmV0dXJuICFvcmlnaW5hbEV2ZW50LmFsdEtleSAmJiAoTUFDID8gb3JpZ2luYWxFdmVudC5tZXRhS2V5IDogb3JpZ2luYWxFdmVudC5jdHJsS2V5KSAmJiAhb3JpZ2luYWxFdmVudC5zaGlmdEtleTtcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgb25seSB0aGUgc2hpZnQta2V5IGlzIHByZXNzZWQsIGBmYWxzZWAgb3RoZXJ3aXNlIChlLmcuIHdoZW5cbiAqIGFkZGl0aW9uYWxseSB0aGUgYWx0LWtleSBpcyBwcmVzc2VkKS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG9ubHkgdGhlIHNoaWZ0IGtleSBpcyBwcmVzc2VkLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgc2hpZnRLZXlPbmx5ID0gZnVuY3Rpb24gc2hpZnRLZXlPbmx5KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9XG4gIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudHxNb3VzZUV2ZW50fFRvdWNoRXZlbnR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICByZXR1cm4gIW9yaWdpbmFsRXZlbnQuYWx0S2V5ICYmICEob3JpZ2luYWxFdmVudC5tZXRhS2V5IHx8IG9yaWdpbmFsRXZlbnQuY3RybEtleSkgJiYgb3JpZ2luYWxFdmVudC5zaGlmdEtleTtcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIG5vdCBlZGl0YWJsZSwgaS5lLiBub3QgYSBgPGlucHV0PmAtLFxuICogYDxzZWxlY3Q+YC0gb3IgYDx0ZXh0YXJlYT5gLWVsZW1lbnQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgb25seSBpZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgbm90IGVkaXRhYmxlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgdGFyZ2V0Tm90RWRpdGFibGUgPSBmdW5jdGlvbiB0YXJnZXROb3RFZGl0YWJsZShtYXBCcm93c2VyRXZlbnQpIHtcbiAgdmFyIG9yaWdpbmFsRXZlbnQgPVxuICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR8TW91c2VFdmVudHxUb3VjaEV2ZW50fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgdmFyIHRhZ05hbWUgPVxuICAvKiogQHR5cGUge0VsZW1lbnR9ICovXG4gIG9yaWdpbmFsRXZlbnQudGFyZ2V0LnRhZ05hbWU7XG4gIHJldHVybiB0YWdOYW1lICE9PSAnSU5QVVQnICYmIHRhZ05hbWUgIT09ICdTRUxFQ1QnICYmIHRhZ05hbWUgIT09ICdURVhUQVJFQSc7XG59O1xuLyoqXG4gKiBSZXR1cm4gYHRydWVgIGlmIHRoZSBldmVudCBvcmlnaW5hdGVzIGZyb20gYSBtb3VzZSBkZXZpY2UuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgbW91c2UgZGV2aWNlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgbW91c2VPbmx5ID0gZnVuY3Rpb24gbW91c2VPbmx5KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgcG9pbnRlckV2ZW50ID1cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnRcIikuZGVmYXVsdH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIGFzc2VydChwb2ludGVyRXZlbnQgIT09IHVuZGVmaW5lZCwgNTYpOyAvLyBtYXBCcm93c2VyRXZlbnQgbXVzdCBvcmlnaW5hdGUgZnJvbSBhIHBvaW50ZXIgZXZlbnRcbiAgLy8gc2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3BvaW50ZXJldmVudHMvI3dpZGwtUG9pbnRlckV2ZW50LXBvaW50ZXJUeXBlXG5cbiAgcmV0dXJuIHBvaW50ZXJFdmVudC5wb2ludGVyVHlwZSA9PSAnbW91c2UnO1xufTtcbi8qKlxuICogUmV0dXJuIGB0cnVlYCBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgdG91Y2hhYmxlIGRldmljZS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBldmVudCBvcmlnaW5hdGVzIGZyb20gYSB0b3VjaGFibGUgZGV2aWNlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgdG91Y2hPbmx5ID0gZnVuY3Rpb24gdG91Y2hPbmx5KG1hcEJyb3dzZXJFdmVudCkge1xuICB2YXIgcG9pbnRlckV2dCA9XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50XCIpLmRlZmF1bHR9ICovXG4gIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICBhc3NlcnQocG9pbnRlckV2dCAhPT0gdW5kZWZpbmVkLCA1Nik7IC8vIG1hcEJyb3dzZXJFdmVudCBtdXN0IG9yaWdpbmF0ZSBmcm9tIGEgcG9pbnRlciBldmVudFxuICAvLyBzZWUgaHR0cDovL3d3dy53My5vcmcvVFIvcG9pbnRlcmV2ZW50cy8jd2lkbC1Qb2ludGVyRXZlbnQtcG9pbnRlclR5cGVcblxuICByZXR1cm4gcG9pbnRlckV2dC5wb2ludGVyVHlwZSA9PT0gJ3RvdWNoJztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIGRpZ2l0YWwgcGVuLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIGRpZ2l0YWwgcGVuLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgcGVuT25seSA9IGZ1bmN0aW9uIHBlbk9ubHkobWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBwb2ludGVyRXZ0ID1cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnRcIikuZGVmYXVsdH0gKi9cbiAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gIGFzc2VydChwb2ludGVyRXZ0ICE9PSB1bmRlZmluZWQsIDU2KTsgLy8gbWFwQnJvd3NlckV2ZW50IG11c3Qgb3JpZ2luYXRlIGZyb20gYSBwb2ludGVyIGV2ZW50XG4gIC8vIHNlZSBodHRwOi8vd3d3LnczLm9yZy9UUi9wb2ludGVyZXZlbnRzLyN3aWRsLVBvaW50ZXJFdmVudC1wb2ludGVyVHlwZVxuXG4gIHJldHVybiBwb2ludGVyRXZ0LnBvaW50ZXJUeXBlID09PSAncGVuJztcbn07XG4vKipcbiAqIFJldHVybiBgdHJ1ZWAgaWYgdGhlIGV2ZW50IG9yaWdpbmF0ZXMgZnJvbSBhIHByaW1hcnkgcG9pbnRlciBpblxuICogY29udGFjdCB3aXRoIHRoZSBzdXJmYWNlIG9yIGlmIHRoZSBsZWZ0IG1vdXNlIGJ1dHRvbiBpcyBwcmVzc2VkLlxuICogU2VlIGh0dHA6Ly93d3cudzMub3JnL1RSL3BvaW50ZXJldmVudHMvI2J1dHRvbi1zdGF0ZXMuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IE1hcCBicm93c2VyIGV2ZW50LlxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgZXZlbnQgb3JpZ2luYXRlcyBmcm9tIGEgcHJpbWFyeSBwb2ludGVyLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCB2YXIgcHJpbWFyeUFjdGlvbiA9IGZ1bmN0aW9uIHByaW1hcnlBY3Rpb24obWFwQnJvd3NlckV2ZW50KSB7XG4gIHZhciBwb2ludGVyRXZlbnQgPVxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudFwiKS5kZWZhdWx0fSAqL1xuICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgYXNzZXJ0KHBvaW50ZXJFdmVudCAhPT0gdW5kZWZpbmVkLCA1Nik7IC8vIG1hcEJyb3dzZXJFdmVudCBtdXN0IG9yaWdpbmF0ZSBmcm9tIGEgcG9pbnRlciBldmVudFxuXG4gIHJldHVybiBwb2ludGVyRXZlbnQuaXNQcmltYXJ5ICYmIHBvaW50ZXJFdmVudC5idXR0b24gPT09IDA7XG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vRHJhZ1BhblxuICovXG5cblxuaW1wb3J0IFBvaW50ZXJJbnRlcmFjdGlvbiwgeyBjZW50cm9pZCBhcyBjZW50cm9pZEZyb21Qb2ludGVycyB9IGZyb20gJy4vUG9pbnRlci5qcyc7XG5pbXBvcnQgeyBGQUxTRSB9IGZyb20gJy4uL2Z1bmN0aW9ucy5qcyc7XG5pbXBvcnQgeyBhbGwsIGZvY3VzV2l0aFRhYmluZGV4LCBub01vZGlmaWVyS2V5cywgcHJpbWFyeUFjdGlvbiB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuaW1wb3J0IHsgZWFzZU91dCB9IGZyb20gJy4uL2Vhc2luZy5qcyc7XG5pbXBvcnQgeyByb3RhdGUgYXMgcm90YXRlQ29vcmRpbmF0ZSwgc2NhbGUgYXMgc2NhbGVDb29yZGluYXRlIH0gZnJvbSAnLi4vY29vcmRpbmF0ZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259IFtjb25kaXRpb25dIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9IGFuZCByZXR1cm5zIGEgYm9vbGVhblxuICogdG8gaW5kaWNhdGUgd2hldGhlciB0aGF0IGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkLlxuICogRGVmYXVsdCBpcyB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+bm9Nb2RpZmllcktleXN9IGFuZCB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+cHJpbWFyeUFjdGlvbn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvbkZvY3VzT25seT1mYWxzZV0gV2hlbiB0aGUgbWFwJ3MgdGFyZ2V0IGhhcyBhIGB0YWJpbmRleGAgYXR0cmlidXRlIHNldCxcbiAqIHRoZSBpbnRlcmFjdGlvbiB3aWxsIG9ubHkgaGFuZGxlIGV2ZW50cyB3aGVuIHRoZSBtYXAgaGFzIHRoZSBmb2N1cy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vS2luZXRpYy5qc1wiKS5kZWZhdWx0fSBba2luZXRpY10gS2luZXRpYyBpbmVydGlhIHRvIGFwcGx5IHRvIHRoZSBwYW4uXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gcGFuIHRoZSBtYXAgYnkgZHJhZ2dpbmcgdGhlIG1hcC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgRHJhZ1BhbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEcmFnUGFuLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBEcmFnUGFuKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgc3RvcERvd246IEZBTFNFXG4gICAgfSkgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL0tpbmV0aWMuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5raW5ldGljXyA9IG9wdGlvbnMua2luZXRpYztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0Q2VudHJvaWQgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0UG9pbnRlcnNDb3VudF87XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5wYW5uaW5nXyA9IGZhbHNlO1xuICAgIHZhciBjb25kaXRpb24gPSBvcHRpb25zLmNvbmRpdGlvbiA/IG9wdGlvbnMuY29uZGl0aW9uIDogYWxsKG5vTW9kaWZpZXJLZXlzLCBwcmltYXJ5QWN0aW9uKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbmRpdGlvbl8gPSBvcHRpb25zLm9uRm9jdXNPbmx5ID8gYWxsKGZvY3VzV2l0aFRhYmluZGV4LCBjb25kaXRpb24pIDogY29uZGl0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5ub0tpbmV0aWNfID0gZmFsc2U7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkcmFnIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKi9cblxuXG4gIERyYWdQYW4ucHJvdG90eXBlLmhhbmRsZURyYWdFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMucGFubmluZ18pIHtcbiAgICAgIHRoaXMucGFubmluZ18gPSB0cnVlO1xuICAgICAgdGhpcy5nZXRNYXAoKS5nZXRWaWV3KCkuYmVnaW5JbnRlcmFjdGlvbigpO1xuICAgIH1cblxuICAgIHZhciB0YXJnZXRQb2ludGVycyA9IHRoaXMudGFyZ2V0UG9pbnRlcnM7XG4gICAgdmFyIGNlbnRyb2lkID0gY2VudHJvaWRGcm9tUG9pbnRlcnModGFyZ2V0UG9pbnRlcnMpO1xuXG4gICAgaWYgKHRhcmdldFBvaW50ZXJzLmxlbmd0aCA9PSB0aGlzLmxhc3RQb2ludGVyc0NvdW50Xykge1xuICAgICAgaWYgKHRoaXMua2luZXRpY18pIHtcbiAgICAgICAgdGhpcy5raW5ldGljXy51cGRhdGUoY2VudHJvaWRbMF0sIGNlbnRyb2lkWzFdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubGFzdENlbnRyb2lkKSB7XG4gICAgICAgIHZhciBkZWx0YSA9IFt0aGlzLmxhc3RDZW50cm9pZFswXSAtIGNlbnRyb2lkWzBdLCBjZW50cm9pZFsxXSAtIHRoaXMubGFzdENlbnRyb2lkWzFdXTtcbiAgICAgICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcbiAgICAgICAgc2NhbGVDb29yZGluYXRlKGRlbHRhLCB2aWV3LmdldFJlc29sdXRpb24oKSk7XG4gICAgICAgIHJvdGF0ZUNvb3JkaW5hdGUoZGVsdGEsIHZpZXcuZ2V0Um90YXRpb24oKSk7XG4gICAgICAgIHZpZXcuYWRqdXN0Q2VudGVySW50ZXJuYWwoZGVsdGEpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5raW5ldGljXykge1xuICAgICAgLy8gcmVzZXQgc28gd2UgZG9uJ3Qgb3ZlcmVzdGltYXRlIHRoZSBraW5ldGljIGVuZXJneSBhZnRlclxuICAgICAgLy8gYWZ0ZXIgb25lIGZpbmdlciBkb3duLCB0aW55IGRyYWcsIHNlY29uZCBmaW5nZXIgZG93blxuICAgICAgdGhpcy5raW5ldGljXy5iZWdpbigpO1xuICAgIH1cblxuICAgIHRoaXMubGFzdENlbnRyb2lkID0gY2VudHJvaWQ7XG4gICAgdGhpcy5sYXN0UG9pbnRlcnNDb3VudF8gPSB0YXJnZXRQb2ludGVycy5sZW5ndGg7XG4gICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIHVwIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIERyYWdQYW4ucHJvdG90eXBlLmhhbmRsZVVwRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAoIXRoaXMubm9LaW5ldGljXyAmJiB0aGlzLmtpbmV0aWNfICYmIHRoaXMua2luZXRpY18uZW5kKCkpIHtcbiAgICAgICAgdmFyIGRpc3RhbmNlID0gdGhpcy5raW5ldGljXy5nZXREaXN0YW5jZSgpO1xuICAgICAgICB2YXIgYW5nbGUgPSB0aGlzLmtpbmV0aWNfLmdldEFuZ2xlKCk7XG4gICAgICAgIHZhciBjZW50ZXIgPSB2aWV3LmdldENlbnRlckludGVybmFsKCk7XG4gICAgICAgIHZhciBjZW50ZXJweCA9IG1hcC5nZXRQaXhlbEZyb21Db29yZGluYXRlSW50ZXJuYWwoY2VudGVyKTtcbiAgICAgICAgdmFyIGRlc3QgPSBtYXAuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKFtjZW50ZXJweFswXSAtIGRpc3RhbmNlICogTWF0aC5jb3MoYW5nbGUpLCBjZW50ZXJweFsxXSAtIGRpc3RhbmNlICogTWF0aC5zaW4oYW5nbGUpXSk7XG4gICAgICAgIHZpZXcuYW5pbWF0ZUludGVybmFsKHtcbiAgICAgICAgICBjZW50ZXI6IHZpZXcuZ2V0Q29uc3RyYWluZWRDZW50ZXIoZGVzdCksXG4gICAgICAgICAgZHVyYXRpb246IDUwMCxcbiAgICAgICAgICBlYXNpbmc6IGVhc2VPdXRcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhbm5pbmdfKSB7XG4gICAgICAgIHRoaXMucGFubmluZ18gPSBmYWxzZTtcbiAgICAgICAgdmlldy5lbmRJbnRlcmFjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmtpbmV0aWNfKSB7XG4gICAgICAgIC8vIHJlc2V0IHNvIHdlIGRvbid0IG92ZXJlc3RpbWF0ZSB0aGUga2luZXRpYyBlbmVyZ3kgYWZ0ZXJcbiAgICAgICAgLy8gYWZ0ZXIgb25lIGZpbmdlciB1cCwgdGlueSBkcmFnLCBzZWNvbmQgZmluZ2VyIHVwXG4gICAgICAgIHRoaXMua2luZXRpY18uYmVnaW4oKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sYXN0Q2VudHJvaWQgPSBudWxsO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZG93biBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICovXG5cblxuICBEcmFnUGFuLnByb3RvdHlwZS5oYW5kbGVEb3duRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoID4gMCAmJiB0aGlzLmNvbmRpdGlvbl8obWFwQnJvd3NlckV2ZW50KSkge1xuICAgICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgICB0aGlzLmxhc3RDZW50cm9pZCA9IG51bGw7IC8vIHN0b3AgYW55IGN1cnJlbnQgYW5pbWF0aW9uXG5cbiAgICAgIGlmICh2aWV3LmdldEFuaW1hdGluZygpKSB7XG4gICAgICAgIHZpZXcuY2FuY2VsQW5pbWF0aW9ucygpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5raW5ldGljXykge1xuICAgICAgICB0aGlzLmtpbmV0aWNfLmJlZ2luKCk7XG4gICAgICB9IC8vIE5vIGtpbmV0aWMgYXMgc29vbiBhcyBtb3JlIHRoYW4gb25lIHBvaW50ZXIgb24gdGhlIHNjcmVlbiBpc1xuICAgICAgLy8gZGV0ZWN0ZWQuIFRoaXMgaXMgdG8gcHJldmVudCBuYXN0eSBwYW5zIGFmdGVyIHBpbmNoLlxuXG5cbiAgICAgIHRoaXMubm9LaW5ldGljXyA9IHRoaXMudGFyZ2V0UG9pbnRlcnMubGVuZ3RoID4gMTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBEcmFnUGFuO1xufShQb2ludGVySW50ZXJhY3Rpb24pO1xuXG5leHBvcnQgZGVmYXVsdCBEcmFnUGFuOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZVxuICovXG5cblxuaW1wb3J0IFBvaW50ZXJJbnRlcmFjdGlvbiBmcm9tICcuL1BvaW50ZXIuanMnO1xuaW1wb3J0IHsgRkFMU0UgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgYWx0U2hpZnRLZXlzT25seSwgbW91c2VBY3Rpb25CdXR0b24sIG1vdXNlT25seSB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuaW1wb3J0IHsgZGlzYWJsZSB9IGZyb20gJy4uL3JvdGF0aW9uY29uc3RyYWludC5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259IFtjb25kaXRpb25dIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhblxuICoge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fSBhbmQgcmV0dXJucyBhIGJvb2xlYW5cbiAqIHRvIGluZGljYXRlIHdoZXRoZXIgdGhhdCBldmVudCBzaG91bGQgYmUgaGFuZGxlZC5cbiAqIERlZmF1bHQgaXMge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufmFsdFNoaWZ0S2V5c09ubHl9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yNTBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gcm90YXRlIHRoZSBtYXAgYnkgY2xpY2tpbmcgYW5kIGRyYWdnaW5nIG9uIHRoZSBtYXAsXG4gKiBub3JtYWxseSBjb21iaW5lZCB3aXRoIGFuIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn0gdGhhdCBsaW1pdHNcbiAqIGl0IHRvIHdoZW4gdGhlIGFsdCBhbmQgc2hpZnQga2V5cyBhcmUgaGVsZCBkb3duLlxuICpcbiAqIFRoaXMgaW50ZXJhY3Rpb24gaXMgb25seSBzdXBwb3J0ZWQgZm9yIG1vdXNlIGRldmljZXMuXG4gKiBAYXBpXG4gKi9cblxudmFyIERyYWdSb3RhdGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoRHJhZ1JvdGF0ZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRHJhZ1JvdGF0ZShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIHN0b3BEb3duOiBGQUxTRVxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259XG4gICAgICovXG5cbiAgICBfdGhpcy5jb25kaXRpb25fID0gb3B0aW9ucy5jb25kaXRpb24gPyBvcHRpb25zLmNvbmRpdGlvbiA6IGFsdFNoaWZ0S2V5c09ubHk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmxhc3RBbmdsZV8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDI1MDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRyYWcgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqL1xuXG5cbiAgRHJhZ1JvdGF0ZS5wcm90b3R5cGUuaGFuZGxlRHJhZ0V2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICghbW91c2VPbmx5KG1hcEJyb3dzZXJFdmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG5cbiAgICBpZiAodmlldy5nZXRDb25zdHJhaW50cygpLnJvdGF0aW9uID09PSBkaXNhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNpemUgPSBtYXAuZ2V0U2l6ZSgpO1xuICAgIHZhciBvZmZzZXQgPSBtYXBCcm93c2VyRXZlbnQucGl4ZWw7XG4gICAgdmFyIHRoZXRhID0gTWF0aC5hdGFuMihzaXplWzFdIC8gMiAtIG9mZnNldFsxXSwgb2Zmc2V0WzBdIC0gc2l6ZVswXSAvIDIpO1xuXG4gICAgaWYgKHRoaXMubGFzdEFuZ2xlXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgZGVsdGEgPSB0aGV0YSAtIHRoaXMubGFzdEFuZ2xlXztcbiAgICAgIHZpZXcuYWRqdXN0Um90YXRpb25JbnRlcm5hbCgtZGVsdGEpO1xuICAgIH1cblxuICAgIHRoaXMubGFzdEFuZ2xlXyA9IHRoZXRhO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgdXAgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgRHJhZ1JvdGF0ZS5wcm90b3R5cGUuaGFuZGxlVXBFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAoIW1vdXNlT25seShtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgdmlldy5lbmRJbnRlcmFjdGlvbih0aGlzLmR1cmF0aW9uXyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZG93biBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICovXG5cblxuICBEcmFnUm90YXRlLnByb3RvdHlwZS5oYW5kbGVEb3duRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKCFtb3VzZU9ubHkobWFwQnJvd3NlckV2ZW50KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChtb3VzZUFjdGlvbkJ1dHRvbihtYXBCcm93c2VyRXZlbnQpICYmIHRoaXMuY29uZGl0aW9uXyhtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIG1hcC5nZXRWaWV3KCkuYmVnaW5JbnRlcmFjdGlvbigpO1xuICAgICAgdGhpcy5sYXN0QW5nbGVfID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIERyYWdSb3RhdGU7XG59KFBvaW50ZXJJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IERyYWdSb3RhdGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9Cb3hcbiAqL1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IERpc3Bvc2FibGUgZnJvbSAnLi4vRGlzcG9zYWJsZS5qcyc7XG5pbXBvcnQgUG9seWdvbiBmcm9tICcuLi9nZW9tL1BvbHlnb24uanMnO1xuXG52YXIgUmVuZGVyQm94ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFJlbmRlckJveCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjbGFzc05hbWUgQ1NTIGNsYXNzIG5hbWUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gUmVuZGVyQm94KGNsYXNzTmFtZSkge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLmdlb21ldHJ5XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0hUTUxEaXZFbGVtZW50fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5lbGVtZW50XyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIF90aGlzLmVsZW1lbnRfLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBfdGhpcy5lbGVtZW50Xy5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgIF90aGlzLmVsZW1lbnRfLmNsYXNzTmFtZSA9ICdvbC1ib3ggJyArIGNsYXNzTmFtZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLm1hcF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RhcnRQaXhlbF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZW5kUGl4ZWxfID0gbnVsbDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENsZWFuIHVwLlxuICAgKi9cblxuXG4gIFJlbmRlckJveC5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2V0TWFwKG51bGwpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBSZW5kZXJCb3gucHJvdG90eXBlLnJlbmRlcl8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXJ0UGl4ZWwgPSB0aGlzLnN0YXJ0UGl4ZWxfO1xuICAgIHZhciBlbmRQaXhlbCA9IHRoaXMuZW5kUGl4ZWxfO1xuICAgIHZhciBweCA9ICdweCc7XG4gICAgdmFyIHN0eWxlID0gdGhpcy5lbGVtZW50Xy5zdHlsZTtcbiAgICBzdHlsZS5sZWZ0ID0gTWF0aC5taW4oc3RhcnRQaXhlbFswXSwgZW5kUGl4ZWxbMF0pICsgcHg7XG4gICAgc3R5bGUudG9wID0gTWF0aC5taW4oc3RhcnRQaXhlbFsxXSwgZW5kUGl4ZWxbMV0pICsgcHg7XG4gICAgc3R5bGUud2lkdGggPSBNYXRoLmFicyhlbmRQaXhlbFswXSAtIHN0YXJ0UGl4ZWxbMF0pICsgcHg7XG4gICAgc3R5bGUuaGVpZ2h0ID0gTWF0aC5hYnMoZW5kUGl4ZWxbMV0gLSBzdGFydFBpeGVsWzFdKSArIHB4O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdH0gbWFwIE1hcC5cbiAgICovXG5cblxuICBSZW5kZXJCb3gucHJvdG90eXBlLnNldE1hcCA9IGZ1bmN0aW9uIChtYXApIHtcbiAgICBpZiAodGhpcy5tYXBfKSB7XG4gICAgICB0aGlzLm1hcF8uZ2V0T3ZlcmxheUNvbnRhaW5lcigpLnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudF8pO1xuICAgICAgdmFyIHN0eWxlID0gdGhpcy5lbGVtZW50Xy5zdHlsZTtcbiAgICAgIHN0eWxlLmxlZnQgPSAnaW5oZXJpdCc7XG4gICAgICBzdHlsZS50b3AgPSAnaW5oZXJpdCc7XG4gICAgICBzdHlsZS53aWR0aCA9ICdpbmhlcml0JztcbiAgICAgIHN0eWxlLmhlaWdodCA9ICdpbmhlcml0JztcbiAgICB9XG5cbiAgICB0aGlzLm1hcF8gPSBtYXA7XG5cbiAgICBpZiAodGhpcy5tYXBfKSB7XG4gICAgICB0aGlzLm1hcF8uZ2V0T3ZlcmxheUNvbnRhaW5lcigpLmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudF8pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHN0YXJ0UGl4ZWwgU3RhcnQgcGl4ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IGVuZFBpeGVsIEVuZCBwaXhlbC5cbiAgICovXG5cblxuICBSZW5kZXJCb3gucHJvdG90eXBlLnNldFBpeGVscyA9IGZ1bmN0aW9uIChzdGFydFBpeGVsLCBlbmRQaXhlbCkge1xuICAgIHRoaXMuc3RhcnRQaXhlbF8gPSBzdGFydFBpeGVsO1xuICAgIHRoaXMuZW5kUGl4ZWxfID0gZW5kUGl4ZWw7XG4gICAgdGhpcy5jcmVhdGVPclVwZGF0ZUdlb21ldHJ5KCk7XG4gICAgdGhpcy5yZW5kZXJfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGVzIG9yIHVwZGF0ZXMgdGhlIGNhY2hlZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBSZW5kZXJCb3gucHJvdG90eXBlLmNyZWF0ZU9yVXBkYXRlR2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXJ0UGl4ZWwgPSB0aGlzLnN0YXJ0UGl4ZWxfO1xuICAgIHZhciBlbmRQaXhlbCA9IHRoaXMuZW5kUGl4ZWxfO1xuICAgIHZhciBwaXhlbHMgPSBbc3RhcnRQaXhlbCwgW3N0YXJ0UGl4ZWxbMF0sIGVuZFBpeGVsWzFdXSwgZW5kUGl4ZWwsIFtlbmRQaXhlbFswXSwgc3RhcnRQaXhlbFsxXV1dO1xuICAgIHZhciBjb29yZGluYXRlcyA9IHBpeGVscy5tYXAodGhpcy5tYXBfLmdldENvb3JkaW5hdGVGcm9tUGl4ZWxJbnRlcm5hbCwgdGhpcy5tYXBfKTsgLy8gY2xvc2UgdGhlIHBvbHlnb25cblxuICAgIGNvb3JkaW5hdGVzWzRdID0gY29vcmRpbmF0ZXNbMF0uc2xpY2UoKTtcblxuICAgIGlmICghdGhpcy5nZW9tZXRyeV8pIHtcbiAgICAgIHRoaXMuZ2VvbWV0cnlfID0gbmV3IFBvbHlnb24oW2Nvb3JkaW5hdGVzXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ2VvbWV0cnlfLnNldENvb3JkaW5hdGVzKFtjb29yZGluYXRlc10pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeS5cbiAgICovXG5cblxuICBSZW5kZXJCb3gucHJvdG90eXBlLmdldEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdlb21ldHJ5XztcbiAgfTtcblxuICByZXR1cm4gUmVuZGVyQm94O1xufShEaXNwb3NhYmxlKTtcblxuZXhwb3J0IGRlZmF1bHQgUmVuZGVyQm94OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vRHJhZ0JveFxuICovXG4vLyBGSVhNRSBkcmF3IGRyYWcgYm94XG5cblxuaW1wb3J0IEV2ZW50IGZyb20gJy4uL2V2ZW50cy9FdmVudC5qcyc7XG5pbXBvcnQgUG9pbnRlckludGVyYWN0aW9uIGZyb20gJy4vUG9pbnRlci5qcyc7XG5pbXBvcnQgUmVuZGVyQm94IGZyb20gJy4uL3JlbmRlci9Cb3guanMnO1xuaW1wb3J0IHsgbW91c2VBY3Rpb25CdXR0b24gfSBmcm9tICcuLi9ldmVudHMvY29uZGl0aW9uLmpzJztcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGEge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR9IGFuZCB0d29cbiAqIHtAbGluayBtb2R1bGU6b2wvcGl4ZWx+UGl4ZWx9cyBhbmQgcmV0dXJucyBhIGB7Ym9vbGVhbn1gLiBJZiB0aGUgY29uZGl0aW9uIGlzIG1ldCxcbiAqIHRydWUgc2hvdWxkIGJlIHJldHVybmVkLlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKHRoaXM6ID8sIGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbCwgaW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWwpOmJvb2xlYW59IEVuZENvbmRpdGlvblxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWRyYWdib3gnXSBDU1MgY2xhc3MgbmFtZSBmb3Igc3R5bGluZyB0aGUgYm94LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYSBib29sZWFuXG4gKiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoYXQgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuXG4gKiBEZWZhdWx0IGlzIHtAbGluayBvbC9ldmVudHMvY29uZGl0aW9ufm1vdXNlQWN0aW9uQnV0dG9ufS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluQXJlYT02NF0gVGhlIG1pbmltdW0gYXJlYSBvZiB0aGUgYm94IGluIHBpeGVsLCB0aGlzIHZhbHVlIGlzIHVzZWQgYnkgdGhlIGRlZmF1bHRcbiAqIGBib3hFbmRDb25kaXRpb25gIGZ1bmN0aW9uLlxuICogQHByb3BlcnR5IHtFbmRDb25kaXRpb259IFtib3hFbmRDb25kaXRpb25dIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHR3b1xuICoge0BsaW5rIG1vZHVsZTpvbC9waXhlbH5QaXhlbH1zIHRvIGluZGljYXRlIHdoZXRoZXIgYSBgYm94ZW5kYCBldmVudCBzaG91bGQgYmUgZmlyZWQuXG4gKiBEZWZhdWx0IGlzIGB0cnVlYCBpZiB0aGUgYXJlYSBvZiB0aGUgYm94IGlzIGJpZ2dlciB0aGFuIHRoZSBgbWluQXJlYWAgb3B0aW9uLlxuICogQHByb3BlcnR5IHtmdW5jdGlvbih0aGlzOkRyYWdCb3gsIGltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0KTp2b2lkfSBbb25Cb3hFbmRdIENvZGUgdG8gZXhlY3V0ZSBqdXN0XG4gKiBiZWZvcmUgYGJveGVuZGAgaXMgZmlyZWQuXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5cbnZhciBEcmFnQm94RXZlbnRUeXBlID0ge1xuICAvKipcbiAgICogVHJpZ2dlcmVkIHVwb24gZHJhZyBib3ggc3RhcnQuXG4gICAqIEBldmVudCBEcmFnQm94RXZlbnQjYm94c3RhcnRcbiAgICogQGFwaVxuICAgKi9cbiAgQk9YU1RBUlQ6ICdib3hzdGFydCcsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCBvbiBkcmFnIHdoZW4gYm94IGlzIGFjdGl2ZS5cbiAgICogQGV2ZW50IERyYWdCb3hFdmVudCNib3hkcmFnXG4gICAqIEBhcGlcbiAgICovXG4gIEJPWERSQUc6ICdib3hkcmFnJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHVwb24gZHJhZyBib3ggZW5kLlxuICAgKiBAZXZlbnQgRHJhZ0JveEV2ZW50I2JveGVuZFxuICAgKiBAYXBpXG4gICAqL1xuICBCT1hFTkQ6ICdib3hlbmQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgdXBvbiBkcmFnIGJveCBjYW5jZWxlZC5cbiAgICogQGV2ZW50IERyYWdCb3hFdmVudCNib3hjYW5jZWxcbiAgICogQGFwaVxuICAgKi9cbiAgQk9YQ0FOQ0VMOiAnYm94Y2FuY2VsJ1xufTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogRXZlbnRzIGVtaXR0ZWQgYnkge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9EcmFnQm94fkRyYWdCb3h9IGluc3RhbmNlcyBhcmUgaW5zdGFuY2VzIG9mXG4gKiB0aGlzIHR5cGUuXG4gKi9cblxudmFyIERyYWdCb3hFdmVudCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEcmFnQm94RXZlbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBUaGUgZXZlbnQgdHlwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgVGhlIGV2ZW50IGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBPcmlnaW5hdGluZyBldmVudC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBEcmFnQm94RXZlbnQodHlwZSwgY29vcmRpbmF0ZSwgbWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUaGUgY29vcmRpbmF0ZSBvZiB0aGUgZHJhZyBldmVudC5cbiAgICAgKiBAY29uc3RcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29vcmRpbmF0ZSA9IGNvb3JkaW5hdGU7XG4gICAgLyoqXG4gICAgICogQGNvbnN0XG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICAgIF90aGlzLm1hcEJyb3dzZXJFdmVudCA9IG1hcEJyb3dzZXJFdmVudDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gRHJhZ0JveEV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCB7IERyYWdCb3hFdmVudCB9O1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gZHJhdyBhIHZlY3RvciBib3ggYnkgY2xpY2tpbmcgYW5kIGRyYWdnaW5nIG9uIHRoZSBtYXAsXG4gKiBub3JtYWxseSBjb21iaW5lZCB3aXRoIGFuIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn0gdGhhdCBsaW1pdHNcbiAqIGl0IHRvIHdoZW4gdGhlIHNoaWZ0IG9yIG90aGVyIGtleSBpcyBoZWxkIGRvd24uIFRoaXMgaXMgdXNlZCwgZm9yIGV4YW1wbGUsXG4gKiBmb3Igem9vbWluZyB0byBhIHNwZWNpZmljIGFyZWEgb2YgdGhlIG1hcFxuICogKHNlZSB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0RyYWdab29tfkRyYWdab29tfSBhbmRcbiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vRHJhZ1JvdGF0ZUFuZFpvb219KS5cbiAqXG4gKiBAZmlyZXMgRHJhZ0JveEV2ZW50XG4gKiBAYXBpXG4gKi9cblxudmFyIERyYWdCb3ggPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoRHJhZ0JveCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRHJhZ0JveChvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyL0JveC5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5ib3hfID0gbmV3IFJlbmRlckJveChvcHRpb25zLmNsYXNzTmFtZSB8fCAnb2wtZHJhZ2JveCcpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLm1pbkFyZWFfID0gb3B0aW9ucy5taW5BcmVhICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1pbkFyZWEgOiA2NDtcblxuICAgIGlmIChvcHRpb25zLm9uQm94RW5kKSB7XG4gICAgICBfdGhpcy5vbkJveEVuZCA9IG9wdGlvbnMub25Cb3hFbmQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5zdGFydFBpeGVsXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259XG4gICAgICovXG5cbiAgICBfdGhpcy5jb25kaXRpb25fID0gb3B0aW9ucy5jb25kaXRpb24gPyBvcHRpb25zLmNvbmRpdGlvbiA6IG1vdXNlQWN0aW9uQnV0dG9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0VuZENvbmRpdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmJveEVuZENvbmRpdGlvbl8gPSBvcHRpb25zLmJveEVuZENvbmRpdGlvbiA/IG9wdGlvbnMuYm94RW5kQ29uZGl0aW9uIDogX3RoaXMuZGVmYXVsdEJveEVuZENvbmRpdGlvbjtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGNvbmRpdGlvbiBmb3IgZGV0ZXJtaW5pbmcgd2hldGhlciB0aGUgYm94ZW5kIGV2ZW50XG4gICAqIHNob3VsZCBmaXJlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgVGhlIG9yaWdpbmF0aW5nIE1hcEJyb3dzZXJFdmVudFxuICAgKiAgICAgbGVhZGluZyB0byB0aGUgYm94IGVuZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gc3RhcnRQaXhlbCBUaGUgc3RhcnRpbmcgcGl4ZWwgb2YgdGhlIGJveC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9waXhlbC5qc1wiKS5QaXhlbH0gZW5kUGl4ZWwgVGhlIGVuZCBwaXhlbCBvZiB0aGUgYm94LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIG9yIG5vdCB0aGUgYm94ZW5kIGNvbmRpdGlvbiBzaG91bGQgYmUgZmlyZWQuXG4gICAqL1xuXG5cbiAgRHJhZ0JveC5wcm90b3R5cGUuZGVmYXVsdEJveEVuZENvbmRpdGlvbiA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQsIHN0YXJ0UGl4ZWwsIGVuZFBpeGVsKSB7XG4gICAgdmFyIHdpZHRoID0gZW5kUGl4ZWxbMF0gLSBzdGFydFBpeGVsWzBdO1xuICAgIHZhciBoZWlnaHQgPSBlbmRQaXhlbFsxXSAtIHN0YXJ0UGl4ZWxbMV07XG4gICAgcmV0dXJuIHdpZHRoICogd2lkdGggKyBoZWlnaHQgKiBoZWlnaHQgPj0gdGhpcy5taW5BcmVhXztcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgZ2VvbWV0cnkgb2YgbGFzdCBkcmF3biBib3guXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIERyYWdCb3gucHJvdG90eXBlLmdldEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmJveF8uZ2V0R2VvbWV0cnkoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRyYWcgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqL1xuXG5cbiAgRHJhZ0JveC5wcm90b3R5cGUuaGFuZGxlRHJhZ0V2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHRoaXMuYm94Xy5zZXRQaXhlbHModGhpcy5zdGFydFBpeGVsXywgbWFwQnJvd3NlckV2ZW50LnBpeGVsKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IERyYWdCb3hFdmVudChEcmFnQm94RXZlbnRUeXBlLkJPWERSQUcsIG1hcEJyb3dzZXJFdmVudC5jb29yZGluYXRlLCBtYXBCcm93c2VyRXZlbnQpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIHVwIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIERyYWdCb3gucHJvdG90eXBlLmhhbmRsZVVwRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdGhpcy5ib3hfLnNldE1hcChudWxsKTtcbiAgICB2YXIgY29tcGxldGVCb3ggPSB0aGlzLmJveEVuZENvbmRpdGlvbl8obWFwQnJvd3NlckV2ZW50LCB0aGlzLnN0YXJ0UGl4ZWxfLCBtYXBCcm93c2VyRXZlbnQucGl4ZWwpO1xuXG4gICAgaWYgKGNvbXBsZXRlQm94KSB7XG4gICAgICB0aGlzLm9uQm94RW5kKG1hcEJyb3dzZXJFdmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBEcmFnQm94RXZlbnQoY29tcGxldGVCb3ggPyBEcmFnQm94RXZlbnRUeXBlLkJPWEVORCA6IERyYWdCb3hFdmVudFR5cGUuQk9YQ0FOQ0VMLCBtYXBCcm93c2VyRXZlbnQuY29vcmRpbmF0ZSwgbWFwQnJvd3NlckV2ZW50KSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZG93biBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSWYgdGhlIGV2ZW50IHdhcyBjb25zdW1lZC5cbiAgICovXG5cblxuICBEcmFnQm94LnByb3RvdHlwZS5oYW5kbGVEb3duRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKHRoaXMuY29uZGl0aW9uXyhtYXBCcm93c2VyRXZlbnQpKSB7XG4gICAgICB0aGlzLnN0YXJ0UGl4ZWxfID0gbWFwQnJvd3NlckV2ZW50LnBpeGVsO1xuICAgICAgdGhpcy5ib3hfLnNldE1hcChtYXBCcm93c2VyRXZlbnQubWFwKTtcbiAgICAgIHRoaXMuYm94Xy5zZXRQaXhlbHModGhpcy5zdGFydFBpeGVsXywgdGhpcy5zdGFydFBpeGVsXyk7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IERyYWdCb3hFdmVudChEcmFnQm94RXZlbnRUeXBlLkJPWFNUQVJULCBtYXBCcm93c2VyRXZlbnQuY29vcmRpbmF0ZSwgbWFwQnJvd3NlckV2ZW50KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRvIGV4ZWN1dGUganVzdCBiZWZvcmUgYG9uYm94ZW5kYCBpcyBmaXJlZFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBFdmVudC5cbiAgICovXG5cblxuICBEcmFnQm94LnByb3RvdHlwZS5vbkJveEVuZCA9IGZ1bmN0aW9uIChldmVudCkge307XG5cbiAgcmV0dXJuIERyYWdCb3g7XG59KFBvaW50ZXJJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IERyYWdCb3g7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9EcmFnWm9vbVxuICovXG5cblxuaW1wb3J0IERyYWdCb3ggZnJvbSAnLi9EcmFnQm94LmpzJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGVzLCBnZXRCb3R0b21MZWZ0LCBnZXRDZW50ZXIsIGdldFRvcFJpZ2h0LCBzY2FsZUZyb21DZW50ZXIgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZWFzZU91dCB9IGZyb20gJy4uL2Vhc2luZy5qcyc7XG5pbXBvcnQgeyBzaGlmdEtleU9ubHkgfSBmcm9tICcuLi9ldmVudHMvY29uZGl0aW9uLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWRyYWd6b29tJ10gQ1NTIGNsYXNzIG5hbWUgZm9yIHN0eWxpbmcgdGhlXG4gKiBib3guXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufSBbY29uZGl0aW9uXSBBIGZ1bmN0aW9uIHRoYXRcbiAqIHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50fk1hcEJyb3dzZXJFdmVudH0gYW5kIHJldHVybnMgYVxuICogYm9vbGVhbiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoYXQgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQuXG4gKiBEZWZhdWx0IGlzIHtAbGluayBtb2R1bGU6b2wvZXZlbnRzL2NvbmRpdGlvbn5zaGlmdEtleU9ubHl9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj0yMDBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvdXQ9ZmFsc2VdIFVzZSBpbnRlcmFjdGlvbiBmb3Igem9vbWluZyBvdXQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pbkFyZWE9NjRdIFRoZSBtaW5pbXVtIGFyZWEgb2YgdGhlIGJveCBpbiBwaXhlbCwgdGhpcyB2YWx1ZSBpcyB1c2VkIGJ5IHRoZSBwYXJlbnQgZGVmYXVsdFxuICogYGJveEVuZENvbmRpdGlvbmAgZnVuY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gem9vbSB0aGUgbWFwIGJ5IGNsaWNraW5nIGFuZCBkcmFnZ2luZyBvbiB0aGUgbWFwLFxuICogbm9ybWFsbHkgY29tYmluZWQgd2l0aCBhbiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb259IHRoYXQgbGltaXRzXG4gKiBpdCB0byB3aGVuIGEga2V5LCBzaGlmdCBieSBkZWZhdWx0LCBpcyBoZWxkIGRvd24uXG4gKlxuICogVG8gY2hhbmdlIHRoZSBzdHlsZSBvZiB0aGUgYm94LCB1c2UgQ1NTIGFuZCB0aGUgYC5vbC1kcmFnem9vbWAgc2VsZWN0b3IsIG9yXG4gKiB5b3VyIGN1c3RvbSBvbmUgY29uZmlndXJlZCB3aXRoIGBjbGFzc05hbWVgLlxuICogQGFwaVxuICovXG5cbnZhciBEcmFnWm9vbSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhEcmFnWm9vbSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gRHJhZ1pvb20ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgdmFyIGNvbmRpdGlvbiA9IG9wdGlvbnMuY29uZGl0aW9uID8gb3B0aW9ucy5jb25kaXRpb24gOiBzaGlmdEtleU9ubHk7XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBjb25kaXRpb246IGNvbmRpdGlvbixcbiAgICAgIGNsYXNzTmFtZTogb3B0aW9ucy5jbGFzc05hbWUgfHwgJ29sLWRyYWd6b29tJyxcbiAgICAgIG1pbkFyZWE6IG9wdGlvbnMubWluQXJlYVxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDIwMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMub3V0XyA9IG9wdGlvbnMub3V0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm91dCA6IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogRnVuY3Rpb24gdG8gZXhlY3V0ZSBqdXN0IGJlZm9yZSBgb25ib3hlbmRgIGlzIGZpcmVkXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEV2ZW50LlxuICAgKi9cblxuXG4gIERyYWdab29tLnByb3RvdHlwZS5vbkJveEVuZCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHZhciBtYXAgPSB0aGlzLmdldE1hcCgpO1xuICAgIHZhciB2aWV3ID1cbiAgICAvKiogQHR5cGUgeyFpbXBvcnQoXCIuLi9WaWV3LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgbWFwLmdldFZpZXcoKTtcbiAgICB2YXIgc2l6ZSA9XG4gICAgLyoqIEB0eXBlIHshaW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSAqL1xuICAgIG1hcC5nZXRTaXplKCk7XG4gICAgdmFyIGV4dGVudCA9IHRoaXMuZ2V0R2VvbWV0cnkoKS5nZXRFeHRlbnQoKTtcblxuICAgIGlmICh0aGlzLm91dF8pIHtcbiAgICAgIHZhciBtYXBFeHRlbnQgPSB2aWV3LmNhbGN1bGF0ZUV4dGVudEludGVybmFsKHNpemUpO1xuICAgICAgdmFyIGJveFBpeGVsRXh0ZW50ID0gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZXMoW21hcC5nZXRQaXhlbEZyb21Db29yZGluYXRlSW50ZXJuYWwoZ2V0Qm90dG9tTGVmdChleHRlbnQpKSwgbWFwLmdldFBpeGVsRnJvbUNvb3JkaW5hdGVJbnRlcm5hbChnZXRUb3BSaWdodChleHRlbnQpKV0pO1xuICAgICAgdmFyIGZhY3RvciA9IHZpZXcuZ2V0UmVzb2x1dGlvbkZvckV4dGVudEludGVybmFsKGJveFBpeGVsRXh0ZW50LCBzaXplKTtcbiAgICAgIHNjYWxlRnJvbUNlbnRlcihtYXBFeHRlbnQsIDEgLyBmYWN0b3IpO1xuICAgICAgZXh0ZW50ID0gbWFwRXh0ZW50O1xuICAgIH1cblxuICAgIHZhciByZXNvbHV0aW9uID0gdmlldy5nZXRDb25zdHJhaW5lZFJlc29sdXRpb24odmlldy5nZXRSZXNvbHV0aW9uRm9yRXh0ZW50SW50ZXJuYWwoZXh0ZW50LCBzaXplKSk7XG4gICAgdmFyIGNlbnRlciA9IHZpZXcuZ2V0Q29uc3RyYWluZWRDZW50ZXIoZ2V0Q2VudGVyKGV4dGVudCksIHJlc29sdXRpb24pO1xuICAgIHZpZXcuYW5pbWF0ZUludGVybmFsKHtcbiAgICAgIHJlc29sdXRpb246IHJlc29sdXRpb24sXG4gICAgICBjZW50ZXI6IGNlbnRlcixcbiAgICAgIGR1cmF0aW9uOiB0aGlzLmR1cmF0aW9uXyxcbiAgICAgIGVhc2luZzogZWFzZU91dFxuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBEcmFnWm9vbTtcbn0oRHJhZ0JveCk7XG5cbmV4cG9ydCBkZWZhdWx0IERyYWdab29tOyIsIi8qKlxuICogQG1vZHVsZSBvbC9ldmVudHMvS2V5Q29kZVxuICovXG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqIEBjb25zdFxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIExFRlQ6IDM3LFxuICBVUDogMzgsXG4gIFJJR0hUOiAzOSxcbiAgRE9XTjogNDBcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9LZXlib2FyZFBhblxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbnRlcmFjdGlvbiwgeyBwYW4gfSBmcm9tICcuL0ludGVyYWN0aW9uLmpzJztcbmltcG9ydCBLZXlDb2RlIGZyb20gJy4uL2V2ZW50cy9LZXlDb2RlLmpzJztcbmltcG9ydCB7IG5vTW9kaWZpZXJLZXlzLCB0YXJnZXROb3RFZGl0YWJsZSB9IGZyb20gJy4uL2V2ZW50cy9jb25kaXRpb24uanMnO1xuaW1wb3J0IHsgcm90YXRlIGFzIHJvdGF0ZUNvb3JkaW5hdGUgfSBmcm9tICcuLi9jb29yZGluYXRlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0XG4gKiB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9IGFuZCByZXR1cm5zIGFcbiAqIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciB0aGF0IGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkLiBEZWZhdWx0IGlzXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+bm9Nb2RpZmllcktleXN9IGFuZFxuICoge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufnRhcmdldE5vdEVkaXRhYmxlfS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MTAwXSBBbmltYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtwaXhlbERlbHRhPTEyOF0gVGhlIGFtb3VudCBvZiBwaXhlbHMgdG8gcGFuIG9uIGVhY2gga2V5XG4gKiBwcmVzcy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byBwYW4gdGhlIG1hcCB1c2luZyBrZXlib2FyZCBhcnJvd3MuXG4gKiBOb3RlIHRoYXQsIGFsdGhvdWdoIHRoaXMgaW50ZXJhY3Rpb24gaXMgYnkgZGVmYXVsdCBpbmNsdWRlZCBpbiBtYXBzLFxuICogdGhlIGtleXMgY2FuIG9ubHkgYmUgdXNlZCB3aGVuIGJyb3dzZXIgZm9jdXMgaXMgb24gdGhlIGVsZW1lbnQgdG8gd2hpY2hcbiAqIHRoZSBrZXlib2FyZCBldmVudHMgYXJlIGF0dGFjaGVkLiBCeSBkZWZhdWx0LCB0aGlzIGlzIHRoZSBtYXAgZGl2LFxuICogdGhvdWdoIHlvdSBjYW4gY2hhbmdlIHRoaXMgd2l0aCB0aGUgYGtleWJvYXJkRXZlbnRUYXJnZXRgIGluXG4gKiB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXB9LiBgZG9jdW1lbnRgIG5ldmVyIGxvc2VzIGZvY3VzIGJ1dCwgZm9yIGFueSBvdGhlclxuICogZWxlbWVudCwgZm9jdXMgd2lsbCBoYXZlIHRvIGJlIG9uLCBhbmQgcmV0dXJuZWQgdG8sIHRoaXMgZWxlbWVudCBpZiB0aGUga2V5c1xuICogYXJlIHRvIGZ1bmN0aW9uLlxuICogU2VlIGFsc28ge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9LZXlib2FyZFpvb21+S2V5Ym9hcmRab29tfS5cbiAqIEBhcGlcbiAqL1xuXG52YXIgS2V5Ym9hcmRQYW4gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoS2V5Ym9hcmRQYW4sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEtleWJvYXJkUGFuKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgQnJvd3NlciBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBDb21iaW5lZCBjb25kaXRpb24gcmVzdWx0LlxuICAgICAqL1xuXG4gICAgX3RoaXMuZGVmYXVsdENvbmRpdGlvbl8gPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgICByZXR1cm4gbm9Nb2RpZmllcktleXMobWFwQnJvd3NlckV2ZW50KSAmJiB0YXJnZXROb3RFZGl0YWJsZShtYXBCcm93c2VyRXZlbnQpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259XG4gICAgICovXG5cblxuICAgIF90aGlzLmNvbmRpdGlvbl8gPSBvcHRpb25zLmNvbmRpdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb25kaXRpb24gOiBfdGhpcy5kZWZhdWx0Q29uZGl0aW9uXztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMTAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsRGVsdGFfID0gb3B0aW9ucy5waXhlbERlbHRhICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnBpeGVsRGVsdGEgOiAxMjg7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudCBtYXAgYnJvd3NlciBldmVudH0gaWYgaXQgd2FzIGFcbiAgICogYEtleUV2ZW50YCwgYW5kIGRlY2lkZXMgdGhlIGRpcmVjdGlvbiB0byBwYW4gdG8gKGlmIGFuIGFycm93IGtleSB3YXNcbiAgICogcHJlc3NlZCkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBNYXAgYnJvd3NlciBldmVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYGZhbHNlYCB0byBzdG9wIGV2ZW50IHByb3BhZ2F0aW9uLlxuICAgKiBAdGhpcyB7S2V5Ym9hcmRQYW59XG4gICAqL1xuXG5cbiAgS2V5Ym9hcmRQYW4ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHZhciBzdG9wRXZlbnQgPSBmYWxzZTtcblxuICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBFdmVudFR5cGUuS0VZRE9XTikge1xuICAgICAgdmFyIGtleUV2ZW50ID1cbiAgICAgIC8qKiBAdHlwZSB7S2V5Ym9hcmRFdmVudH0gKi9cbiAgICAgIG1hcEJyb3dzZXJFdmVudC5vcmlnaW5hbEV2ZW50O1xuICAgICAgdmFyIGtleUNvZGUgPSBrZXlFdmVudC5rZXlDb2RlO1xuXG4gICAgICBpZiAodGhpcy5jb25kaXRpb25fKG1hcEJyb3dzZXJFdmVudCkgJiYgKGtleUNvZGUgPT0gS2V5Q29kZS5ET1dOIHx8IGtleUNvZGUgPT0gS2V5Q29kZS5MRUZUIHx8IGtleUNvZGUgPT0gS2V5Q29kZS5SSUdIVCB8fCBrZXlDb2RlID09IEtleUNvZGUuVVApKSB7XG4gICAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG4gICAgICAgIHZhciBtYXBVbml0c0RlbHRhID0gdmlldy5nZXRSZXNvbHV0aW9uKCkgKiB0aGlzLnBpeGVsRGVsdGFfO1xuICAgICAgICB2YXIgZGVsdGFYID0gMCxcbiAgICAgICAgICAgIGRlbHRhWSA9IDA7XG5cbiAgICAgICAgaWYgKGtleUNvZGUgPT0gS2V5Q29kZS5ET1dOKSB7XG4gICAgICAgICAgZGVsdGFZID0gLW1hcFVuaXRzRGVsdGE7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Q29kZSA9PSBLZXlDb2RlLkxFRlQpIHtcbiAgICAgICAgICBkZWx0YVggPSAtbWFwVW5pdHNEZWx0YTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXlDb2RlID09IEtleUNvZGUuUklHSFQpIHtcbiAgICAgICAgICBkZWx0YVggPSBtYXBVbml0c0RlbHRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlbHRhWSA9IG1hcFVuaXRzRGVsdGE7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZGVsdGEgPSBbZGVsdGFYLCBkZWx0YVldO1xuICAgICAgICByb3RhdGVDb29yZGluYXRlKGRlbHRhLCB2aWV3LmdldFJvdGF0aW9uKCkpO1xuICAgICAgICBwYW4odmlldywgZGVsdGEsIHRoaXMuZHVyYXRpb25fKTtcbiAgICAgICAga2V5RXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgc3RvcEV2ZW50ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gIXN0b3BFdmVudDtcbiAgfTtcblxuICByZXR1cm4gS2V5Ym9hcmRQYW47XG59KEludGVyYWN0aW9uKTtcblxuZXhwb3J0IGRlZmF1bHQgS2V5Ym9hcmRQYW47IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9pbnRlcmFjdGlvbi9LZXlib2FyZFpvb21cbiAqL1xuXG5cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgSW50ZXJhY3Rpb24sIHsgem9vbUJ5RGVsdGEgfSBmcm9tICcuL0ludGVyYWN0aW9uLmpzJztcbmltcG9ydCB7IHRhcmdldE5vdEVkaXRhYmxlIH0gZnJvbSAnLi4vZXZlbnRzL2NvbmRpdGlvbi5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MTAwXSBBbmltYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn0gW2NvbmRpdGlvbl0gQSBmdW5jdGlvbiB0aGF0XG4gKiB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL01hcEJyb3dzZXJFdmVudH5NYXBCcm93c2VyRXZlbnR9IGFuZCByZXR1cm5zIGFcbiAqIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciB0aGF0IGV2ZW50IHNob3VsZCBiZSBoYW5kbGVkLiBEZWZhdWx0IGlzXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2V2ZW50cy9jb25kaXRpb25+dGFyZ2V0Tm90RWRpdGFibGV9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YT0xXSBUaGUgem9vbSBsZXZlbCBkZWx0YSBvbiBlYWNoIGtleSBwcmVzcy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byB6b29tIHRoZSBtYXAgdXNpbmcga2V5Ym9hcmQgKyBhbmQgLS5cbiAqIE5vdGUgdGhhdCwgYWx0aG91Z2ggdGhpcyBpbnRlcmFjdGlvbiBpcyBieSBkZWZhdWx0IGluY2x1ZGVkIGluIG1hcHMsXG4gKiB0aGUga2V5cyBjYW4gb25seSBiZSB1c2VkIHdoZW4gYnJvd3NlciBmb2N1cyBpcyBvbiB0aGUgZWxlbWVudCB0byB3aGljaFxuICogdGhlIGtleWJvYXJkIGV2ZW50cyBhcmUgYXR0YWNoZWQuIEJ5IGRlZmF1bHQsIHRoaXMgaXMgdGhlIG1hcCBkaXYsXG4gKiB0aG91Z2ggeW91IGNhbiBjaGFuZ2UgdGhpcyB3aXRoIHRoZSBga2V5Ym9hcmRFdmVudFRhcmdldGAgaW5cbiAqIHtAbGluayBtb2R1bGU6b2wvTWFwfk1hcH0uIGBkb2N1bWVudGAgbmV2ZXIgbG9zZXMgZm9jdXMgYnV0LCBmb3IgYW55IG90aGVyXG4gKiBlbGVtZW50LCBmb2N1cyB3aWxsIGhhdmUgdG8gYmUgb24sIGFuZCByZXR1cm5lZCB0bywgdGhpcyBlbGVtZW50IGlmIHRoZSBrZXlzXG4gKiBhcmUgdG8gZnVuY3Rpb24uXG4gKiBTZWUgYWxzbyB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0tleWJvYXJkUGFufktleWJvYXJkUGFufS5cbiAqIEBhcGlcbiAqL1xuXG52YXIgS2V5Ym9hcmRab29tID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEtleWJvYXJkWm9vbSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gS2V5Ym9hcmRab29tKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V2ZW50cy9jb25kaXRpb24uanNcIikuQ29uZGl0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29uZGl0aW9uXyA9IG9wdGlvbnMuY29uZGl0aW9uID8gb3B0aW9ucy5jb25kaXRpb24gOiB0YXJnZXROb3RFZGl0YWJsZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWx0YV8gPSBvcHRpb25zLmRlbHRhID8gb3B0aW9ucy5kZWx0YSA6IDE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDEwMDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEhhbmRsZXMgdGhlIHtAbGluayBtb2R1bGU6b2wvTWFwQnJvd3NlckV2ZW50IG1hcCBicm93c2VyIGV2ZW50fSBpZiBpdCB3YXMgYVxuICAgKiBgS2V5RXZlbnRgLCBhbmQgZGVjaWRlcyB3aGV0aGVyIHRvIHpvb20gaW4gb3Igb3V0IChkZXBlbmRpbmcgb24gd2hldGhlciB0aGVcbiAgICoga2V5IHByZXNzZWQgd2FzICcrJyBvciAnLScpLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGBmYWxzZWAgdG8gc3RvcCBldmVudCBwcm9wYWdhdGlvbi5cbiAgICogQHRoaXMge0tleWJvYXJkWm9vbX1cbiAgICovXG5cblxuICBLZXlib2FyZFpvb20ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIHZhciBzdG9wRXZlbnQgPSBmYWxzZTtcblxuICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBFdmVudFR5cGUuS0VZRE9XTiB8fCBtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBFdmVudFR5cGUuS0VZUFJFU1MpIHtcbiAgICAgIHZhciBrZXlFdmVudCA9XG4gICAgICAvKiogQHR5cGUge0tleWJvYXJkRXZlbnR9ICovXG4gICAgICBtYXBCcm93c2VyRXZlbnQub3JpZ2luYWxFdmVudDtcbiAgICAgIHZhciBjaGFyQ29kZSA9IGtleUV2ZW50LmNoYXJDb2RlO1xuXG4gICAgICBpZiAodGhpcy5jb25kaXRpb25fKG1hcEJyb3dzZXJFdmVudCkgJiYgKGNoYXJDb2RlID09ICcrJy5jaGFyQ29kZUF0KDApIHx8IGNoYXJDb2RlID09ICctJy5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgICAgdmFyIGRlbHRhID0gY2hhckNvZGUgPT0gJysnLmNoYXJDb2RlQXQoMCkgPyB0aGlzLmRlbHRhXyA6IC10aGlzLmRlbHRhXztcbiAgICAgICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuICAgICAgICB6b29tQnlEZWx0YSh2aWV3LCBkZWx0YSwgdW5kZWZpbmVkLCB0aGlzLmR1cmF0aW9uXyk7XG4gICAgICAgIGtleUV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHN0b3BFdmVudCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICFzdG9wRXZlbnQ7XG4gIH07XG5cbiAgcmV0dXJuIEtleWJvYXJkWm9vbTtcbn0oSW50ZXJhY3Rpb24pO1xuXG5leHBvcnQgZGVmYXVsdCBLZXlib2FyZFpvb207IiwiLyoqXG4gKiBAbW9kdWxlIG9sL0tpbmV0aWNcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEltcGxlbWVudGF0aW9uIG9mIGluZXJ0aWFsIGRlY2VsZXJhdGlvbiBmb3IgbWFwIG1vdmVtZW50LlxuICpcbiAqIEBhcGlcbiAqL1xudmFyIEtpbmV0aWMgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlY2F5IFJhdGUgb2YgZGVjYXkgKG11c3QgYmUgbmVnYXRpdmUpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluVmVsb2NpdHkgTWluaW11bSB2ZWxvY2l0eSAocGl4ZWxzL21pbGxpc2Vjb25kKS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGRlbGF5IERlbGF5IHRvIGNvbnNpZGVyIHRvIGNhbGN1bGF0ZSB0aGUga2luZXRpY1xuICAgKiAgICAgaW5pdGlhbCB2YWx1ZXMgKG1pbGxpc2Vjb25kcykuXG4gICAqL1xuICBmdW5jdGlvbiBLaW5ldGljKGRlY2F5LCBtaW5WZWxvY2l0eSwgZGVsYXkpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5kZWNheV8gPSBkZWNheTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1pblZlbG9jaXR5XyA9IG1pblZlbG9jaXR5O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMuZGVsYXlfID0gZGVsYXk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMucG9pbnRzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMuYW5nbGVfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLmluaXRpYWxWZWxvY2l0eV8gPSAwO1xuICB9XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBLaW5ldGljLnByb3RvdHlwZS5iZWdpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnBvaW50c18ubGVuZ3RoID0gMDtcbiAgICB0aGlzLmFuZ2xlXyA9IDA7XG4gICAgdGhpcy5pbml0aWFsVmVsb2NpdHlfID0gMDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqL1xuXG5cbiAgS2luZXRpYy5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICB0aGlzLnBvaW50c18ucHVzaCh4LCB5LCBEYXRlLm5vdygpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgd2Ugc2hvdWxkIGRvIGtpbmV0aWMgYW5pbWF0aW9uLlxuICAgKi9cblxuXG4gIEtpbmV0aWMucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5wb2ludHNfLmxlbmd0aCA8IDYpIHtcbiAgICAgIC8vIGF0IGxlYXN0IDIgcG9pbnRzIGFyZSByZXF1aXJlZCAoaS5lLiB0aGVyZSBtdXN0IGJlIGF0IGxlYXN0IDYgZWxlbWVudHNcbiAgICAgIC8vIGluIHRoZSBhcnJheSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgZGVsYXkgPSBEYXRlLm5vdygpIC0gdGhpcy5kZWxheV87XG4gICAgdmFyIGxhc3RJbmRleCA9IHRoaXMucG9pbnRzXy5sZW5ndGggLSAzO1xuXG4gICAgaWYgKHRoaXMucG9pbnRzX1tsYXN0SW5kZXggKyAyXSA8IGRlbGF5KSB7XG4gICAgICAvLyB0aGUgbGFzdCB0cmFja2VkIHBvaW50IGlzIHRvbyBvbGQsIHdoaWNoIG1lYW5zIHRoYXQgdGhlIHVzZXIgc3RvcHBlZFxuICAgICAgLy8gcGFubmluZyBiZWZvcmUgcmVsZWFzaW5nIHRoZSBtYXBcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IC8vIGdldCB0aGUgZmlyc3QgcG9pbnQgd2hpY2ggc3RpbGwgZmFsbHMgaW50byB0aGUgZGVsYXkgdGltZVxuXG5cbiAgICB2YXIgZmlyc3RJbmRleCA9IGxhc3RJbmRleCAtIDM7XG5cbiAgICB3aGlsZSAoZmlyc3RJbmRleCA+IDAgJiYgdGhpcy5wb2ludHNfW2ZpcnN0SW5kZXggKyAyXSA+IGRlbGF5KSB7XG4gICAgICBmaXJzdEluZGV4IC09IDM7XG4gICAgfVxuXG4gICAgdmFyIGR1cmF0aW9uID0gdGhpcy5wb2ludHNfW2xhc3RJbmRleCArIDJdIC0gdGhpcy5wb2ludHNfW2ZpcnN0SW5kZXggKyAyXTsgLy8gd2UgZG9uJ3Qgd2FudCBhIGR1cmF0aW9uIG9mIDAgKGRpdmlkZSBieSB6ZXJvKVxuICAgIC8vIHdlIGFsc28gbWFrZSBzdXJlIHRoZSB1c2VyIHBhbm5lZCBmb3IgYSBkdXJhdGlvbiBvZiBhdCBsZWFzdCBvbmUgZnJhbWVcbiAgICAvLyAoMS82MHMpIHRvIGNvbXB1dGUgc2FuZSBkaXNwbGFjZW1lbnQgdmFsdWVzXG5cbiAgICBpZiAoZHVyYXRpb24gPCAxMDAwIC8gNjApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgZHggPSB0aGlzLnBvaW50c19bbGFzdEluZGV4XSAtIHRoaXMucG9pbnRzX1tmaXJzdEluZGV4XTtcbiAgICB2YXIgZHkgPSB0aGlzLnBvaW50c19bbGFzdEluZGV4ICsgMV0gLSB0aGlzLnBvaW50c19bZmlyc3RJbmRleCArIDFdO1xuICAgIHRoaXMuYW5nbGVfID0gTWF0aC5hdGFuMihkeSwgZHgpO1xuICAgIHRoaXMuaW5pdGlhbFZlbG9jaXR5XyA9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSkgLyBkdXJhdGlvbjtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsVmVsb2NpdHlfID4gdGhpcy5taW5WZWxvY2l0eV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRvdGFsIGRpc3RhbmNlIHRyYXZlbGxlZCAocGl4ZWxzKS5cbiAgICovXG5cblxuICBLaW5ldGljLnByb3RvdHlwZS5nZXREaXN0YW5jZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMubWluVmVsb2NpdHlfIC0gdGhpcy5pbml0aWFsVmVsb2NpdHlfKSAvIHRoaXMuZGVjYXlfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBBbmdsZSBvZiB0aGUga2luZXRpYyBwYW5uaW5nIGFuaW1hdGlvbiAocmFkaWFucykuXG4gICAqL1xuXG5cbiAgS2luZXRpYy5wcm90b3R5cGUuZ2V0QW5nbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYW5nbGVfO1xuICB9O1xuXG4gIHJldHVybiBLaW5ldGljO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBLaW5ldGljOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vTW91c2VXaGVlbFpvb21cbiAqL1xuXG5cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgSW50ZXJhY3Rpb24sIHsgem9vbUJ5RGVsdGEgfSBmcm9tICcuL0ludGVyYWN0aW9uLmpzJztcbmltcG9ydCB7IERFVklDRV9QSVhFTF9SQVRJTywgRklSRUZPWCB9IGZyb20gJy4uL2hhcy5qcyc7XG5pbXBvcnQgeyBhbGwsIGFsd2F5cywgZm9jdXNXaXRoVGFiaW5kZXggfSBmcm9tICcuLi9ldmVudHMvY29uZGl0aW9uLmpzJztcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi4vbWF0aC5qcyc7XG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cblxuZXhwb3J0IHZhciBNb2RlID0ge1xuICBUUkFDS1BBRDogJ3RyYWNrcGFkJyxcbiAgV0hFRUw6ICd3aGVlbCdcbn07XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXZlbnRzL2NvbmRpdGlvbi5qc1wiKS5Db25kaXRpb259IFtjb25kaXRpb25dIEEgZnVuY3Rpb24gdGhhdFxuICogdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnR+TWFwQnJvd3NlckV2ZW50fSBhbmQgcmV0dXJucyBhXG4gKiBib29sZWFuIHRvIGluZGljYXRlIHdoZXRoZXIgdGhhdCBldmVudCBzaG91bGQgYmUgaGFuZGxlZC4gRGVmYXVsdCBpc1xuICoge0BsaW5rIG1vZHVsZTpvbC9ldmVudHMvY29uZGl0aW9ufmFsd2F5c30uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvbkZvY3VzT25seT1mYWxzZV0gV2hlbiB0aGUgbWFwJ3MgdGFyZ2V0IGhhcyBhIGB0YWJpbmRleGAgYXR0cmlidXRlIHNldCxcbiAqIHRoZSBpbnRlcmFjdGlvbiB3aWxsIG9ubHkgaGFuZGxlIGV2ZW50cyB3aGVuIHRoZSBtYXAgaGFzIHRoZSBmb2N1cy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4RGVsdGE9MV0gTWF4aW11bSBtb3VzZSB3aGVlbCBkZWx0YS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MjUwXSBBbmltYXRpb24gZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aW1lb3V0PTgwXSBNb3VzZSB3aGVlbCB0aW1lb3V0IGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VzZUFuY2hvcj10cnVlXSBFbmFibGUgem9vbWluZyB1c2luZyB0aGUgbW91c2Unc1xuICogbG9jYXRpb24gYXMgdGhlIGFuY2hvci4gV2hlbiBzZXQgdG8gYGZhbHNlYCwgem9vbWluZyBpbiBhbmQgb3V0IHdpbGwgem9vbSB0b1xuICogdGhlIGNlbnRlciBvZiB0aGUgc2NyZWVuIGluc3RlYWQgb2Ygem9vbWluZyBvbiB0aGUgbW91c2UncyBsb2NhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2NvbnN0cmFpblJlc29sdXRpb249ZmFsc2VdIElmIHRydWUsIHRoZSBtb3VzZSB3aGVlbCB6b29tXG4gKiBldmVudCB3aWxsIGFsd2F5cyBhbmltYXRlIHRvIHRoZSBjbG9zZXN0IHpvb20gbGV2ZWwgYWZ0ZXIgYW4gaW50ZXJhY3Rpb247XG4gKiBmYWxzZSBtZWFucyBpbnRlcm1lZGlhcnkgem9vbSBsZXZlbHMgYXJlIGFsbG93ZWQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gem9vbSB0aGUgbWFwIGJ5IHNjcm9sbGluZyB0aGUgbW91c2Ugd2hlZWwuXG4gKiBAYXBpXG4gKi9cblxudmFyIE1vdXNlV2hlZWxab29tID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE1vdXNlV2hlZWxab29tLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNb3VzZVdoZWVsWm9vbShvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0ludGVyYWN0aW9uLmpzXCIpLkludGVyYWN0aW9uT3B0aW9uc30gKi9cbiAgICBvcHRpb25zKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRvdGFsRGVsdGFfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0RGVsdGFfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhEZWx0YV8gPSBvcHRpb25zLm1heERlbHRhICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heERlbHRhIDogMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5kdXJhdGlvbl8gPSBvcHRpb25zLmR1cmF0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmR1cmF0aW9uIDogMjUwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbWVvdXRfID0gb3B0aW9ucy50aW1lb3V0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpbWVvdXQgOiA4MDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMudXNlQW5jaG9yXyA9IG9wdGlvbnMudXNlQW5jaG9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnVzZUFuY2hvciA6IHRydWU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnN0cmFpblJlc29sdXRpb25fID0gb3B0aW9ucy5jb25zdHJhaW5SZXNvbHV0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbnN0cmFpblJlc29sdXRpb24gOiBmYWxzZTtcbiAgICB2YXIgY29uZGl0aW9uID0gb3B0aW9ucy5jb25kaXRpb24gPyBvcHRpb25zLmNvbmRpdGlvbiA6IGFsd2F5cztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9ldmVudHMvY29uZGl0aW9uLmpzXCIpLkNvbmRpdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbmRpdGlvbl8gPSBvcHRpb25zLm9uRm9jdXNPbmx5ID8gYWxsKGZvY3VzV2l0aFRhYmluZGV4LCBjb25kaXRpb24pIDogY29uZGl0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0QW5jaG9yXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnN0YXJ0VGltZV8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P31cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbWVvdXRJZF87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7TW9kZXx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5tb2RlXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBUcmFja3BhZCBldmVudHMgc2VwYXJhdGVkIGJ5IHRoaXMgZGVsYXkgd2lsbCBiZSBjb25zaWRlcmVkIHNlcGFyYXRlXG4gICAgICogaW50ZXJhY3Rpb25zLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50cmFja3BhZEV2ZW50R2FwXyA9IDQwMDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7P31cbiAgICAgKi9cblxuICAgIF90aGlzLnRyYWNrcGFkVGltZW91dElkXztcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRlbHRhIHZhbHVlcyBwZXIgem9vbSBsZXZlbFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlbHRhUGVyWm9vbV8gPSAzMDA7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIE1vdXNlV2hlZWxab29tLnByb3RvdHlwZS5lbmRJbnRlcmFjdGlvbl8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy50cmFja3BhZFRpbWVvdXRJZF8gPSB1bmRlZmluZWQ7XG4gICAgdmFyIHZpZXcgPSB0aGlzLmdldE1hcCgpLmdldFZpZXcoKTtcbiAgICB2aWV3LmVuZEludGVyYWN0aW9uKHVuZGVmaW5lZCwgdGhpcy5sYXN0RGVsdGFfID8gdGhpcy5sYXN0RGVsdGFfID4gMCA/IDEgOiAtMSA6IDAsIHRoaXMubGFzdEFuY2hvcl8pO1xuICB9O1xuICAvKipcbiAgICogSGFuZGxlcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXBCcm93c2VyRXZlbnQgbWFwIGJyb3dzZXIgZXZlbnR9IChpZiBpdCB3YXMgYSBtb3VzZXdoZWVsLWV2ZW50KSBhbmQgZXZlbnR1YWxseVxuICAgKiB6b29tcyB0aGUgbWFwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgTWFwIGJyb3dzZXIgZXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGBmYWxzZWAgdG8gc3RvcCBldmVudCBwcm9wYWdhdGlvbi5cbiAgICovXG5cblxuICBNb3VzZVdoZWVsWm9vbS5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmNvbmRpdGlvbl8obWFwQnJvd3NlckV2ZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgdmFyIHR5cGUgPSBtYXBCcm93c2VyRXZlbnQudHlwZTtcblxuICAgIGlmICh0eXBlICE9PSBFdmVudFR5cGUuV0hFRUwpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgIHZhciB3aGVlbEV2ZW50ID1cbiAgICAvKiogQHR5cGUge1doZWVsRXZlbnR9ICovXG4gICAgbWFwQnJvd3NlckV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG4gICAgd2hlZWxFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgaWYgKHRoaXMudXNlQW5jaG9yXykge1xuICAgICAgdGhpcy5sYXN0QW5jaG9yXyA9IG1hcEJyb3dzZXJFdmVudC5jb29yZGluYXRlO1xuICAgIH0gLy8gRGVsdGEgbm9ybWFsaXNhdGlvbiBpbnNwaXJlZCBieVxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL2Jsb2IvMDAxYzdiOS9qcy91aS9oYW5kbGVyL3Njcm9sbF96b29tLmpzXG5cblxuICAgIHZhciBkZWx0YTtcblxuICAgIGlmIChtYXBCcm93c2VyRXZlbnQudHlwZSA9PSBFdmVudFR5cGUuV0hFRUwpIHtcbiAgICAgIGRlbHRhID0gd2hlZWxFdmVudC5kZWx0YVk7XG5cbiAgICAgIGlmIChGSVJFRk9YICYmIHdoZWVsRXZlbnQuZGVsdGFNb2RlID09PSBXaGVlbEV2ZW50LkRPTV9ERUxUQV9QSVhFTCkge1xuICAgICAgICBkZWx0YSAvPSBERVZJQ0VfUElYRUxfUkFUSU87XG4gICAgICB9XG5cbiAgICAgIGlmICh3aGVlbEV2ZW50LmRlbHRhTW9kZSA9PT0gV2hlZWxFdmVudC5ET01fREVMVEFfTElORSkge1xuICAgICAgICBkZWx0YSAqPSA0MDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZGVsdGEgPT09IDApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sYXN0RGVsdGFfID0gZGVsdGE7XG4gICAgfVxuXG4gICAgdmFyIG5vdyA9IERhdGUubm93KCk7XG5cbiAgICBpZiAodGhpcy5zdGFydFRpbWVfID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc3RhcnRUaW1lXyA9IG5vdztcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMubW9kZV8gfHwgbm93IC0gdGhpcy5zdGFydFRpbWVfID4gdGhpcy50cmFja3BhZEV2ZW50R2FwXykge1xuICAgICAgdGhpcy5tb2RlXyA9IE1hdGguYWJzKGRlbHRhKSA8IDQgPyBNb2RlLlRSQUNLUEFEIDogTW9kZS5XSEVFTDtcbiAgICB9XG5cbiAgICB2YXIgdmlldyA9IG1hcC5nZXRWaWV3KCk7XG5cbiAgICBpZiAodGhpcy5tb2RlXyA9PT0gTW9kZS5UUkFDS1BBRCAmJiAhKHZpZXcuZ2V0Q29uc3RyYWluUmVzb2x1dGlvbigpIHx8IHRoaXMuY29uc3RyYWluUmVzb2x1dGlvbl8pKSB7XG4gICAgICBpZiAodGhpcy50cmFja3BhZFRpbWVvdXRJZF8pIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudHJhY2twYWRUaW1lb3V0SWRfKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh2aWV3LmdldEFuaW1hdGluZygpKSB7XG4gICAgICAgICAgdmlldy5jYW5jZWxBbmltYXRpb25zKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2aWV3LmJlZ2luSW50ZXJhY3Rpb24oKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy50cmFja3BhZFRpbWVvdXRJZF8gPSBzZXRUaW1lb3V0KHRoaXMuZW5kSW50ZXJhY3Rpb25fLmJpbmQodGhpcyksIHRoaXMudGltZW91dF8pO1xuICAgICAgdmlldy5hZGp1c3Rab29tKC1kZWx0YSAvIHRoaXMuZGVsdGFQZXJab29tXywgdGhpcy5sYXN0QW5jaG9yXyk7XG4gICAgICB0aGlzLnN0YXJ0VGltZV8gPSBub3c7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy50b3RhbERlbHRhXyArPSBkZWx0YTtcbiAgICB2YXIgdGltZUxlZnQgPSBNYXRoLm1heCh0aGlzLnRpbWVvdXRfIC0gKG5vdyAtIHRoaXMuc3RhcnRUaW1lXyksIDApO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRJZF8pO1xuICAgIHRoaXMudGltZW91dElkXyA9IHNldFRpbWVvdXQodGhpcy5oYW5kbGVXaGVlbFpvb21fLmJpbmQodGhpcywgbWFwKSwgdGltZUxlZnQpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAqL1xuXG5cbiAgTW91c2VXaGVlbFpvb20ucHJvdG90eXBlLmhhbmRsZVdoZWVsWm9vbV8gPSBmdW5jdGlvbiAobWFwKSB7XG4gICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gICAgaWYgKHZpZXcuZ2V0QW5pbWF0aW5nKCkpIHtcbiAgICAgIHZpZXcuY2FuY2VsQW5pbWF0aW9ucygpO1xuICAgIH1cblxuICAgIHZhciBkZWx0YSA9IC1jbGFtcCh0aGlzLnRvdGFsRGVsdGFfLCAtdGhpcy5tYXhEZWx0YV8gKiB0aGlzLmRlbHRhUGVyWm9vbV8sIHRoaXMubWF4RGVsdGFfICogdGhpcy5kZWx0YVBlclpvb21fKSAvIHRoaXMuZGVsdGFQZXJab29tXztcblxuICAgIGlmICh2aWV3LmdldENvbnN0cmFpblJlc29sdXRpb24oKSB8fCB0aGlzLmNvbnN0cmFpblJlc29sdXRpb25fKSB7XG4gICAgICAvLyB2aWV3IGhhcyBhIHpvb20gY29uc3RyYWludCwgem9vbSBieSAxXG4gICAgICBkZWx0YSA9IGRlbHRhID8gZGVsdGEgPiAwID8gMSA6IC0xIDogMDtcbiAgICB9XG5cbiAgICB6b29tQnlEZWx0YSh2aWV3LCBkZWx0YSwgdGhpcy5sYXN0QW5jaG9yXywgdGhpcy5kdXJhdGlvbl8pO1xuICAgIHRoaXMubW9kZV8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy50b3RhbERlbHRhXyA9IDA7XG4gICAgdGhpcy5sYXN0QW5jaG9yXyA9IG51bGw7XG4gICAgdGhpcy5zdGFydFRpbWVfID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudGltZW91dElkXyA9IHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEVuYWJsZSBvciBkaXNhYmxlIHVzaW5nIHRoZSBtb3VzZSdzIGxvY2F0aW9uIGFzIGFuIGFuY2hvciB3aGVuIHpvb21pbmdcbiAgICogQHBhcmFtIHtib29sZWFufSB1c2VBbmNob3IgdHJ1ZSB0byB6b29tIHRvIHRoZSBtb3VzZSdzIGxvY2F0aW9uLCBmYWxzZVxuICAgKiB0byB6b29tIHRvIHRoZSBjZW50ZXIgb2YgdGhlIG1hcFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTW91c2VXaGVlbFpvb20ucHJvdG90eXBlLnNldE1vdXNlQW5jaG9yID0gZnVuY3Rpb24gKHVzZUFuY2hvcikge1xuICAgIHRoaXMudXNlQW5jaG9yXyA9IHVzZUFuY2hvcjtcblxuICAgIGlmICghdXNlQW5jaG9yKSB7XG4gICAgICB0aGlzLmxhc3RBbmNob3JfID0gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIE1vdXNlV2hlZWxab29tO1xufShJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IE1vdXNlV2hlZWxab29tOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vUGluY2hSb3RhdGVcbiAqL1xuXG5cbmltcG9ydCBQb2ludGVySW50ZXJhY3Rpb24sIHsgY2VudHJvaWQgYXMgY2VudHJvaWRGcm9tUG9pbnRlcnMgfSBmcm9tICcuL1BvaW50ZXIuanMnO1xuaW1wb3J0IHsgRkFMU0UgfSBmcm9tICcuLi9mdW5jdGlvbnMuanMnO1xuaW1wb3J0IHsgZGlzYWJsZSB9IGZyb20gJy4uL3JvdGF0aW9uY29uc3RyYWludC5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MjUwXSBUaGUgZHVyYXRpb24gb2YgdGhlIGFuaW1hdGlvbiBpblxuICogbWlsbGlzZWNvbmRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aHJlc2hvbGQ9MC4zXSBNaW5pbWFsIGFuZ2xlIGluIHJhZGlhbnMgdG8gc3RhcnQgYSByb3RhdGlvbi5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFsbG93cyB0aGUgdXNlciB0byByb3RhdGUgdGhlIG1hcCBieSB0d2lzdGluZyB3aXRoIHR3byBmaW5nZXJzXG4gKiBvbiBhIHRvdWNoIHNjcmVlbi5cbiAqIEBhcGlcbiAqL1xuXG52YXIgUGluY2hSb3RhdGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUGluY2hSb3RhdGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFBpbmNoUm90YXRlKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIHZhciBwb2ludGVyT3B0aW9ucyA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL1BvaW50ZXIuanNcIikuT3B0aW9uc30gKi9cbiAgICBvcHRpb25zO1xuXG4gICAgaWYgKCFwb2ludGVyT3B0aW9ucy5zdG9wRG93bikge1xuICAgICAgcG9pbnRlck9wdGlvbnMuc3RvcERvd24gPSBGQUxTRTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHBvaW50ZXJPcHRpb25zKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvcl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0QW5nbGVfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5yb3RhdGluZ18gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yb3RhdGlvbkRlbHRhXyA9IDAuMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50aHJlc2hvbGRfID0gb3B0aW9ucy50aHJlc2hvbGQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGhyZXNob2xkIDogMC4zO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmR1cmF0aW9uXyA9IG9wdGlvbnMuZHVyYXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZHVyYXRpb24gOiAyNTA7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkcmFnIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKi9cblxuXG4gIFBpbmNoUm90YXRlLnByb3RvdHlwZS5oYW5kbGVEcmFnRXZlbnQgPSBmdW5jdGlvbiAobWFwQnJvd3NlckV2ZW50KSB7XG4gICAgdmFyIHJvdGF0aW9uRGVsdGEgPSAwLjA7XG4gICAgdmFyIHRvdWNoMCA9IHRoaXMudGFyZ2V0UG9pbnRlcnNbMF07XG4gICAgdmFyIHRvdWNoMSA9IHRoaXMudGFyZ2V0UG9pbnRlcnNbMV07IC8vIGFuZ2xlIGJldHdlZW4gdG91Y2hlc1xuXG4gICAgdmFyIGFuZ2xlID0gTWF0aC5hdGFuMih0b3VjaDEuY2xpZW50WSAtIHRvdWNoMC5jbGllbnRZLCB0b3VjaDEuY2xpZW50WCAtIHRvdWNoMC5jbGllbnRYKTtcblxuICAgIGlmICh0aGlzLmxhc3RBbmdsZV8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIGRlbHRhID0gYW5nbGUgLSB0aGlzLmxhc3RBbmdsZV87XG4gICAgICB0aGlzLnJvdGF0aW9uRGVsdGFfICs9IGRlbHRhO1xuXG4gICAgICBpZiAoIXRoaXMucm90YXRpbmdfICYmIE1hdGguYWJzKHRoaXMucm90YXRpb25EZWx0YV8pID4gdGhpcy50aHJlc2hvbGRfKSB7XG4gICAgICAgIHRoaXMucm90YXRpbmdfID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcm90YXRpb25EZWx0YSA9IGRlbHRhO1xuICAgIH1cblxuICAgIHRoaXMubGFzdEFuZ2xlXyA9IGFuZ2xlO1xuICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmICh2aWV3LmdldENvbnN0cmFpbnRzKCkucm90YXRpb24gPT09IGRpc2FibGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIHJvdGF0ZSBhbmNob3IgcG9pbnQuXG4gICAgLy8gRklYTUU6IHNob3VsZCBiZSB0aGUgaW50ZXJzZWN0aW9uIHBvaW50IGJldHdlZW4gdGhlIGxpbmVzOlxuICAgIC8vICAgICB0b3VjaDAsdG91Y2gxIGFuZCBwcmV2aW91c1RvdWNoMCxwcmV2aW91c1RvdWNoMVxuXG5cbiAgICB2YXIgdmlld3BvcnRQb3NpdGlvbiA9IG1hcC5nZXRWaWV3cG9ydCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBjZW50cm9pZCA9IGNlbnRyb2lkRnJvbVBvaW50ZXJzKHRoaXMudGFyZ2V0UG9pbnRlcnMpO1xuICAgIGNlbnRyb2lkWzBdIC09IHZpZXdwb3J0UG9zaXRpb24ubGVmdDtcbiAgICBjZW50cm9pZFsxXSAtPSB2aWV3cG9ydFBvc2l0aW9uLnRvcDtcbiAgICB0aGlzLmFuY2hvcl8gPSBtYXAuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKGNlbnRyb2lkKTsgLy8gcm90YXRlXG5cbiAgICBpZiAodGhpcy5yb3RhdGluZ18pIHtcbiAgICAgIG1hcC5yZW5kZXIoKTtcbiAgICAgIHZpZXcuYWRqdXN0Um90YXRpb25JbnRlcm5hbChyb3RhdGlvbkRlbHRhLCB0aGlzLmFuY2hvcl8pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIHVwIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIFBpbmNoUm90YXRlLnByb3RvdHlwZS5oYW5kbGVVcEV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICh0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgICAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuICAgICAgdmlldy5lbmRJbnRlcmFjdGlvbih0aGlzLmR1cmF0aW9uXyk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIGRvd24gZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL01hcEJyb3dzZXJFdmVudC5qc1wiKS5kZWZhdWx0fSBtYXBCcm93c2VyRXZlbnQgRXZlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElmIHRoZSBldmVudCB3YXMgY29uc3VtZWQuXG4gICAqL1xuXG5cbiAgUGluY2hSb3RhdGUucHJvdG90eXBlLmhhbmRsZURvd25FdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAodGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPj0gMikge1xuICAgICAgdmFyIG1hcCA9IG1hcEJyb3dzZXJFdmVudC5tYXA7XG4gICAgICB0aGlzLmFuY2hvcl8gPSBudWxsO1xuICAgICAgdGhpcy5sYXN0QW5nbGVfID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5yb3RhdGluZ18gPSBmYWxzZTtcbiAgICAgIHRoaXMucm90YXRpb25EZWx0YV8gPSAwLjA7XG5cbiAgICAgIGlmICghdGhpcy5oYW5kbGluZ0Rvd25VcFNlcXVlbmNlKSB7XG4gICAgICAgIG1hcC5nZXRWaWV3KCkuYmVnaW5JbnRlcmFjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gUGluY2hSb3RhdGU7XG59KFBvaW50ZXJJbnRlcmFjdGlvbik7XG5cbmV4cG9ydCBkZWZhdWx0IFBpbmNoUm90YXRlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvaW50ZXJhY3Rpb24vUGluY2hab29tXG4gKi9cblxuXG5pbXBvcnQgUG9pbnRlckludGVyYWN0aW9uLCB7IGNlbnRyb2lkIGFzIGNlbnRyb2lkRnJvbVBvaW50ZXJzIH0gZnJvbSAnLi9Qb2ludGVyLmpzJztcbmltcG9ydCB7IEZBTFNFIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkdXJhdGlvbj00MDBdIEFuaW1hdGlvbiBkdXJhdGlvbiBpbiBtaWxsaXNlY29uZHMuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBbGxvd3MgdGhlIHVzZXIgdG8gem9vbSB0aGUgbWFwIGJ5IHBpbmNoaW5nIHdpdGggdHdvIGZpbmdlcnNcbiAqIG9uIGEgdG91Y2ggc2NyZWVuLlxuICogQGFwaVxuICovXG5cbnZhciBQaW5jaFpvb20gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUGluY2hab29tLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBQaW5jaFpvb20ob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyA/IG9wdF9vcHRpb25zIDoge307XG4gICAgdmFyIHBvaW50ZXJPcHRpb25zID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vUG9pbnRlci5qc1wiKS5PcHRpb25zfSAqL1xuICAgIG9wdGlvbnM7XG5cbiAgICBpZiAoIXBvaW50ZXJPcHRpb25zLnN0b3BEb3duKSB7XG4gICAgICBwb2ludGVyT3B0aW9ucy5zdG9wRG93biA9IEZBTFNFO1xuICAgIH1cblxuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgcG9pbnRlck9wdGlvbnMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZHVyYXRpb25fID0gb3B0aW9ucy5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kdXJhdGlvbiA6IDQwMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMubGFzdERpc3RhbmNlXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXN0U2NhbGVEZWx0YV8gPSAxO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogSGFuZGxlIHBvaW50ZXIgZHJhZyBldmVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vTWFwQnJvd3NlckV2ZW50LmpzXCIpLmRlZmF1bHR9IG1hcEJyb3dzZXJFdmVudCBFdmVudC5cbiAgICovXG5cblxuICBQaW5jaFpvb20ucHJvdG90eXBlLmhhbmRsZURyYWdFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICB2YXIgc2NhbGVEZWx0YSA9IDEuMDtcbiAgICB2YXIgdG91Y2gwID0gdGhpcy50YXJnZXRQb2ludGVyc1swXTtcbiAgICB2YXIgdG91Y2gxID0gdGhpcy50YXJnZXRQb2ludGVyc1sxXTtcbiAgICB2YXIgZHggPSB0b3VjaDAuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYO1xuICAgIHZhciBkeSA9IHRvdWNoMC5jbGllbnRZIC0gdG91Y2gxLmNsaWVudFk7IC8vIGRpc3RhbmNlIGJldHdlZW4gdG91Y2hlc1xuXG4gICAgdmFyIGRpc3RhbmNlID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcblxuICAgIGlmICh0aGlzLmxhc3REaXN0YW5jZV8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2NhbGVEZWx0YSA9IHRoaXMubGFzdERpc3RhbmNlXyAvIGRpc3RhbmNlO1xuICAgIH1cblxuICAgIHRoaXMubGFzdERpc3RhbmNlXyA9IGRpc3RhbmNlO1xuICAgIHZhciBtYXAgPSBtYXBCcm93c2VyRXZlbnQubWFwO1xuICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcblxuICAgIGlmIChzY2FsZURlbHRhICE9IDEuMCkge1xuICAgICAgdGhpcy5sYXN0U2NhbGVEZWx0YV8gPSBzY2FsZURlbHRhO1xuICAgIH0gLy8gc2NhbGUgYW5jaG9yIHBvaW50LlxuXG5cbiAgICB2YXIgdmlld3BvcnRQb3NpdGlvbiA9IG1hcC5nZXRWaWV3cG9ydCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBjZW50cm9pZCA9IGNlbnRyb2lkRnJvbVBvaW50ZXJzKHRoaXMudGFyZ2V0UG9pbnRlcnMpO1xuICAgIGNlbnRyb2lkWzBdIC09IHZpZXdwb3J0UG9zaXRpb24ubGVmdDtcbiAgICBjZW50cm9pZFsxXSAtPSB2aWV3cG9ydFBvc2l0aW9uLnRvcDtcbiAgICB0aGlzLmFuY2hvcl8gPSBtYXAuZ2V0Q29vcmRpbmF0ZUZyb21QaXhlbEludGVybmFsKGNlbnRyb2lkKTsgLy8gc2NhbGUsIGJ5cGFzcyB0aGUgcmVzb2x1dGlvbiBjb25zdHJhaW50XG5cbiAgICBtYXAucmVuZGVyKCk7XG4gICAgdmlldy5hZGp1c3RSZXNvbHV0aW9uSW50ZXJuYWwoc2NhbGVEZWx0YSwgdGhpcy5hbmNob3JfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEhhbmRsZSBwb2ludGVyIHVwIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIFBpbmNoWm9vbS5wcm90b3R5cGUuaGFuZGxlVXBFdmVudCA9IGZ1bmN0aW9uIChtYXBCcm93c2VyRXZlbnQpIHtcbiAgICBpZiAodGhpcy50YXJnZXRQb2ludGVycy5sZW5ndGggPCAyKSB7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIHZhciB2aWV3ID0gbWFwLmdldFZpZXcoKTtcbiAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLmxhc3RTY2FsZURlbHRhXyA+IDEgPyAxIDogLTE7XG4gICAgICB2aWV3LmVuZEludGVyYWN0aW9uKHRoaXMuZHVyYXRpb25fLCBkaXJlY3Rpb24pO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgcG9pbnRlciBkb3duIGV2ZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9NYXBCcm93c2VyRXZlbnQuanNcIikuZGVmYXVsdH0gbWFwQnJvd3NlckV2ZW50IEV2ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJZiB0aGUgZXZlbnQgd2FzIGNvbnN1bWVkLlxuICAgKi9cblxuXG4gIFBpbmNoWm9vbS5wcm90b3R5cGUuaGFuZGxlRG93bkV2ZW50ID0gZnVuY3Rpb24gKG1hcEJyb3dzZXJFdmVudCkge1xuICAgIGlmICh0aGlzLnRhcmdldFBvaW50ZXJzLmxlbmd0aCA+PSAyKSB7XG4gICAgICB2YXIgbWFwID0gbWFwQnJvd3NlckV2ZW50Lm1hcDtcbiAgICAgIHRoaXMuYW5jaG9yXyA9IG51bGw7XG4gICAgICB0aGlzLmxhc3REaXN0YW5jZV8gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmxhc3RTY2FsZURlbHRhXyA9IDE7XG5cbiAgICAgIGlmICghdGhpcy5oYW5kbGluZ0Rvd25VcFNlcXVlbmNlKSB7XG4gICAgICAgIG1hcC5nZXRWaWV3KCkuYmVnaW5JbnRlcmFjdGlvbigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gUGluY2hab29tO1xufShQb2ludGVySW50ZXJhY3Rpb24pO1xuXG5leHBvcnQgZGVmYXVsdCBQaW5jaFpvb207IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2ludGVyYWN0aW9uXG4gKi9cbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gJy4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgRG91YmxlQ2xpY2tab29tIGZyb20gJy4vaW50ZXJhY3Rpb24vRG91YmxlQ2xpY2tab29tLmpzJztcbmltcG9ydCBEcmFnUGFuIGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1Bhbi5qcyc7XG5pbXBvcnQgRHJhZ1JvdGF0ZSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdSb3RhdGUuanMnO1xuaW1wb3J0IERyYWdab29tIGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ1pvb20uanMnO1xuaW1wb3J0IEtleWJvYXJkUGFuIGZyb20gJy4vaW50ZXJhY3Rpb24vS2V5Ym9hcmRQYW4uanMnO1xuaW1wb3J0IEtleWJvYXJkWm9vbSBmcm9tICcuL2ludGVyYWN0aW9uL0tleWJvYXJkWm9vbS5qcyc7XG5pbXBvcnQgS2luZXRpYyBmcm9tICcuL0tpbmV0aWMuanMnO1xuaW1wb3J0IE1vdXNlV2hlZWxab29tIGZyb20gJy4vaW50ZXJhY3Rpb24vTW91c2VXaGVlbFpvb20uanMnO1xuaW1wb3J0IFBpbmNoUm90YXRlIGZyb20gJy4vaW50ZXJhY3Rpb24vUGluY2hSb3RhdGUuanMnO1xuaW1wb3J0IFBpbmNoWm9vbSBmcm9tICcuL2ludGVyYWN0aW9uL1BpbmNoWm9vbS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIERvdWJsZUNsaWNrWm9vbSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRG91YmxlQ2xpY2tab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhZ0FuZERyb3AgfSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdBbmREcm9wLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhZ0JveCB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhZ0JveC5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIERyYWdQYW4gfSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdQYW4uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBEcmFnUm90YXRlIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9EcmFnUm90YXRlLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhZ1JvdGF0ZUFuZFpvb20gfSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdSb3RhdGVBbmRab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhZ1pvb20gfSBmcm9tICcuL2ludGVyYWN0aW9uL0RyYWdab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgRHJhdyB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRHJhdy5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIEV4dGVudCB9IGZyb20gJy4vaW50ZXJhY3Rpb24vRXh0ZW50LmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgSW50ZXJhY3Rpb24gfSBmcm9tICcuL2ludGVyYWN0aW9uL0ludGVyYWN0aW9uLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgS2V5Ym9hcmRQYW4gfSBmcm9tICcuL2ludGVyYWN0aW9uL0tleWJvYXJkUGFuLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgS2V5Ym9hcmRab29tIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9LZXlib2FyZFpvb20uanMnO1xuZXhwb3J0IHsgZGVmYXVsdCBhcyBNb2RpZnkgfSBmcm9tICcuL2ludGVyYWN0aW9uL01vZGlmeS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIE1vdXNlV2hlZWxab29tIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9Nb3VzZVdoZWVsWm9vbS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFBpbmNoUm90YXRlIH0gZnJvbSAnLi9pbnRlcmFjdGlvbi9QaW5jaFJvdGF0ZS5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFBpbmNoWm9vbSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vUGluY2hab29tLmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgUG9pbnRlciB9IGZyb20gJy4vaW50ZXJhY3Rpb24vUG9pbnRlci5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFNlbGVjdCB9IGZyb20gJy4vaW50ZXJhY3Rpb24vU2VsZWN0LmpzJztcbmV4cG9ydCB7IGRlZmF1bHQgYXMgU25hcCB9IGZyb20gJy4vaW50ZXJhY3Rpb24vU25hcC5qcyc7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFRyYW5zbGF0ZSB9IGZyb20gJy4vaW50ZXJhY3Rpb24vVHJhbnNsYXRlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRGVmYXVsdHNPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthbHRTaGlmdERyYWdSb3RhdGU9dHJ1ZV0gV2hldGhlciBBbHQtU2hpZnQtZHJhZyByb3RhdGUgaXNcbiAqIGRlc2lyZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvbkZvY3VzT25seT1mYWxzZV0gSW50ZXJhY3Qgb25seSB3aGVuIHRoZSBtYXAgaGFzIHRoZVxuICogZm9jdXMuIFRoaXMgYWZmZWN0cyB0aGUgYE1vdXNlV2hlZWxab29tYCBhbmQgYERyYWdQYW5gIGludGVyYWN0aW9ucyBhbmQgaXNcbiAqIHVzZWZ1bCB3aGVuIHBhZ2Ugc2Nyb2xsIGlzIGRlc2lyZWQgZm9yIG1hcHMgdGhhdCBkbyBub3QgaGF2ZSB0aGUgYnJvd3NlcidzXG4gKiBmb2N1cy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RvdWJsZUNsaWNrWm9vbT10cnVlXSBXaGV0aGVyIGRvdWJsZSBjbGljayB6b29tIGlzXG4gKiBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBba2V5Ym9hcmQ9dHJ1ZV0gV2hldGhlciBrZXlib2FyZCBpbnRlcmFjdGlvbiBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbbW91c2VXaGVlbFpvb209dHJ1ZV0gV2hldGhlciBtb3VzZXdoZWVsIHpvb20gaXMgZGVzaXJlZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3NoaWZ0RHJhZ1pvb209dHJ1ZV0gV2hldGhlciBTaGlmdC1kcmFnIHpvb20gaXMgZGVzaXJlZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RyYWdQYW49dHJ1ZV0gV2hldGhlciBkcmFnIHBhbiBpcyBkZXNpcmVkLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcGluY2hSb3RhdGU9dHJ1ZV0gV2hldGhlciBwaW5jaCByb3RhdGUgaXMgZGVzaXJlZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3BpbmNoWm9vbT10cnVlXSBXaGV0aGVyIHBpbmNoIHpvb20gaXMgZGVzaXJlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbem9vbURlbHRhXSBab29tIGxldmVsIGRlbHRhIHdoZW4gdXNpbmcga2V5Ym9hcmQgb3IgZG91YmxlIGNsaWNrIHpvb20uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pvb21EdXJhdGlvbl0gRHVyYXRpb24gb2YgdGhlIHpvb20gYW5pbWF0aW9uIGluXG4gKiBtaWxsaXNlY29uZHMuXG4gKi9cblxuLyoqXG4gKiBTZXQgb2YgaW50ZXJhY3Rpb25zIGluY2x1ZGVkIGluIG1hcHMgYnkgZGVmYXVsdC4gU3BlY2lmaWMgaW50ZXJhY3Rpb25zIGNhbiBiZVxuICogZXhjbHVkZWQgYnkgc2V0dGluZyB0aGUgYXBwcm9wcmlhdGUgb3B0aW9uIHRvIGZhbHNlIGluIHRoZSBjb25zdHJ1Y3RvclxuICogb3B0aW9ucywgYnV0IHRoZSBvcmRlciBvZiB0aGUgaW50ZXJhY3Rpb25zIGlzIGZpeGVkLiAgSWYgeW91IHdhbnQgdG8gc3BlY2lmeVxuICogYSBkaWZmZXJlbnQgb3JkZXIgZm9yIGludGVyYWN0aW9ucywgeW91IHdpbGwgbmVlZCB0byBjcmVhdGUgeW91ciBvd25cbiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb259IGluc3RhbmNlcyBhbmQgaW5zZXJ0XG4gKiB0aGVtIGludG8gYSB7QGxpbmsgbW9kdWxlOm9sL0NvbGxlY3Rpb259IGluIHRoZSBvcmRlciB5b3Ugd2FudFxuICogYmVmb3JlIGNyZWF0aW5nIHlvdXIge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwfSBpbnN0YW5jZS4gQ2hhbmdpbmcgdGhlIG9yZGVyIGNhblxuICogYmUgb2YgaW50ZXJlc3QgaWYgdGhlIGV2ZW50IHByb3BhZ2F0aW9uIG5lZWRzIHRvIGJlIHN0b3BwZWQgYXQgYSBwb2ludC5cbiAqIFRoZSBkZWZhdWx0IHNldCBvZiBpbnRlcmFjdGlvbnMsIGluIHNlcXVlbmNlLCBpczpcbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9EcmFnUm90YXRlfkRyYWdSb3RhdGV9XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vRG91YmxlQ2xpY2tab29tfkRvdWJsZUNsaWNrWm9vbX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9EcmFnUGFufkRyYWdQYW59XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vUGluY2hSb3RhdGV+UGluY2hSb3RhdGV9XG4gKiAqIHtAbGluayBtb2R1bGU6b2wvaW50ZXJhY3Rpb24vUGluY2hab29tflBpbmNoWm9vbX1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9LZXlib2FyZFBhbn5LZXlib2FyZFBhbn1cbiAqICoge0BsaW5rIG1vZHVsZTpvbC9pbnRlcmFjdGlvbi9LZXlib2FyZFpvb21+S2V5Ym9hcmRab29tfVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL01vdXNlV2hlZWxab29tfk1vdXNlV2hlZWxab29tfVxuICogKiB7QGxpbmsgbW9kdWxlOm9sL2ludGVyYWN0aW9uL0RyYWdab29tfkRyYWdab29tfVxuICpcbiAqIEBwYXJhbSB7RGVmYXVsdHNPcHRpb25zPX0gb3B0X29wdGlvbnMgRGVmYXVsdHMgb3B0aW9ucy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vQ29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0PGltcG9ydChcIi4vaW50ZXJhY3Rpb24vSW50ZXJhY3Rpb24uanNcIikuZGVmYXVsdD59XG4gKiBBIGNvbGxlY3Rpb24gb2YgaW50ZXJhY3Rpb25zIHRvIGJlIHVzZWQgd2l0aCB0aGUge0BsaW5rIG1vZHVsZTpvbC9NYXB+TWFwfVxuICogY29uc3RydWN0b3IncyBgaW50ZXJhY3Rpb25zYCBvcHRpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRzKG9wdF9vcHRpb25zKSB7XG4gIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICB2YXIgaW50ZXJhY3Rpb25zID0gbmV3IENvbGxlY3Rpb24oKTtcbiAgdmFyIGtpbmV0aWMgPSBuZXcgS2luZXRpYygtMC4wMDUsIDAuMDUsIDEwMCk7XG4gIHZhciBhbHRTaGlmdERyYWdSb3RhdGUgPSBvcHRpb25zLmFsdFNoaWZ0RHJhZ1JvdGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hbHRTaGlmdERyYWdSb3RhdGUgOiB0cnVlO1xuXG4gIGlmIChhbHRTaGlmdERyYWdSb3RhdGUpIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgRHJhZ1JvdGF0ZSgpKTtcbiAgfVxuXG4gIHZhciBkb3VibGVDbGlja1pvb20gPSBvcHRpb25zLmRvdWJsZUNsaWNrWm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5kb3VibGVDbGlja1pvb20gOiB0cnVlO1xuXG4gIGlmIChkb3VibGVDbGlja1pvb20pIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgRG91YmxlQ2xpY2tab29tKHtcbiAgICAgIGRlbHRhOiBvcHRpb25zLnpvb21EZWx0YSxcbiAgICAgIGR1cmF0aW9uOiBvcHRpb25zLnpvb21EdXJhdGlvblxuICAgIH0pKTtcbiAgfVxuXG4gIHZhciBkcmFnUGFuID0gb3B0aW9ucy5kcmFnUGFuICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmRyYWdQYW4gOiB0cnVlO1xuXG4gIGlmIChkcmFnUGFuKSB7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IERyYWdQYW4oe1xuICAgICAgb25Gb2N1c09ubHk6IG9wdGlvbnMub25Gb2N1c09ubHksXG4gICAgICBraW5ldGljOiBraW5ldGljXG4gICAgfSkpO1xuICB9XG5cbiAgdmFyIHBpbmNoUm90YXRlID0gb3B0aW9ucy5waW5jaFJvdGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5waW5jaFJvdGF0ZSA6IHRydWU7XG5cbiAgaWYgKHBpbmNoUm90YXRlKSB7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IFBpbmNoUm90YXRlKCkpO1xuICB9XG5cbiAgdmFyIHBpbmNoWm9vbSA9IG9wdGlvbnMucGluY2hab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnBpbmNoWm9vbSA6IHRydWU7XG5cbiAgaWYgKHBpbmNoWm9vbSkge1xuICAgIGludGVyYWN0aW9ucy5wdXNoKG5ldyBQaW5jaFpvb20oe1xuICAgICAgZHVyYXRpb246IG9wdGlvbnMuem9vbUR1cmF0aW9uXG4gICAgfSkpO1xuICB9XG5cbiAgdmFyIGtleWJvYXJkID0gb3B0aW9ucy5rZXlib2FyZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5rZXlib2FyZCA6IHRydWU7XG5cbiAgaWYgKGtleWJvYXJkKSB7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IEtleWJvYXJkUGFuKCkpO1xuICAgIGludGVyYWN0aW9ucy5wdXNoKG5ldyBLZXlib2FyZFpvb20oe1xuICAgICAgZGVsdGE6IG9wdGlvbnMuem9vbURlbHRhLFxuICAgICAgZHVyYXRpb246IG9wdGlvbnMuem9vbUR1cmF0aW9uXG4gICAgfSkpO1xuICB9XG5cbiAgdmFyIG1vdXNlV2hlZWxab29tID0gb3B0aW9ucy5tb3VzZVdoZWVsWm9vbSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tb3VzZVdoZWVsWm9vbSA6IHRydWU7XG5cbiAgaWYgKG1vdXNlV2hlZWxab29tKSB7XG4gICAgaW50ZXJhY3Rpb25zLnB1c2gobmV3IE1vdXNlV2hlZWxab29tKHtcbiAgICAgIG9uRm9jdXNPbmx5OiBvcHRpb25zLm9uRm9jdXNPbmx5LFxuICAgICAgZHVyYXRpb246IG9wdGlvbnMuem9vbUR1cmF0aW9uXG4gICAgfSkpO1xuICB9XG5cbiAgdmFyIHNoaWZ0RHJhZ1pvb20gPSBvcHRpb25zLnNoaWZ0RHJhZ1pvb20gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2hpZnREcmFnWm9vbSA6IHRydWU7XG5cbiAgaWYgKHNoaWZ0RHJhZ1pvb20pIHtcbiAgICBpbnRlcmFjdGlvbnMucHVzaChuZXcgRHJhZ1pvb20oe1xuICAgICAgZHVyYXRpb246IG9wdGlvbnMuem9vbUR1cmF0aW9uXG4gICAgfSkpO1xuICB9XG5cbiAgcmV0dXJuIGludGVyYWN0aW9ucztcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL01hcFxuICovXG5cblxuaW1wb3J0IENvbXBvc2l0ZU1hcFJlbmRlcmVyIGZyb20gJy4vcmVuZGVyZXIvQ29tcG9zaXRlLmpzJztcbmltcG9ydCBQbHVnZ2FibGVNYXAgZnJvbSAnLi9QbHVnZ2FibGVNYXAuanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi9vYmouanMnO1xuaW1wb3J0IHsgZGVmYXVsdHMgYXMgZGVmYXVsdENvbnRyb2xzIH0gZnJvbSAnLi9jb250cm9sLmpzJztcbmltcG9ydCB7IGRlZmF1bHRzIGFzIGRlZmF1bHRJbnRlcmFjdGlvbnMgfSBmcm9tICcuL2ludGVyYWN0aW9uLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogVGhlIG1hcCBpcyB0aGUgY29yZSBjb21wb25lbnQgb2YgT3BlbkxheWVycy4gRm9yIGEgbWFwIHRvIHJlbmRlciwgYSB2aWV3LFxuICogb25lIG9yIG1vcmUgbGF5ZXJzLCBhbmQgYSB0YXJnZXQgY29udGFpbmVyIGFyZSBuZWVkZWQ6XG4gKlxuICogICAgIGltcG9ydCBNYXAgZnJvbSAnb2wvTWFwJztcbiAqICAgICBpbXBvcnQgVmlldyBmcm9tICdvbC9WaWV3JztcbiAqICAgICBpbXBvcnQgVGlsZUxheWVyIGZyb20gJ29sL2xheWVyL1RpbGUnO1xuICogICAgIGltcG9ydCBPU00gZnJvbSAnb2wvc291cmNlL09TTSc7XG4gKlxuICogICAgIHZhciBtYXAgPSBuZXcgTWFwKHtcbiAqICAgICAgIHZpZXc6IG5ldyBWaWV3KHtcbiAqICAgICAgICAgY2VudGVyOiBbMCwgMF0sXG4gKiAgICAgICAgIHpvb206IDFcbiAqICAgICAgIH0pLFxuICogICAgICAgbGF5ZXJzOiBbXG4gKiAgICAgICAgIG5ldyBUaWxlTGF5ZXIoe1xuICogICAgICAgICAgIHNvdXJjZTogbmV3IE9TTSgpXG4gKiAgICAgICAgIH0pXG4gKiAgICAgICBdLFxuICogICAgICAgdGFyZ2V0OiAnbWFwJ1xuICogICAgIH0pO1xuICpcbiAqIFRoZSBhYm92ZSBzbmlwcGV0IGNyZWF0ZXMgYSBtYXAgdXNpbmcgYSB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL1RpbGV9IHRvXG4gKiBkaXNwbGF5IHtAbGluayBtb2R1bGU6b2wvc291cmNlL09TTX5PU019IE9TTSBkYXRhIGFuZCByZW5kZXIgaXQgdG8gYSBET01cbiAqIGVsZW1lbnQgd2l0aCB0aGUgaWQgYG1hcGAuXG4gKlxuICogVGhlIGNvbnN0cnVjdG9yIHBsYWNlcyBhIHZpZXdwb3J0IGNvbnRhaW5lciAod2l0aCBDU1MgY2xhc3MgbmFtZVxuICogYG9sLXZpZXdwb3J0YCkgaW4gdGhlIHRhcmdldCBlbGVtZW50IChzZWUgYGdldFZpZXdwb3J0KClgKSwgYW5kIHRoZW4gdHdvXG4gKiBmdXJ0aGVyIGVsZW1lbnRzIHdpdGhpbiB0aGUgdmlld3BvcnQ6IG9uZSB3aXRoIENTUyBjbGFzcyBuYW1lXG4gKiBgb2wtb3ZlcmxheWNvbnRhaW5lci1zdG9wZXZlbnRgIGZvciBjb250cm9scyBhbmQgc29tZSBvdmVybGF5cywgYW5kIG9uZSB3aXRoXG4gKiBDU1MgY2xhc3MgbmFtZSBgb2wtb3ZlcmxheWNvbnRhaW5lcmAgZm9yIG90aGVyIG92ZXJsYXlzIChzZWUgdGhlIGBzdG9wRXZlbnRgXG4gKiBvcHRpb24gb2Yge0BsaW5rIG1vZHVsZTpvbC9PdmVybGF5fk92ZXJsYXl9IGZvciB0aGUgZGlmZmVyZW5jZSkuIFRoZSBtYXBcbiAqIGl0c2VsZiBpcyBwbGFjZWQgaW4gYSBmdXJ0aGVyIGVsZW1lbnQgd2l0aGluIHRoZSB2aWV3cG9ydC5cbiAqXG4gKiBMYXllcnMgYXJlIHN0b3JlZCBhcyBhIHtAbGluayBtb2R1bGU6b2wvQ29sbGVjdGlvbn5Db2xsZWN0aW9ufSBpblxuICogbGF5ZXJHcm91cHMuIEEgdG9wLWxldmVsIGdyb3VwIGlzIHByb3ZpZGVkIGJ5IHRoZSBsaWJyYXJ5LiBUaGlzIGlzIHdoYXQgaXNcbiAqIGFjY2Vzc2VkIGJ5IGBnZXRMYXllckdyb3VwYCBhbmQgYHNldExheWVyR3JvdXBgLiBMYXllcnMgZW50ZXJlZCBpbiB0aGVcbiAqIG9wdGlvbnMgYXJlIGFkZGVkIHRvIHRoaXMgZ3JvdXAsIGFuZCBgYWRkTGF5ZXJgIGFuZCBgcmVtb3ZlTGF5ZXJgIGNoYW5nZSB0aGVcbiAqIGxheWVyIGNvbGxlY3Rpb24gaW4gdGhlIGdyb3VwLiBgZ2V0TGF5ZXJzYCBpcyBhIGNvbnZlbmllbmNlIGZ1bmN0aW9uIGZvclxuICogYGdldExheWVyR3JvdXAoKS5nZXRMYXllcnMoKWAuIE5vdGUgdGhhdCB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0dyb3Vwfkdyb3VwfVxuICogaXMgYSBzdWJjbGFzcyBvZiB7QGxpbmsgbW9kdWxlOm9sL2xheWVyL0Jhc2V9LCBzbyBsYXllcnMgZW50ZXJlZCBpbiB0aGVcbiAqIG9wdGlvbnMgb3IgYWRkZWQgd2l0aCBgYWRkTGF5ZXJgIGNhbiBiZSBncm91cHMsIHdoaWNoIGNhbiBjb250YWluIGZ1cnRoZXJcbiAqIGdyb3VwcywgYW5kIHNvIG9uLlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgTWFwID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE1hcCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuTWFwT3B0aW9uc30gb3B0aW9ucyBNYXAgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNYXAob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRpb25zKTtcblxuICAgIGlmICghb3B0aW9ucy5jb250cm9scykge1xuICAgICAgb3B0aW9ucy5jb250cm9scyA9IGRlZmF1bHRDb250cm9scygpO1xuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy5pbnRlcmFjdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMuaW50ZXJhY3Rpb25zID0gZGVmYXVsdEludGVyYWN0aW9ucyh7XG4gICAgICAgIG9uRm9jdXNPbmx5OiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIG9wdGlvbnMpIHx8IHRoaXM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgTWFwLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IENvbXBvc2l0ZU1hcFJlbmRlcmVyKHRoaXMpO1xuICB9O1xuXG4gIHJldHVybiBNYXA7XG59KFBsdWdnYWJsZU1hcCk7XG5cbmV4cG9ydCBkZWZhdWx0IE1hcDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvSW1hZ2VTdGF0ZVxuICovXG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBJRExFOiAwLFxuICBMT0FESU5HOiAxLFxuICBMT0FERUQ6IDIsXG4gIEVSUk9SOiAzLFxuICBFTVBUWTogNFxufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3R5bGUvSW1hZ2VcbiAqL1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4uL3NpemUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gb3BhY2l0eVxuICogQHByb3BlcnR5IHtib29sZWFufSByb3RhdGVXaXRoVmlld1xuICogQHByb3BlcnR5IHtudW1iZXJ9IHJvdGF0aW9uXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IHNjYWxlXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IGRpc3BsYWNlbWVudFxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQSBiYXNlIGNsYXNzIHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdCBpbnN0YW50aWF0ZWQgaW5cbiAqIGFwcHMuIEJhc2UgY2xhc3MgZm9yIHtAbGluayBtb2R1bGU6b2wvc3R5bGUvSWNvbn5JY29ufSwge0BsaW5rIG1vZHVsZTpvbC9zdHlsZS9DaXJjbGV+Q2lyY2xlU3R5bGV9IGFuZFxuICoge0BsaW5rIG1vZHVsZTpvbC9zdHlsZS9SZWd1bGFyU2hhcGV+UmVndWxhclNoYXBlfS5cbiAqIEBhYnN0cmFjdFxuICogQGFwaVxuICovXG5cbnZhciBJbWFnZVN0eWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cbiAgZnVuY3Rpb24gSW1hZ2VTdHlsZShvcHRpb25zKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMub3BhY2l0eV8gPSBvcHRpb25zLm9wYWNpdHk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHRoaXMucm90YXRlV2l0aFZpZXdfID0gb3B0aW9ucy5yb3RhdGVXaXRoVmlldztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLnJvdGF0aW9uXyA9IG9wdGlvbnMucm90YXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIHRoaXMuc2NhbGVfID0gb3B0aW9ucy5zY2FsZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICB0aGlzLnNjYWxlQXJyYXlfID0gdG9TaXplKG9wdGlvbnMuc2NhbGUpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLmRpc3BsYWNlbWVudF8gPSBvcHRpb25zLmRpc3BsYWNlbWVudDtcbiAgfVxuICAvKipcbiAgICogQ2xvbmVzIHRoZSBzdHlsZS5cbiAgICogQHJldHVybiB7SW1hZ2VTdHlsZX0gVGhlIGNsb25lZCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoKTtcbiAgICByZXR1cm4gbmV3IEltYWdlU3R5bGUoe1xuICAgICAgb3BhY2l0eTogdGhpcy5nZXRPcGFjaXR5KCksXG4gICAgICBzY2FsZTogQXJyYXkuaXNBcnJheShzY2FsZSkgPyBzY2FsZS5zbGljZSgpIDogc2NhbGUsXG4gICAgICByb3RhdGlvbjogdGhpcy5nZXRSb3RhdGlvbigpLFxuICAgICAgcm90YXRlV2l0aFZpZXc6IHRoaXMuZ2V0Um90YXRlV2l0aFZpZXcoKSxcbiAgICAgIGRpc3BsYWNlbWVudDogdGhpcy5nZXREaXNwbGFjZW1lbnQoKS5zbGljZSgpXG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN5bWJvbGl6ZXIgb3BhY2l0eS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBPcGFjaXR5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0T3BhY2l0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vcGFjaXR5XztcbiAgfTtcbiAgLyoqXG4gICAqIERldGVybWluZSB3aGV0aGVyIHRoZSBzeW1ib2xpemVyIHJvdGF0ZXMgd2l0aCB0aGUgbWFwLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBSb3RhdGUgd2l0aCBtYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRSb3RhdGVXaXRoVmlldyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3RhdGVXaXRoVmlld187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN5bW9ibGl6ZXIgcm90YXRpb24uXG4gICAqIEByZXR1cm4ge251bWJlcn0gUm90YXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRSb3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3RhdGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN5bWJvbGl6ZXIgc2NhbGUuXG4gICAqIEByZXR1cm4ge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFNjYWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0U2NhbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2NhbGVfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzeW1ib2xpemVyIHNjYWxlIGFycmF5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFNjYWxlIGFycmF5LlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldFNjYWxlQXJyYXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2NhbGVBcnJheV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGRpc3BsYWNlbWVudCBvZiB0aGUgc2hhcGVcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gU2hhcGUncyBjZW50ZXIgZGlzcGxhY2VtZW50XG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXREaXNwbGFjZW1lbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGxhY2VtZW50XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgYW5jaG9yIHBvaW50IGluIHBpeGVscy4gVGhlIGFuY2hvciBkZXRlcm1pbmVzIHRoZSBjZW50ZXIgcG9pbnQgZm9yIHRoZVxuICAgKiBzeW1ib2xpemVyLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gQW5jaG9yLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldEFuY2hvciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgaW1hZ2UgZWxlbWVudCBmb3IgdGhlIHN5bWJvbGl6ZXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fSBJbWFnZSBlbGVtZW50LlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR9IEltYWdlIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qXG4gICAqIEdldCB0aGUgaW1hZ2UgcGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuZ2V0UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgcmV0dXJuIDE7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBJbWFnZSBzdGF0ZS5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRJbWFnZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gSW1hZ2Ugc2l6ZS5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRJbWFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBTaXplIG9mIHRoZSBoaXQtZGV0ZWN0aW9uIGltYWdlLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldEhpdERldGVjdGlvbkltYWdlU2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgb3JpZ2luIG9mIHRoZSBzeW1ib2xpemVyLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3JpZ2luLlxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmdldE9yaWdpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc2l6ZSBvZiB0aGUgc3ltYm9saXplciAoaW4gcGl4ZWxzKS5cbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2l6ZS5cbiAgICovXG5cblxuICBJbWFnZVN0eWxlLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBvcGFjaXR5LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3BhY2l0eSBPcGFjaXR5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuc2V0T3BhY2l0eSA9IGZ1bmN0aW9uIChvcGFjaXR5KSB7XG4gICAgdGhpcy5vcGFjaXR5XyA9IG9wYWNpdHk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgd2hldGhlciB0byByb3RhdGUgdGhlIHN0eWxlIHdpdGggdGhlIHZpZXcuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcm90YXRlV2l0aFZpZXcgUm90YXRlIHdpdGggbWFwLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuc2V0Um90YXRlV2l0aFZpZXcgPSBmdW5jdGlvbiAocm90YXRlV2l0aFZpZXcpIHtcbiAgICB0aGlzLnJvdGF0ZVdpdGhWaWV3XyA9IHJvdGF0ZVdpdGhWaWV3O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSByb3RhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUuc2V0Um90YXRpb24gPSBmdW5jdGlvbiAocm90YXRpb24pIHtcbiAgICB0aGlzLnJvdGF0aW9uXyA9IHJvdGF0aW9uO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzY2FsZS5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBzY2FsZSBTY2FsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLnNldFNjYWxlID0gZnVuY3Rpb24gKHNjYWxlKSB7XG4gICAgdGhpcy5zY2FsZV8gPSBzY2FsZTtcbiAgICB0aGlzLnNjYWxlQXJyYXlfID0gdG9TaXplKHNjYWxlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KTogdm9pZH0gbGlzdGVuZXIgTGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUubGlzdGVuSW1hZ2VDaGFuZ2UgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cblxuXG4gIEltYWdlU3R5bGUucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KTogdm9pZH0gbGlzdGVuZXIgTGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgSW1hZ2VTdHlsZS5wcm90b3R5cGUudW5saXN0ZW5JbWFnZUNoYW5nZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgIGFic3RyYWN0KCk7XG4gIH07XG5cbiAgcmV0dXJuIEltYWdlU3R5bGU7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IEltYWdlU3R5bGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2NvbG9ybGlrZVxuICovXG5pbXBvcnQgeyB0b1N0cmluZyB9IGZyb20gJy4vY29sb3IuanMnO1xuLyoqXG4gKiBBIHR5cGUgYWNjZXB0ZWQgYnkgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELmZpbGxTdHlsZVxuICogb3IgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJELnN0cm9rZVN0eWxlLlxuICogUmVwcmVzZW50cyBhIGNvbG9yLCBwYXR0ZXJuLCBvciBncmFkaWVudC4gVGhlIG9yaWdpbiBmb3IgcGF0dGVybnMgYW5kXG4gKiBncmFkaWVudHMgYXMgZmlsbCBzdHlsZSBpcyBhbiBpbmNyZW1lbnQgb2YgNTEyIGNzcyBwaXhlbHMgZnJvbSBtYXAgY29vcmRpbmF0ZVxuICogYFswLCAwXWAuIEZvciBzZWFtbGVzcyByZXBlYXQgcGF0dGVybnMsIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHBhdHRlcm4gaW1hZ2VcbiAqIG11c3QgYmUgYSBmYWN0b3Igb2YgdHdvICgyLCA0LCA4LCAuLi4sIDUxMikuXG4gKlxuICogQHR5cGVkZWYge3N0cmluZ3xDYW52YXNQYXR0ZXJufENhbnZhc0dyYWRpZW50fSBDb2xvckxpa2VcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb2xvci5qc1wiKS5Db2xvcnxDb2xvckxpa2V9IGNvbG9yIENvbG9yLlxuICogQHJldHVybiB7Q29sb3JMaWtlfSBUaGUgY29sb3IgYXMgYW4ge0BsaW5rIG9sL2NvbG9ybGlrZX5Db2xvckxpa2V9LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhc0NvbG9yTGlrZShjb2xvcikge1xuICBpZiAoQXJyYXkuaXNBcnJheShjb2xvcikpIHtcbiAgICByZXR1cm4gdG9TdHJpbmcoY29sb3IpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb2xvcjtcbiAgfVxufSIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9SZWd1bGFyU2hhcGVcbiAqL1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IEltYWdlU3RhdGUgZnJvbSAnLi4vSW1hZ2VTdGF0ZS5qcyc7XG5pbXBvcnQgSW1hZ2VTdHlsZSBmcm9tICcuL0ltYWdlLmpzJztcbmltcG9ydCB7IGFzQXJyYXkgfSBmcm9tICcuLi9jb2xvci5qcyc7XG5pbXBvcnQgeyBhc0NvbG9yTGlrZSB9IGZyb20gJy4uL2NvbG9ybGlrZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDYW52YXNDb250ZXh0MkQgfSBmcm9tICcuLi9kb20uanMnO1xuaW1wb3J0IHsgZGVmYXVsdEZpbGxTdHlsZSwgZGVmYXVsdExpbmVDYXAsIGRlZmF1bHRMaW5lSm9pbiwgZGVmYXVsdExpbmVXaWR0aCwgZGVmYXVsdE1pdGVyTGltaXQsIGRlZmF1bHRTdHJva2VTdHlsZSB9IGZyb20gJy4uL3JlbmRlci9jYW52YXMuanMnO1xuLyoqXG4gKiBTcGVjaWZ5IHJhZGl1cyBmb3IgcmVndWxhciBwb2x5Z29ucywgb3IgcmFkaXVzMSBhbmQgcmFkaXVzMiBmb3Igc3RhcnMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fSBbZmlsbF0gRmlsbCBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBwb2ludHMgTnVtYmVyIG9mIHBvaW50cyBmb3Igc3RhcnMgYW5kIHJlZ3VsYXIgcG9seWdvbnMuIEluIGNhc2Ugb2YgYSBwb2x5Z29uLCB0aGUgbnVtYmVyIG9mIHBvaW50c1xuICogaXMgdGhlIG51bWJlciBvZiBzaWRlcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmFkaXVzXSBSYWRpdXMgb2YgYSByZWd1bGFyIHBvbHlnb24uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JhZGl1czFdIE91dGVyIHJhZGl1cyBvZiBhIHN0YXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JhZGl1czJdIElubmVyIHJhZGl1cyBvZiBhIHN0YXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2FuZ2xlPTBdIFNoYXBlJ3MgYW5nbGUgaW4gcmFkaWFucy4gQSB2YWx1ZSBvZiAwIHdpbGwgaGF2ZSBvbmUgb2YgdGhlIHNoYXBlJ3MgcG9pbnQgZmFjaW5nIHVwLlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbZGlzcGxhY2VtZW50PVswLDBdXSBEaXNwbGFjZW1lbnQgb2YgdGhlIHNoYXBlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFtzdHJva2VdIFN0cm9rZSBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcm90YXRpb249MF0gUm90YXRpb24gaW4gcmFkaWFucyAocG9zaXRpdmUgcm90YXRpb24gY2xvY2t3aXNlKS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3JvdGF0ZVdpdGhWaWV3PWZhbHNlXSBXaGV0aGVyIHRvIHJvdGF0ZSB0aGUgc2hhcGUgd2l0aCB0aGUgdmlldy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW3NjYWxlPTFdIFNjYWxlLiBVbmxlc3MgdHdvIGRpbWVuc2lvbmFsIHNjYWxpbmcgaXMgcmVxdWlyZWQgYSBiZXR0ZXJcbiAqIHJlc3VsdCBtYXkgYmUgb2J0YWluZWQgd2l0aCBhcHByb3ByaWF0ZSBzZXR0aW5ncyBmb3IgYHJhZGl1c2AsIGByYWRpdXMxYCBhbmQgYHJhZGl1czJgLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUmVuZGVyT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBbc3Ryb2tlU3R5bGVdXG4gKiBAcHJvcGVydHkge251bWJlcn0gc3Ryb2tlV2lkdGhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBzaXplXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVDYXB9IGxpbmVDYXBcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gbGluZURhc2hcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsaW5lRGFzaE9mZnNldFxuICogQHByb3BlcnR5IHtDYW52YXNMaW5lSm9pbn0gbGluZUpvaW5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaXRlckxpbWl0XG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTZXQgcmVndWxhciBzaGFwZSBzdHlsZSBmb3IgdmVjdG9yIGZlYXR1cmVzLiBUaGUgcmVzdWx0aW5nIHNoYXBlIHdpbGwgYmVcbiAqIGEgcmVndWxhciBwb2x5Z29uIHdoZW4gYHJhZGl1c2AgaXMgcHJvdmlkZWQsIG9yIGEgc3RhciB3aGVuIGByYWRpdXMxYCBhbmRcbiAqIGByYWRpdXMyYCBhcmUgcHJvdmlkZWQuXG4gKiBAYXBpXG4gKi9cblxudmFyIFJlZ3VsYXJTaGFwZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhSZWd1bGFyU2hhcGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBSZWd1bGFyU2hhcGUob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cblxuICAgIHZhciByb3RhdGVXaXRoVmlldyA9IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgOiBmYWxzZTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIG9wYWNpdHk6IDEsXG4gICAgICByb3RhdGVXaXRoVmlldzogcm90YXRlV2l0aFZpZXcsXG4gICAgICByb3RhdGlvbjogb3B0aW9ucy5yb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGlvbiA6IDAsXG4gICAgICBzY2FsZTogb3B0aW9ucy5zY2FsZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zY2FsZSA6IDEsXG4gICAgICBkaXNwbGFjZW1lbnQ6IG9wdGlvbnMuZGlzcGxhY2VtZW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmRpc3BsYWNlbWVudCA6IFswLCAwXVxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PG51bWJlciwgSFRNTENhbnZhc0VsZW1lbnQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2FudmFzXyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaGl0RGV0ZWN0aW9uQ2FudmFzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5maWxsXyA9IG9wdGlvbnMuZmlsbCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5maWxsIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMub3JpZ2luXyA9IFswLCAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5wb2ludHNfID0gb3B0aW9ucy5wb2ludHM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yYWRpdXNfID0gb3B0aW9ucy5yYWRpdXMgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucmFkaXVzIDogb3B0aW9ucy5yYWRpdXMxO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yYWRpdXMyXyA9IG9wdGlvbnMucmFkaXVzMjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmdsZV8gPSBvcHRpb25zLmFuZ2xlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFuZ2xlIDogMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1N0cm9rZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3Ryb2tlXyA9IG9wdGlvbnMuc3Ryb2tlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnN0cm9rZSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvcl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnNpemVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZVNpemVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZVNpemVfID0gbnVsbDtcblxuICAgIF90aGlzLnJlbmRlcigpO1xuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtSZWd1bGFyU2hhcGV9IFRoZSBjbG9uZWQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoKTtcbiAgICB2YXIgc3R5bGUgPSBuZXcgUmVndWxhclNoYXBlKHtcbiAgICAgIGZpbGw6IHRoaXMuZ2V0RmlsbCgpID8gdGhpcy5nZXRGaWxsKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHBvaW50czogdGhpcy5nZXRQb2ludHMoKSxcbiAgICAgIHJhZGl1czogdGhpcy5nZXRSYWRpdXMoKSxcbiAgICAgIHJhZGl1czI6IHRoaXMuZ2V0UmFkaXVzMigpLFxuICAgICAgYW5nbGU6IHRoaXMuZ2V0QW5nbGUoKSxcbiAgICAgIHN0cm9rZTogdGhpcy5nZXRTdHJva2UoKSA/IHRoaXMuZ2V0U3Ryb2tlKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHJvdGF0aW9uOiB0aGlzLmdldFJvdGF0aW9uKCksXG4gICAgICByb3RhdGVXaXRoVmlldzogdGhpcy5nZXRSb3RhdGVXaXRoVmlldygpLFxuICAgICAgc2NhbGU6IEFycmF5LmlzQXJyYXkoc2NhbGUpID8gc2NhbGUuc2xpY2UoKSA6IHNjYWxlLFxuICAgICAgZGlzcGxhY2VtZW50OiB0aGlzLmdldERpc3BsYWNlbWVudCgpLnNsaWNlKClcbiAgICB9KTtcbiAgICBzdHlsZS5zZXRPcGFjaXR5KHRoaXMuZ2V0T3BhY2l0eSgpKTtcbiAgICByZXR1cm4gc3R5bGU7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFuY2hvciBwb2ludCBpbiBwaXhlbHMuIFRoZSBhbmNob3IgZGV0ZXJtaW5lcyB0aGUgY2VudGVyIHBvaW50IGZvciB0aGVcbiAgICogc3ltYm9saXplci5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gQW5jaG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRBbmNob3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYW5jaG9yXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgYW5nbGUgdXNlZCBpbiBnZW5lcmF0aW5nIHRoZSBzaGFwZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBTaGFwZSdzIHJvdGF0aW9uIGluIHJhZGlhbnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldEFuZ2xlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmFuZ2xlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmlsbCBzdHlsZSBmb3IgdGhlIHNoYXBlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gRmlsbCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0RmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5maWxsXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fSBJbWFnZSBlbGVtZW50LlxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmhpdERldGVjdGlvbkNhbnZhc18pIHtcbiAgICAgIHZhciByZW5kZXJPcHRpb25zID0gdGhpcy5jcmVhdGVSZW5kZXJPcHRpb25zKCk7XG4gICAgICB0aGlzLmNyZWF0ZUhpdERldGVjdGlvbkNhbnZhc18ocmVuZGVyT3B0aW9ucyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuaGl0RGV0ZWN0aW9uQ2FudmFzXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgaW1hZ2UgaWNvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fSBJbWFnZSBvciBDYW52YXMgZWxlbWVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIGlmICghdGhpcy5jYW52YXNfW3BpeGVsUmF0aW8gfHwgMV0pIHtcbiAgICAgIHZhciByZW5kZXJPcHRpb25zID0gdGhpcy5jcmVhdGVSZW5kZXJPcHRpb25zKCk7XG4gICAgICB2YXIgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRChyZW5kZXJPcHRpb25zLnNpemUgKiBwaXhlbFJhdGlvIHx8IDEsIHJlbmRlck9wdGlvbnMuc2l6ZSAqIHBpeGVsUmF0aW8gfHwgMSk7XG4gICAgICB0aGlzLmRyYXdfKHJlbmRlck9wdGlvbnMsIGNvbnRleHQsIDAsIDAsIHBpeGVsUmF0aW8gfHwgMSk7XG4gICAgICB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpbyB8fCAxXSA9IGNvbnRleHQuY2FudmFzO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpbyB8fCAxXTtcbiAgfTtcbiAgLypcbiAgICogR2V0IHRoZSBpbWFnZSBwaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldFBpeGVsUmF0aW8gPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIHJldHVybiBwaXhlbFJhdGlvO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBJbWFnZSBzaXplLlxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0SW1hZ2VTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlU2l6ZV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFNpemUgb2YgdGhlIGhpdC1kZXRlY3Rpb24gaW1hZ2UuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRIaXREZXRlY3Rpb25JbWFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VTaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH0gSW1hZ2Ugc3RhdGUuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5nZXRJbWFnZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBJbWFnZVN0YXRlLkxPQURFRDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgb3JpZ2luIG9mIHRoZSBzeW1ib2xpemVyLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPcmlnaW4uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldE9yaWdpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vcmlnaW5fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2YgcG9pbnRzIGZvciBnZW5lcmF0aW5nIHRoZSBzaGFwZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBOdW1iZXIgb2YgcG9pbnRzIGZvciBzdGFycyBhbmQgcmVndWxhciBwb2x5Z29ucy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0UG9pbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnBvaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIChwcmltYXJ5KSByYWRpdXMgZm9yIHRoZSBzaGFwZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBSYWRpdXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldFJhZGl1cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yYWRpdXNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzZWNvbmRhcnkgcmFkaXVzIGZvciB0aGUgc2hhcGUuXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJhZGl1czIuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmdldFJhZGl1czIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmFkaXVzMl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHNpemUgb2YgdGhlIHN5bWJvbGl6ZXIgKGluIHBpeGVscykuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gU2l6ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3Ryb2tlIHN0eWxlIGZvciB0aGUgc2hhcGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFN0cm9rZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZ2V0U3Ryb2tlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0cm9rZV87XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KTogdm9pZH0gbGlzdGVuZXIgTGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5saXN0ZW5JbWFnZUNoYW5nZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge307XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAgICovXG5cblxuICBSZWd1bGFyU2hhcGUucHJvdG90eXBlLnVubGlzdGVuSW1hZ2VDaGFuZ2UgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHt9O1xuICAvKipcbiAgICogQHJldHVybnMge1JlbmRlck9wdGlvbnN9ICBUaGUgcmVuZGVyIG9wdGlvbnNcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuY3JlYXRlUmVuZGVyT3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGluZUNhcCA9IGRlZmF1bHRMaW5lQ2FwO1xuICAgIHZhciBsaW5lSm9pbiA9IGRlZmF1bHRMaW5lSm9pbjtcbiAgICB2YXIgbWl0ZXJMaW1pdCA9IDA7XG4gICAgdmFyIGxpbmVEYXNoID0gbnVsbDtcbiAgICB2YXIgbGluZURhc2hPZmZzZXQgPSAwO1xuICAgIHZhciBzdHJva2VTdHlsZTtcbiAgICB2YXIgc3Ryb2tlV2lkdGggPSAwO1xuXG4gICAgaWYgKHRoaXMuc3Ryb2tlXykge1xuICAgICAgc3Ryb2tlU3R5bGUgPSB0aGlzLnN0cm9rZV8uZ2V0Q29sb3IoKTtcblxuICAgICAgaWYgKHN0cm9rZVN0eWxlID09PSBudWxsKSB7XG4gICAgICAgIHN0cm9rZVN0eWxlID0gZGVmYXVsdFN0cm9rZVN0eWxlO1xuICAgICAgfVxuXG4gICAgICBzdHJva2VTdHlsZSA9IGFzQ29sb3JMaWtlKHN0cm9rZVN0eWxlKTtcbiAgICAgIHN0cm9rZVdpZHRoID0gdGhpcy5zdHJva2VfLmdldFdpZHRoKCk7XG5cbiAgICAgIGlmIChzdHJva2VXaWR0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN0cm9rZVdpZHRoID0gZGVmYXVsdExpbmVXaWR0aDtcbiAgICAgIH1cblxuICAgICAgbGluZURhc2ggPSB0aGlzLnN0cm9rZV8uZ2V0TGluZURhc2goKTtcbiAgICAgIGxpbmVEYXNoT2Zmc2V0ID0gdGhpcy5zdHJva2VfLmdldExpbmVEYXNoT2Zmc2V0KCk7XG4gICAgICBsaW5lSm9pbiA9IHRoaXMuc3Ryb2tlXy5nZXRMaW5lSm9pbigpO1xuXG4gICAgICBpZiAobGluZUpvaW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsaW5lSm9pbiA9IGRlZmF1bHRMaW5lSm9pbjtcbiAgICAgIH1cblxuICAgICAgbGluZUNhcCA9IHRoaXMuc3Ryb2tlXy5nZXRMaW5lQ2FwKCk7XG5cbiAgICAgIGlmIChsaW5lQ2FwID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGluZUNhcCA9IGRlZmF1bHRMaW5lQ2FwO1xuICAgICAgfVxuXG4gICAgICBtaXRlckxpbWl0ID0gdGhpcy5zdHJva2VfLmdldE1pdGVyTGltaXQoKTtcblxuICAgICAgaWYgKG1pdGVyTGltaXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtaXRlckxpbWl0ID0gZGVmYXVsdE1pdGVyTGltaXQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNpemUgPSAyICogKHRoaXMucmFkaXVzXyArIHN0cm9rZVdpZHRoKSArIDE7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0cm9rZVN0eWxlOiBzdHJva2VTdHlsZSxcbiAgICAgIHN0cm9rZVdpZHRoOiBzdHJva2VXaWR0aCxcbiAgICAgIHNpemU6IHNpemUsXG4gICAgICBsaW5lQ2FwOiBsaW5lQ2FwLFxuICAgICAgbGluZURhc2g6IGxpbmVEYXNoLFxuICAgICAgbGluZURhc2hPZmZzZXQ6IGxpbmVEYXNoT2Zmc2V0LFxuICAgICAgbGluZUpvaW46IGxpbmVKb2luLFxuICAgICAgbWl0ZXJMaW1pdDogbWl0ZXJMaW1pdFxuICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHJlbmRlck9wdGlvbnMgPSB0aGlzLmNyZWF0ZVJlbmRlck9wdGlvbnMoKTtcbiAgICB2YXIgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRChyZW5kZXJPcHRpb25zLnNpemUsIHJlbmRlck9wdGlvbnMuc2l6ZSk7XG4gICAgdGhpcy5kcmF3XyhyZW5kZXJPcHRpb25zLCBjb250ZXh0LCAwLCAwLCAxKTtcbiAgICB0aGlzLmNhbnZhc18gPSB7fTtcbiAgICB0aGlzLmNhbnZhc19bMV0gPSBjb250ZXh0LmNhbnZhczsgLy8gY2FudmFzLndpZHRoIGFuZCBoZWlnaHQgYXJlIHJvdW5kZWQgdG8gdGhlIGNsb3Nlc3QgaW50ZWdlclxuXG4gICAgdmFyIHNpemUgPSBjb250ZXh0LmNhbnZhcy53aWR0aDtcbiAgICB2YXIgaW1hZ2VTaXplID0gc2l6ZTtcbiAgICB2YXIgZGlzcGxhY2VtZW50ID0gdGhpcy5nZXREaXNwbGFjZW1lbnQoKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlU2l6ZV8gPSBbcmVuZGVyT3B0aW9ucy5zaXplLCByZW5kZXJPcHRpb25zLnNpemVdO1xuICAgIHRoaXMuY3JlYXRlSGl0RGV0ZWN0aW9uQ2FudmFzXyhyZW5kZXJPcHRpb25zKTtcbiAgICB0aGlzLmFuY2hvcl8gPSBbc2l6ZSAvIDIgLSBkaXNwbGFjZW1lbnRbMF0sIHNpemUgLyAyICsgZGlzcGxhY2VtZW50WzFdXTtcbiAgICB0aGlzLnNpemVfID0gW3NpemUsIHNpemVdO1xuICAgIHRoaXMuaW1hZ2VTaXplXyA9IFtpbWFnZVNpemUsIGltYWdlU2l6ZV07XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge1JlbmRlck9wdGlvbnN9IHJlbmRlck9wdGlvbnMgUmVuZGVyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IFRoZSByZW5kZXJpbmcgY29udGV4dC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGhlIG9yaWdpbiBmb3IgdGhlIHN5bWJvbCAoeCkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRoZSBvcmlnaW4gZm9yIHRoZSBzeW1ib2wgKHkpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBUaGUgcGl4ZWwgcmF0aW8uXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5kcmF3XyA9IGZ1bmN0aW9uIChyZW5kZXJPcHRpb25zLCBjb250ZXh0LCB4LCB5LCBwaXhlbFJhdGlvKSB7XG4gICAgdmFyIGksIGFuZ2xlMCwgcmFkaXVzQzsgLy8gcmVzZXQgdHJhbnNmb3JtXG5cbiAgICBjb250ZXh0LnNldFRyYW5zZm9ybShwaXhlbFJhdGlvLCAwLCAwLCBwaXhlbFJhdGlvLCAwLCAwKTsgLy8gdGhlbiBtb3ZlIHRvICh4LCB5KVxuXG4gICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHNfO1xuXG4gICAgaWYgKHBvaW50cyA9PT0gSW5maW5pdHkpIHtcbiAgICAgIGNvbnRleHQuYXJjKHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIsIHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIsIHRoaXMucmFkaXVzXywgMCwgMiAqIE1hdGguUEksIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcmFkaXVzMiA9IHRoaXMucmFkaXVzMl8gIT09IHVuZGVmaW5lZCA/IHRoaXMucmFkaXVzMl8gOiB0aGlzLnJhZGl1c187XG5cbiAgICAgIGlmIChyYWRpdXMyICE9PSB0aGlzLnJhZGl1c18pIHtcbiAgICAgICAgcG9pbnRzID0gMiAqIHBvaW50cztcbiAgICAgIH1cblxuICAgICAgZm9yIChpID0gMDsgaSA8PSBwb2ludHM7IGkrKykge1xuICAgICAgICBhbmdsZTAgPSBpICogMiAqIE1hdGguUEkgLyBwb2ludHMgLSBNYXRoLlBJIC8gMiArIHRoaXMuYW5nbGVfO1xuICAgICAgICByYWRpdXNDID0gaSAlIDIgPT09IDAgPyB0aGlzLnJhZGl1c18gOiByYWRpdXMyO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyhyZW5kZXJPcHRpb25zLnNpemUgLyAyICsgcmFkaXVzQyAqIE1hdGguY29zKGFuZ2xlMCksIHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIgKyByYWRpdXNDICogTWF0aC5zaW4oYW5nbGUwKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZmlsbF8pIHtcbiAgICAgIHZhciBjb2xvciA9IHRoaXMuZmlsbF8uZ2V0Q29sb3IoKTtcblxuICAgICAgaWYgKGNvbG9yID09PSBudWxsKSB7XG4gICAgICAgIGNvbG9yID0gZGVmYXVsdEZpbGxTdHlsZTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBhc0NvbG9yTGlrZShjb2xvcik7XG4gICAgICBjb250ZXh0LmZpbGwoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdHJva2VfKSB7XG4gICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gcmVuZGVyT3B0aW9ucy5zdHJva2VTdHlsZTtcbiAgICAgIGNvbnRleHQubGluZVdpZHRoID0gcmVuZGVyT3B0aW9ucy5zdHJva2VXaWR0aDtcblxuICAgICAgaWYgKGNvbnRleHQuc2V0TGluZURhc2ggJiYgcmVuZGVyT3B0aW9ucy5saW5lRGFzaCkge1xuICAgICAgICBjb250ZXh0LnNldExpbmVEYXNoKHJlbmRlck9wdGlvbnMubGluZURhc2gpO1xuICAgICAgICBjb250ZXh0LmxpbmVEYXNoT2Zmc2V0ID0gcmVuZGVyT3B0aW9ucy5saW5lRGFzaE9mZnNldDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5saW5lQ2FwID0gcmVuZGVyT3B0aW9ucy5saW5lQ2FwO1xuICAgICAgY29udGV4dC5saW5lSm9pbiA9IHJlbmRlck9wdGlvbnMubGluZUpvaW47XG4gICAgICBjb250ZXh0Lm1pdGVyTGltaXQgPSByZW5kZXJPcHRpb25zLm1pdGVyTGltaXQ7XG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH1cblxuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge1JlbmRlck9wdGlvbnN9IHJlbmRlck9wdGlvbnMgUmVuZGVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgUmVndWxhclNoYXBlLnByb3RvdHlwZS5jcmVhdGVIaXREZXRlY3Rpb25DYW52YXNfID0gZnVuY3Rpb24gKHJlbmRlck9wdGlvbnMpIHtcbiAgICB0aGlzLmhpdERldGVjdGlvbkNhbnZhc18gPSB0aGlzLmdldEltYWdlKDEpO1xuXG4gICAgaWYgKHRoaXMuZmlsbF8pIHtcbiAgICAgIHZhciBjb2xvciA9IHRoaXMuZmlsbF8uZ2V0Q29sb3IoKTsgLy8gZGV0ZXJtaW5lIGlmIGZpbGwgaXMgdHJhbnNwYXJlbnQgKG9yIHBhdHRlcm4gb3IgZ3JhZGllbnQpXG5cbiAgICAgIHZhciBvcGFjaXR5ID0gMDtcblxuICAgICAgaWYgKHR5cGVvZiBjb2xvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29sb3IgPSBhc0FycmF5KGNvbG9yKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbG9yID09PSBudWxsKSB7XG4gICAgICAgIG9wYWNpdHkgPSAxO1xuICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGNvbG9yKSkge1xuICAgICAgICBvcGFjaXR5ID0gY29sb3IubGVuZ3RoID09PSA0ID8gY29sb3JbM10gOiAxO1xuICAgICAgfVxuXG4gICAgICBpZiAob3BhY2l0eSA9PT0gMCkge1xuICAgICAgICAvLyBpZiBhIHRyYW5zcGFyZW50IGZpbGwgc3R5bGUgaXMgc2V0LCBjcmVhdGUgYW4gZXh0cmEgaGl0LWRldGVjdGlvbiBpbWFnZVxuICAgICAgICAvLyB3aXRoIGEgZGVmYXVsdCBmaWxsIHN0eWxlXG4gICAgICAgIHZhciBjb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKHJlbmRlck9wdGlvbnMuc2l6ZSwgcmVuZGVyT3B0aW9ucy5zaXplKTtcbiAgICAgICAgdGhpcy5oaXREZXRlY3Rpb25DYW52YXNfID0gY29udGV4dC5jYW52YXM7XG4gICAgICAgIHRoaXMuZHJhd0hpdERldGVjdGlvbkNhbnZhc18ocmVuZGVyT3B0aW9ucywgY29udGV4dCwgMCwgMCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtSZW5kZXJPcHRpb25zfSByZW5kZXJPcHRpb25zIFJlbmRlciBvcHRpb25zLlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBUaGUgY29udGV4dC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGhlIG9yaWdpbiBmb3IgdGhlIHN5bWJvbCAoeCkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRoZSBvcmlnaW4gZm9yIHRoZSBzeW1ib2wgKHkpLlxuICAgKi9cblxuXG4gIFJlZ3VsYXJTaGFwZS5wcm90b3R5cGUuZHJhd0hpdERldGVjdGlvbkNhbnZhc18gPSBmdW5jdGlvbiAocmVuZGVyT3B0aW9ucywgY29udGV4dCwgeCwgeSkge1xuICAgIC8vIG1vdmUgdG8gKHgsIHkpXG4gICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICB2YXIgcG9pbnRzID0gdGhpcy5wb2ludHNfO1xuXG4gICAgaWYgKHBvaW50cyA9PT0gSW5maW5pdHkpIHtcbiAgICAgIGNvbnRleHQuYXJjKHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIsIHJlbmRlck9wdGlvbnMuc2l6ZSAvIDIsIHRoaXMucmFkaXVzXywgMCwgMiAqIE1hdGguUEksIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgcmFkaXVzMiA9IHRoaXMucmFkaXVzMl8gIT09IHVuZGVmaW5lZCA/IHRoaXMucmFkaXVzMl8gOiB0aGlzLnJhZGl1c187XG5cbiAgICAgIGlmIChyYWRpdXMyICE9PSB0aGlzLnJhZGl1c18pIHtcbiAgICAgICAgcG9pbnRzID0gMiAqIHBvaW50cztcbiAgICAgIH1cblxuICAgICAgdmFyIGkgPSB2b2lkIDAsXG4gICAgICAgICAgcmFkaXVzQyA9IHZvaWQgMCxcbiAgICAgICAgICBhbmdsZTAgPSB2b2lkIDA7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPD0gcG9pbnRzOyBpKyspIHtcbiAgICAgICAgYW5nbGUwID0gaSAqIDIgKiBNYXRoLlBJIC8gcG9pbnRzIC0gTWF0aC5QSSAvIDIgKyB0aGlzLmFuZ2xlXztcbiAgICAgICAgcmFkaXVzQyA9IGkgJSAyID09PSAwID8gdGhpcy5yYWRpdXNfIDogcmFkaXVzMjtcbiAgICAgICAgY29udGV4dC5saW5lVG8ocmVuZGVyT3B0aW9ucy5zaXplIC8gMiArIHJhZGl1c0MgKiBNYXRoLmNvcyhhbmdsZTApLCByZW5kZXJPcHRpb25zLnNpemUgLyAyICsgcmFkaXVzQyAqIE1hdGguc2luKGFuZ2xlMCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gZGVmYXVsdEZpbGxTdHlsZTtcbiAgICBjb250ZXh0LmZpbGwoKTtcblxuICAgIGlmICh0aGlzLnN0cm9rZV8pIHtcbiAgICAgIGNvbnRleHQuc3Ryb2tlU3R5bGUgPSByZW5kZXJPcHRpb25zLnN0cm9rZVN0eWxlO1xuICAgICAgY29udGV4dC5saW5lV2lkdGggPSByZW5kZXJPcHRpb25zLnN0cm9rZVdpZHRoO1xuXG4gICAgICBpZiAocmVuZGVyT3B0aW9ucy5saW5lRGFzaCkge1xuICAgICAgICBjb250ZXh0LnNldExpbmVEYXNoKHJlbmRlck9wdGlvbnMubGluZURhc2gpO1xuICAgICAgICBjb250ZXh0LmxpbmVEYXNoT2Zmc2V0ID0gcmVuZGVyT3B0aW9ucy5saW5lRGFzaE9mZnNldDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICB9XG5cbiAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICB9O1xuXG4gIHJldHVybiBSZWd1bGFyU2hhcGU7XG59KEltYWdlU3R5bGUpO1xuXG5leHBvcnQgZGVmYXVsdCBSZWd1bGFyU2hhcGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0NpcmNsZVxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgUmVndWxhclNoYXBlIGZyb20gJy4vUmVndWxhclNoYXBlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gW2ZpbGxdIEZpbGwgc3R5bGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmFkaXVzIENpcmNsZSByYWRpdXMuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFtzdHJva2VdIFN0cm9rZSBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW2Rpc3BsYWNlbWVudD1bMCwwXV0gZGlzcGxhY2VtZW50XG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFtzY2FsZT0xXSBTY2FsZS4gQSB0d28gZGltZW5zaW9uYWwgc2NhbGUgd2lsbCBwcm9kdWNlIGFuIGVsbGlwc2UuXG4gKiBVbmxlc3MgdHdvIGRpbWVuc2lvbmFsIHNjYWxpbmcgaXMgcmVxdWlyZWQgYSBiZXR0ZXIgcmVzdWx0IG1heSBiZSBvYnRhaW5lZCB3aXRoIGFuIGFwcHJvcHJpYXRlIHNldHRpbmcgZm9yIGByYWRpdXNgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyb3RhdGlvbj0wXSBSb3RhdGlvbiBpbiByYWRpYW5zXG4gKiAocG9zaXRpdmUgcm90YXRpb24gY2xvY2t3aXNlLCBtZWFuaW5nZnVsIG9ubHkgd2hlbiB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYSB0d28gZGltZW5zaW9uYWwgc2NhbGUpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcm90YXRlV2l0aFZpZXc9ZmFsc2VdIFdoZXRoZXIgdG8gcm90YXRlIHRoZSBzaGFwZSB3aXRoIHRoZSB2aWV3XG4gKiAobWVhbmluZ2Z1bCBvbmx5IHdoZW4gdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIGEgdHdvIGRpbWVuc2lvbmFsIHNjYWxlKS5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFNldCBjaXJjbGUgc3R5bGUgZm9yIHZlY3RvciBmZWF0dXJlcy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgQ2lyY2xlU3R5bGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2lyY2xlU3R5bGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENpcmNsZVN0eWxlKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgcG9pbnRzOiBJbmZpbml0eSxcbiAgICAgIGZpbGw6IG9wdGlvbnMuZmlsbCxcbiAgICAgIHJhZGl1czogb3B0aW9ucy5yYWRpdXMsXG4gICAgICBzdHJva2U6IG9wdGlvbnMuc3Ryb2tlLFxuICAgICAgc2NhbGU6IG9wdGlvbnMuc2NhbGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2NhbGUgOiAxLFxuICAgICAgcm90YXRpb246IG9wdGlvbnMucm90YXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucm90YXRpb24gOiAwLFxuICAgICAgcm90YXRlV2l0aFZpZXc6IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgOiBmYWxzZSxcbiAgICAgIGRpc3BsYWNlbWVudDogb3B0aW9ucy5kaXNwbGFjZW1lbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGlzcGxhY2VtZW50IDogWzAsIDBdXG4gICAgfSkgfHwgdGhpcztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENsb25lcyB0aGUgc3R5bGUuXG4gICAqIEByZXR1cm4ge0NpcmNsZVN0eWxlfSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ2lyY2xlU3R5bGUucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzY2FsZSA9IHRoaXMuZ2V0U2NhbGUoKTtcbiAgICB2YXIgc3R5bGUgPSBuZXcgQ2lyY2xlU3R5bGUoe1xuICAgICAgZmlsbDogdGhpcy5nZXRGaWxsKCkgPyB0aGlzLmdldEZpbGwoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgc3Ryb2tlOiB0aGlzLmdldFN0cm9rZSgpID8gdGhpcy5nZXRTdHJva2UoKS5jbG9uZSgpIDogdW5kZWZpbmVkLFxuICAgICAgcmFkaXVzOiB0aGlzLmdldFJhZGl1cygpLFxuICAgICAgc2NhbGU6IEFycmF5LmlzQXJyYXkoc2NhbGUpID8gc2NhbGUuc2xpY2UoKSA6IHNjYWxlLFxuICAgICAgcm90YXRpb246IHRoaXMuZ2V0Um90YXRpb24oKSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiB0aGlzLmdldFJvdGF0ZVdpdGhWaWV3KCksXG4gICAgICBkaXNwbGFjZW1lbnQ6IHRoaXMuZ2V0RGlzcGxhY2VtZW50KCkuc2xpY2UoKVxuICAgIH0pO1xuICAgIHN0eWxlLnNldE9wYWNpdHkodGhpcy5nZXRPcGFjaXR5KCkpO1xuICAgIHJldHVybiBzdHlsZTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY2lyY2xlIHJhZGl1cy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IHJhZGl1cyBDaXJjbGUgcmFkaXVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ2lyY2xlU3R5bGUucHJvdG90eXBlLnNldFJhZGl1cyA9IGZ1bmN0aW9uIChyYWRpdXMpIHtcbiAgICB0aGlzLnJhZGl1c18gPSByYWRpdXM7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfTtcblxuICByZXR1cm4gQ2lyY2xlU3R5bGU7XG59KFJlZ3VsYXJTaGFwZSk7XG5cbmV4cG9ydCBkZWZhdWx0IENpcmNsZVN0eWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9GaWxsXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfGltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IFtjb2xvcj1udWxsXSBBIGNvbG9yLCBncmFkaWVudCBvciBwYXR0ZXJuLlxuICogU2VlIHtAbGluayBtb2R1bGU6b2wvY29sb3J+Q29sb3J9IGFuZCB7QGxpbmsgbW9kdWxlOm9sL2NvbG9ybGlrZX5Db2xvckxpa2V9IGZvciBwb3NzaWJsZSBmb3JtYXRzLlxuICogRGVmYXVsdCBudWxsOyBpZiBudWxsLCB0aGUgQ2FudmFzL3JlbmRlcmVyIGRlZmF1bHQgYmxhY2sgd2lsbCBiZSB1c2VkLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogU2V0IGZpbGwgc3R5bGUgZm9yIHZlY3RvciBmZWF0dXJlcy5cbiAqIEBhcGlcbiAqL1xudmFyIEZpbGwgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG4gIGZ1bmN0aW9uIEZpbGwob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfGltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9XG4gICAgICovXG5cbiAgICB0aGlzLmNvbG9yXyA9IG9wdGlvbnMuY29sb3IgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY29sb3IgOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLiBUaGUgY29sb3IgaXMgbm90IGNsb25lZCBpZiBpdCBpcyBhbiB7QGxpbmsgbW9kdWxlOm9sL2NvbG9ybGlrZX5Db2xvckxpa2V9LlxuICAgKiBAcmV0dXJuIHtGaWxsfSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRmlsbC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbG9yID0gdGhpcy5nZXRDb2xvcigpO1xuICAgIHJldHVybiBuZXcgRmlsbCh7XG4gICAgICBjb2xvcjogQXJyYXkuaXNBcnJheShjb2xvcikgPyBjb2xvci5zbGljZSgpIDogY29sb3IgfHwgdW5kZWZpbmVkXG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZpbGwgY29sb3IuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfGltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IENvbG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRmlsbC5wcm90b3R5cGUuZ2V0Q29sb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sb3JfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBjb2xvci5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb2xvci5qc1wiKS5Db2xvcnxpbXBvcnQoXCIuLi9jb2xvcmxpa2UuanNcIikuQ29sb3JMaWtlfSBjb2xvciBDb2xvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEZpbGwucHJvdG90eXBlLnNldENvbG9yID0gZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgdGhpcy5jb2xvcl8gPSBjb2xvcjtcbiAgfTtcblxuICByZXR1cm4gRmlsbDtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgRmlsbDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3R5bGUvU3Ryb2tlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfGltcG9ydChcIi4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9IFtjb2xvcl0gQSBjb2xvciwgZ3JhZGllbnQgb3IgcGF0dGVybi5cbiAqIFNlZSB7QGxpbmsgbW9kdWxlOm9sL2NvbG9yfkNvbG9yfSBhbmQge0BsaW5rIG1vZHVsZTpvbC9jb2xvcmxpa2V+Q29sb3JMaWtlfSBmb3IgcG9zc2libGUgZm9ybWF0cy5cbiAqIERlZmF1bHQgbnVsbDsgaWYgbnVsbCwgdGhlIENhbnZhcy9yZW5kZXJlciBkZWZhdWx0IGJsYWNrIHdpbGwgYmUgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7Q2FudmFzTGluZUNhcH0gW2xpbmVDYXA9J3JvdW5kJ10gTGluZSBjYXAgc3R5bGU6IGBidXR0YCwgYHJvdW5kYCwgb3IgYHNxdWFyZWAuXG4gKiBAcHJvcGVydHkge0NhbnZhc0xpbmVKb2lufSBbbGluZUpvaW49J3JvdW5kJ10gTGluZSBqb2luIHN0eWxlOiBgYmV2ZWxgLCBgcm91bmRgLCBvciBgbWl0ZXJgLlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbbGluZURhc2hdIExpbmUgZGFzaCBwYXR0ZXJuLiBEZWZhdWx0IGlzIGBudWxsYCAobm8gZGFzaCkuXG4gKiBQbGVhc2Ugbm90ZSB0aGF0IEludGVybmV0IEV4cGxvcmVyIDEwIGFuZCBsb3dlciBkbyBub3Qgc3VwcG9ydCB0aGUgYHNldExpbmVEYXNoYCBtZXRob2Qgb25cbiAqIHRoZSBgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEYCBhbmQgdGhlcmVmb3JlIHRoaXMgb3B0aW9uIHdpbGwgaGF2ZSBubyB2aXN1YWwgZWZmZWN0IGluIHRoZXNlIGJyb3dzZXJzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsaW5lRGFzaE9mZnNldD0wXSBMaW5lIGRhc2ggb2Zmc2V0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaXRlckxpbWl0PTEwXSBNaXRlciBsaW1pdC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbd2lkdGhdIFdpZHRoLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogU2V0IHN0cm9rZSBzdHlsZSBmb3IgdmVjdG9yIGZlYXR1cmVzLlxuICogTm90ZSB0aGF0IHRoZSBkZWZhdWx0cyBnaXZlbiBhcmUgdGhlIENhbnZhcyBkZWZhdWx0cywgd2hpY2ggd2lsbCBiZSB1c2VkIGlmXG4gKiBvcHRpb24gaXMgbm90IGRlZmluZWQuIFRoZSBgZ2V0YCBmdW5jdGlvbnMgcmV0dXJuIHdoYXRldmVyIHdhcyBlbnRlcmVkIGluXG4gKiB0aGUgb3B0aW9uczsgdGhleSB3aWxsIG5vdCByZXR1cm4gdGhlIGRlZmF1bHQuXG4gKiBAYXBpXG4gKi9cbnZhciBTdHJva2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG4gIGZ1bmN0aW9uIFN0cm9rZShvcHRfb3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgfHwge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX1cbiAgICAgKi9cblxuICAgIHRoaXMuY29sb3JfID0gb3B0aW9ucy5jb2xvciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jb2xvciA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q2FudmFzTGluZUNhcHx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLmxpbmVDYXBfID0gb3B0aW9ucy5saW5lQ2FwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLmxpbmVEYXNoXyA9IG9wdGlvbnMubGluZURhc2ggIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubGluZURhc2ggOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLmxpbmVEYXNoT2Zmc2V0XyA9IG9wdGlvbnMubGluZURhc2hPZmZzZXQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q2FudmFzTGluZUpvaW58dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5saW5lSm9pbl8gPSBvcHRpb25zLmxpbmVKb2luO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLm1pdGVyTGltaXRfID0gb3B0aW9ucy5taXRlckxpbWl0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLndpZHRoXyA9IG9wdGlvbnMud2lkdGg7XG4gIH1cbiAgLyoqXG4gICAqIENsb25lcyB0aGUgc3R5bGUuXG4gICAqIEByZXR1cm4ge1N0cm9rZX0gVGhlIGNsb25lZCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNvbG9yID0gdGhpcy5nZXRDb2xvcigpO1xuICAgIHJldHVybiBuZXcgU3Ryb2tlKHtcbiAgICAgIGNvbG9yOiBBcnJheS5pc0FycmF5KGNvbG9yKSA/IGNvbG9yLnNsaWNlKCkgOiBjb2xvciB8fCB1bmRlZmluZWQsXG4gICAgICBsaW5lQ2FwOiB0aGlzLmdldExpbmVDYXAoKSxcbiAgICAgIGxpbmVEYXNoOiB0aGlzLmdldExpbmVEYXNoKCkgPyB0aGlzLmdldExpbmVEYXNoKCkuc2xpY2UoKSA6IHVuZGVmaW5lZCxcbiAgICAgIGxpbmVEYXNoT2Zmc2V0OiB0aGlzLmdldExpbmVEYXNoT2Zmc2V0KCksXG4gICAgICBsaW5lSm9pbjogdGhpcy5nZXRMaW5lSm9pbigpLFxuICAgICAgbWl0ZXJMaW1pdDogdGhpcy5nZXRNaXRlckxpbWl0KCksXG4gICAgICB3aWR0aDogdGhpcy5nZXRXaWR0aCgpXG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN0cm9rZSBjb2xvci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gQ29sb3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLmdldENvbG9yID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbG9yXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbGluZSBjYXAgdHlwZSBmb3IgdGhlIHN0cm9rZS5cbiAgICogQHJldHVybiB7Q2FudmFzTGluZUNhcHx1bmRlZmluZWR9IExpbmUgY2FwLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5nZXRMaW5lQ2FwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmxpbmVDYXBfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsaW5lIGRhc2ggc3R5bGUgZm9yIHRoZSBzdHJva2UuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IExpbmUgZGFzaC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuZ2V0TGluZURhc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGluZURhc2hfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsaW5lIGRhc2ggb2Zmc2V0IGZvciB0aGUgc3Ryb2tlLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ8dW5kZWZpbmVkfSBMaW5lIGRhc2ggb2Zmc2V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5nZXRMaW5lRGFzaE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5saW5lRGFzaE9mZnNldF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxpbmUgam9pbiB0eXBlIGZvciB0aGUgc3Ryb2tlLlxuICAgKiBAcmV0dXJuIHtDYW52YXNMaW5lSm9pbnx1bmRlZmluZWR9IExpbmUgam9pbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuZ2V0TGluZUpvaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGluZUpvaW5fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBtaXRlciBsaW1pdCBmb3IgdGhlIHN0cm9rZS5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gTWl0ZXIgbGltaXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLmdldE1pdGVyTGltaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWl0ZXJMaW1pdF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHN0cm9rZSB3aWR0aC5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gV2lkdGguXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLmdldFdpZHRoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLndpZHRoXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29sb3IuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8aW1wb3J0KFwiLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gY29sb3IgQ29sb3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLnNldENvbG9yID0gZnVuY3Rpb24gKGNvbG9yKSB7XG4gICAgdGhpcy5jb2xvcl8gPSBjb2xvcjtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbGluZSBjYXAuXG4gICAqXG4gICAqIEBwYXJhbSB7Q2FudmFzTGluZUNhcHx1bmRlZmluZWR9IGxpbmVDYXAgTGluZSBjYXAuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLnNldExpbmVDYXAgPSBmdW5jdGlvbiAobGluZUNhcCkge1xuICAgIHRoaXMubGluZUNhcF8gPSBsaW5lQ2FwO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBsaW5lIGRhc2guXG4gICAqXG4gICAqIFBsZWFzZSBub3RlIHRoYXQgSW50ZXJuZXQgRXhwbG9yZXIgMTAgYW5kIGxvd2VyIFtkbyBub3Qgc3VwcG9ydF1bbWRuXSB0aGVcbiAgICogYHNldExpbmVEYXNoYCBtZXRob2Qgb24gdGhlIGBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkRgIGFuZCB0aGVyZWZvcmUgdGhpc1xuICAgKiBwcm9wZXJ0eSB3aWxsIGhhdmUgbm8gdmlzdWFsIGVmZmVjdCBpbiB0aGVzZSBicm93c2Vycy5cbiAgICpcbiAgICogW21kbl06IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQvc2V0TGluZURhc2gjQnJvd3Nlcl9jb21wYXRpYmlsaXR5XG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gbGluZURhc2ggTGluZSBkYXNoLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5zZXRMaW5lRGFzaCA9IGZ1bmN0aW9uIChsaW5lRGFzaCkge1xuICAgIHRoaXMubGluZURhc2hfID0gbGluZURhc2g7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGxpbmUgZGFzaCBvZmZzZXQuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gbGluZURhc2hPZmZzZXQgTGluZSBkYXNoIG9mZnNldC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuc2V0TGluZURhc2hPZmZzZXQgPSBmdW5jdGlvbiAobGluZURhc2hPZmZzZXQpIHtcbiAgICB0aGlzLmxpbmVEYXNoT2Zmc2V0XyA9IGxpbmVEYXNoT2Zmc2V0O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBsaW5lIGpvaW4uXG4gICAqXG4gICAqIEBwYXJhbSB7Q2FudmFzTGluZUpvaW58dW5kZWZpbmVkfSBsaW5lSm9pbiBMaW5lIGpvaW4uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHJva2UucHJvdG90eXBlLnNldExpbmVKb2luID0gZnVuY3Rpb24gKGxpbmVKb2luKSB7XG4gICAgdGhpcy5saW5lSm9pbl8gPSBsaW5lSm9pbjtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbWl0ZXIgbGltaXQuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gbWl0ZXJMaW1pdCBNaXRlciBsaW1pdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0cm9rZS5wcm90b3R5cGUuc2V0TWl0ZXJMaW1pdCA9IGZ1bmN0aW9uIChtaXRlckxpbWl0KSB7XG4gICAgdGhpcy5taXRlckxpbWl0XyA9IG1pdGVyTGltaXQ7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHdpZHRoLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHdpZHRoIFdpZHRoLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3Ryb2tlLnByb3RvdHlwZS5zZXRXaWR0aCA9IGZ1bmN0aW9uICh3aWR0aCkge1xuICAgIHRoaXMud2lkdGhfID0gd2lkdGg7XG4gIH07XG5cbiAgcmV0dXJuIFN0cm9rZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgU3Ryb2tlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9TdHlsZVxuICovXG5pbXBvcnQgQ2lyY2xlU3R5bGUgZnJvbSAnLi9DaXJjbGUuanMnO1xuaW1wb3J0IEZpbGwgZnJvbSAnLi9GaWxsLmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFN0cm9rZSBmcm9tICcuL1N0cm9rZS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX0gYW5kIGEgYHtudW1iZXJ9YFxuICogcmVwcmVzZW50aW5nIHRoZSB2aWV3J3MgcmVzb2x1dGlvbi4gVGhlIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gYVxuICoge0BsaW5rIG1vZHVsZTpvbC9zdHlsZS9TdHlsZX0gb3IgYW4gYXJyYXkgb2YgdGhlbS4gVGhpcyB3YXkgZS5nLiBhXG4gKiB2ZWN0b3IgbGF5ZXIgY2FuIGJlIHN0eWxlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgYHVuZGVmaW5lZGAsIHRoZVxuICogZmVhdHVyZSB3aWxsIG5vdCBiZSByZW5kZXJlZC5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZSwgbnVtYmVyKTooU3R5bGV8QXJyYXk8U3R5bGU+fHZvaWQpfSBTdHlsZUZ1bmN0aW9uXG4gKi9cblxuLyoqXG4gKiBBIHtAbGluayBTdHlsZX0sIGFuIGFycmF5IG9mIHtAbGluayBTdHlsZX0sIG9yIGEge0BsaW5rIFN0eWxlRnVuY3Rpb259LlxuICogQHR5cGVkZWYge1N0eWxlfEFycmF5PFN0eWxlPnxTdHlsZUZ1bmN0aW9ufSBTdHlsZUxpa2VcbiAqL1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmV9IGFzIGFyZ3VtZW50IGFuZCByZXR1cm5zIGFuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2dlb20vR2VvbWV0cnl9IHRoYXQgd2lsbCBiZSByZW5kZXJlZCBhbmQgc3R5bGVkIGZvciB0aGUgZmVhdHVyZS5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZSk6XG4gKiAgICAgKGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZCl9IEdlb21ldHJ5RnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEN1c3RvbSByZW5kZXJlciBmdW5jdGlvbi4gVGFrZXMgdHdvIGFyZ3VtZW50czpcbiAqXG4gKiAxLiBUaGUgcGl4ZWwgY29vcmRpbmF0ZXMgb2YgdGhlIGdlb21ldHJ5IGluIEdlb0pTT04gbm90YXRpb24uXG4gKiAyLiBUaGUge0BsaW5rIG1vZHVsZTpvbC9yZW5kZXJ+U3RhdGV9IG9mIHRoZSBsYXllciByZW5kZXJlci5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oKGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fEFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+KSxpbXBvcnQoXCIuLi9yZW5kZXIuanNcIikuU3RhdGUpOiB2b2lkfVxuICogUmVuZGVyRnVuY3Rpb25cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxHZW9tZXRyeUZ1bmN0aW9ufSBbZ2VvbWV0cnldIEZlYXR1cmUgcHJvcGVydHkgb3IgZ2VvbWV0cnlcbiAqIG9yIGZ1bmN0aW9uIHJldHVybmluZyBhIGdlb21ldHJ5IHRvIHJlbmRlciBmb3IgdGhpcyBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IFtmaWxsXSBGaWxsIHN0eWxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ltYWdlLmpzXCIpLmRlZmF1bHR9IFtpbWFnZV0gSW1hZ2Ugc3R5bGUuXG4gKiBAcHJvcGVydHkge1JlbmRlckZ1bmN0aW9ufSBbcmVuZGVyZXJdIEN1c3RvbSByZW5kZXJlci4gV2hlbiBjb25maWd1cmVkLCBgZmlsbGAsIGBzdHJva2VgIGFuZCBgaW1hZ2VgIHdpbGwgYmVcbiAqIGlnbm9yZWQsIGFuZCB0aGUgcHJvdmlkZWQgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgd2l0aCBlYWNoIHJlbmRlciBmcmFtZSBmb3IgZWFjaCBnZW9tZXRyeS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gW3N0cm9rZV0gU3Ryb2tlIHN0eWxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1RleHQuanNcIikuZGVmYXVsdH0gW3RleHRdIFRleHQgc3R5bGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pJbmRleF0gWiBpbmRleC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENvbnRhaW5lciBmb3IgdmVjdG9yIGZlYXR1cmUgcmVuZGVyaW5nIHN0eWxlcy4gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgc3R5bGVcbiAqIG9yIGl0cyBjaGlsZHJlbiB0aHJvdWdoIGBzZXQqKClgIG1ldGhvZHMgd2lsbCBub3QgdGFrZSBlZmZlY3QgdW50aWwgdGhlXG4gKiBmZWF0dXJlIG9yIGxheWVyIHRoYXQgdXNlcyB0aGUgc3R5bGUgaXMgcmUtcmVuZGVyZWQuXG4gKlxuICogIyMgRmVhdHVyZSBzdHlsZXNcbiAqXG4gKiBJZiBubyBzdHlsZSBpcyBkZWZpbmVkLCB0aGUgZm9sbG93aW5nIGRlZmF1bHQgc3R5bGUgaXMgdXNlZDpcbiAqIGBgYGpzXG4gKiAgaW1wb3J0IHtGaWxsLCBTdHJva2UsIENpcmNsZSwgU3R5bGV9IGZyb20gJ29sL3N0eWxlJztcbiAqXG4gKiAgdmFyIGZpbGwgPSBuZXcgRmlsbCh7XG4gKiAgICBjb2xvcjogJ3JnYmEoMjU1LDI1NSwyNTUsMC40KSdcbiAqICB9KTtcbiAqICB2YXIgc3Ryb2tlID0gbmV3IFN0cm9rZSh7XG4gKiAgICBjb2xvcjogJyMzMzk5Q0MnLFxuICogICAgd2lkdGg6IDEuMjVcbiAqICB9KTtcbiAqICB2YXIgc3R5bGVzID0gW1xuICogICAgbmV3IFN0eWxlKHtcbiAqICAgICAgaW1hZ2U6IG5ldyBDaXJjbGUoe1xuICogICAgICAgIGZpbGw6IGZpbGwsXG4gKiAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gKiAgICAgICAgcmFkaXVzOiA1XG4gKiAgICAgIH0pLFxuICogICAgICBmaWxsOiBmaWxsLFxuICogICAgICBzdHJva2U6IHN0cm9rZVxuICogICAgfSlcbiAqICBdO1xuICogYGBgXG4gKlxuICogQSBzZXBhcmF0ZSBlZGl0aW5nIHN0eWxlIGhhcyB0aGUgZm9sbG93aW5nIGRlZmF1bHRzOlxuICogYGBganNcbiAqICBpbXBvcnQge0ZpbGwsIFN0cm9rZSwgQ2lyY2xlLCBTdHlsZX0gZnJvbSAnb2wvc3R5bGUnO1xuICogIGltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnb2wvZ2VvbS9HZW9tZXRyeVR5cGUnO1xuICpcbiAqICB2YXIgd2hpdGUgPSBbMjU1LCAyNTUsIDI1NSwgMV07XG4gKiAgdmFyIGJsdWUgPSBbMCwgMTUzLCAyNTUsIDFdO1xuICogIHZhciB3aWR0aCA9IDM7XG4gKiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXSA9IFtcbiAqICAgIG5ldyBTdHlsZSh7XG4gKiAgICAgIGZpbGw6IG5ldyBGaWxsKHtcbiAqICAgICAgICBjb2xvcjogWzI1NSwgMjU1LCAyNTUsIDAuNV1cbiAqICAgICAgfSlcbiAqICAgIH0pXG4gKiAgXTtcbiAqICBzdHlsZXNbR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT05dID1cbiAqICAgICAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXTtcbiAqICBzdHlsZXNbR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HXSA9IFtcbiAqICAgIG5ldyBTdHlsZSh7XG4gKiAgICAgIHN0cm9rZTogbmV3IFN0cm9rZSh7XG4gKiAgICAgICAgY29sb3I6IHdoaXRlLFxuICogICAgICAgIHdpZHRoOiB3aWR0aCArIDJcbiAqICAgICAgfSlcbiAqICAgIH0pLFxuICogICAgbmV3IFN0eWxlKHtcbiAqICAgICAgc3Ryb2tlOiBuZXcgU3Ryb2tlKHtcbiAqICAgICAgICBjb2xvcjogYmx1ZSxcbiAqICAgICAgICB3aWR0aDogd2lkdGhcbiAqICAgICAgfSlcbiAqICAgIH0pXG4gKiAgXTtcbiAqICBzdHlsZXNbR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HXSA9XG4gKiAgICAgIHN0eWxlc1tHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddO1xuICogIHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9JTlRdID0gW1xuICogICAgbmV3IFN0eWxlKHtcbiAqICAgICAgaW1hZ2U6IG5ldyBDaXJjbGUoe1xuICogICAgICAgIHJhZGl1czogd2lkdGggKiAyLFxuICogICAgICAgIGZpbGw6IG5ldyBGaWxsKHtcbiAqICAgICAgICAgIGNvbG9yOiBibHVlXG4gKiAgICAgICAgfSksXG4gKiAgICAgICAgc3Ryb2tlOiBuZXcgU3Ryb2tlKHtcbiAqICAgICAgICAgIGNvbG9yOiB3aGl0ZSxcbiAqICAgICAgICAgIHdpZHRoOiB3aWR0aCAvIDJcbiAqICAgICAgICB9KVxuICogICAgICB9KSxcbiAqICAgICAgekluZGV4OiBJbmZpbml0eVxuICogICAgfSlcbiAqICBdO1xuICogIHN0eWxlc1tHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlRdID1cbiAqICAgICAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0lOVF07XG4gKiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OXSA9XG4gKiAgICAgIHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9MWUdPTl0uY29uY2F0KFxuICogICAgICAgICAgc3R5bGVzW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR10sXG4gKiAgICAgICAgICBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPSU5UXVxuICogICAgICApO1xuICogYGBgXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBTdHlsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBTdHlsZSBvcHRpb25zLlxuICAgKi9cbiAgZnVuY3Rpb24gU3R5bGUob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ3xpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR8R2VvbWV0cnlGdW5jdGlvbn1cbiAgICAgKi9cblxuICAgIHRoaXMuZ2VvbWV0cnlfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshR2VvbWV0cnlGdW5jdGlvbn1cbiAgICAgKi9cblxuICAgIHRoaXMuZ2VvbWV0cnlGdW5jdGlvbl8gPSBkZWZhdWx0R2VvbWV0cnlGdW5jdGlvbjtcblxuICAgIGlmIChvcHRpb25zLmdlb21ldHJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0R2VvbWV0cnkob3B0aW9ucy5nZW9tZXRyeSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG5cbiAgICB0aGlzLmZpbGxfID0gb3B0aW9ucy5maWxsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZpbGwgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vSW1hZ2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuaW1hZ2VfID0gb3B0aW9ucy5pbWFnZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbWFnZSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7UmVuZGVyRnVuY3Rpb258bnVsbH1cbiAgICAgKi9cblxuICAgIHRoaXMucmVuZGVyZXJfID0gb3B0aW9ucy5yZW5kZXJlciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yZW5kZXJlciA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuc3Ryb2tlXyA9IG9wdGlvbnMuc3Ryb2tlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnN0cm9rZSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9UZXh0LmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICB0aGlzLnRleHRfID0gb3B0aW9ucy50ZXh0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRleHQgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLnpJbmRleF8gPSBvcHRpb25zLnpJbmRleDtcbiAgfVxuICAvKipcbiAgICogQ2xvbmVzIHRoZSBzdHlsZS5cbiAgICogQHJldHVybiB7U3R5bGV9IFRoZSBjbG9uZWQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGdlb21ldHJ5ID0gdGhpcy5nZXRHZW9tZXRyeSgpO1xuXG4gICAgaWYgKGdlb21ldHJ5ICYmIHR5cGVvZiBnZW9tZXRyeSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGdlb21ldHJ5ID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuY2xvbmUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFN0eWxlKHtcbiAgICAgIGdlb21ldHJ5OiBnZW9tZXRyeSxcbiAgICAgIGZpbGw6IHRoaXMuZ2V0RmlsbCgpID8gdGhpcy5nZXRGaWxsKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIGltYWdlOiB0aGlzLmdldEltYWdlKCkgPyB0aGlzLmdldEltYWdlKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHN0cm9rZTogdGhpcy5nZXRTdHJva2UoKSA/IHRoaXMuZ2V0U3Ryb2tlKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHRleHQ6IHRoaXMuZ2V0VGV4dCgpID8gdGhpcy5nZXRUZXh0KCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHpJbmRleDogdGhpcy5nZXRaSW5kZXgoKVxuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjdXN0b20gcmVuZGVyZXIgZnVuY3Rpb24gdGhhdCB3YXMgY29uZmlndXJlZCB3aXRoXG4gICAqIHtAbGluayAjc2V0UmVuZGVyZXJ9IG9yIHRoZSBgcmVuZGVyZXJgIGNvbnN0cnVjdG9yIG9wdGlvbi5cbiAgICogQHJldHVybiB7UmVuZGVyRnVuY3Rpb258bnVsbH0gQ3VzdG9tIHJlbmRlcmVyIGZ1bmN0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLmdldFJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJlbmRlcmVyXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldHMgYSBjdXN0b20gcmVuZGVyZXIgZnVuY3Rpb24gZm9yIHRoaXMgc3R5bGUuIFdoZW4gc2V0LCBgZmlsbGAsIGBzdHJva2VgXG4gICAqIGFuZCBgaW1hZ2VgIG9wdGlvbnMgb2YgdGhlIHN0eWxlIHdpbGwgYmUgaWdub3JlZC5cbiAgICogQHBhcmFtIHtSZW5kZXJGdW5jdGlvbnxudWxsfSByZW5kZXJlciBDdXN0b20gcmVuZGVyZXIgZnVuY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0UmVuZGVyZXIgPSBmdW5jdGlvbiAocmVuZGVyZXIpIHtcbiAgICB0aGlzLnJlbmRlcmVyXyA9IHJlbmRlcmVyO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBnZW9tZXRyeSB0byBiZSByZW5kZXJlZC5cbiAgICogQHJldHVybiB7c3RyaW5nfGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxHZW9tZXRyeUZ1bmN0aW9ufVxuICAgKiBGZWF0dXJlIHByb3BlcnR5IG9yIGdlb21ldHJ5IG9yIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZ2VvbWV0cnkgdGhhdCB3aWxsXG4gICAqIGJlIHJlbmRlcmVkIHdpdGggdGhpcyBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRHZW9tZXRyeSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZW9tZXRyeV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gZ2VuZXJhdGUgYSBnZW9tZXRyeSBmb3IgcmVuZGVyaW5nLlxuICAgKiBAcmV0dXJuIHshR2VvbWV0cnlGdW5jdGlvbn0gRnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2l0aCBhIGZlYXR1cmVcbiAgICogYW5kIHJldHVybnMgdGhlIGdlb21ldHJ5IHRvIHJlbmRlciBpbnN0ZWFkIG9mIHRoZSBmZWF0dXJlJ3MgZ2VvbWV0cnkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuZ2V0R2VvbWV0cnlGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmlsbCBzdHlsZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IEZpbGwgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuZ2V0RmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5maWxsXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZmlsbCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gZmlsbCBGaWxsIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLnNldEZpbGwgPSBmdW5jdGlvbiAoZmlsbCkge1xuICAgIHRoaXMuZmlsbF8gPSBmaWxsO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBzdHlsZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9JbWFnZS5qc1wiKS5kZWZhdWx0fSBJbWFnZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbWFnZV87XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGltYWdlIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vSW1hZ2UuanNcIikuZGVmYXVsdH0gaW1hZ2UgSW1hZ2Ugc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0SW1hZ2UgPSBmdW5jdGlvbiAoaW1hZ2UpIHtcbiAgICB0aGlzLmltYWdlXyA9IGltYWdlO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdHJva2Ugc3R5bGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFN0cm9rZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRTdHJva2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3Ryb2tlXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgc3Ryb2tlIHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IHN0cm9rZSBTdHJva2Ugc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0U3Ryb2tlID0gZnVuY3Rpb24gKHN0cm9rZSkge1xuICAgIHRoaXMuc3Ryb2tlXyA9IHN0cm9rZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGV4dCBzdHlsZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9UZXh0LmpzXCIpLmRlZmF1bHR9IFRleHQgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuZ2V0VGV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50ZXh0XztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdGV4dCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RleHQuanNcIikuZGVmYXVsdH0gdGV4dCBUZXh0IHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU3R5bGUucHJvdG90eXBlLnNldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgIHRoaXMudGV4dF8gPSB0ZXh0O1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB6LWluZGV4IGZvciB0aGUgc3R5bGUuXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFpJbmRleC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5nZXRaSW5kZXggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuekluZGV4XztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBhIGdlb21ldHJ5IHRoYXQgaXMgcmVuZGVyZWQgaW5zdGVhZCBvZiB0aGUgZmVhdHVyZSdzIGdlb21ldHJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR8R2VvbWV0cnlGdW5jdGlvbn0gZ2VvbWV0cnlcbiAgICogICAgIEZlYXR1cmUgcHJvcGVydHkgb3IgZ2VvbWV0cnkgb3IgZnVuY3Rpb24gcmV0dXJuaW5nIGEgZ2VvbWV0cnkgdG8gcmVuZGVyXG4gICAqICAgICBmb3IgdGhpcyBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFN0eWxlLnByb3RvdHlwZS5zZXRHZW9tZXRyeSA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIGlmICh0eXBlb2YgZ2VvbWV0cnkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuZ2VvbWV0cnlGdW5jdGlvbl8gPSBnZW9tZXRyeTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBnZW9tZXRyeSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMuZ2VvbWV0cnlGdW5jdGlvbl8gPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGZlYXR1cmUuZ2V0KGdlb21ldHJ5KVxuICAgICAgICApO1xuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKCFnZW9tZXRyeSkge1xuICAgICAgdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXyA9IGRlZmF1bHRHZW9tZXRyeUZ1bmN0aW9uO1xuICAgIH0gZWxzZSBpZiAoZ2VvbWV0cnkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5nZW9tZXRyeUZ1bmN0aW9uXyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBnZW9tZXRyeVxuICAgICAgICApO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLmdlb21ldHJ5XyA9IGdlb21ldHJ5O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB6LWluZGV4LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHpJbmRleCBaSW5kZXguXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTdHlsZS5wcm90b3R5cGUuc2V0WkluZGV4ID0gZnVuY3Rpb24gKHpJbmRleCkge1xuICAgIHRoaXMuekluZGV4XyA9IHpJbmRleDtcbiAgfTtcblxuICByZXR1cm4gU3R5bGU7XG59KCk7XG4vKipcbiAqIENvbnZlcnQgdGhlIHByb3ZpZGVkIG9iamVjdCBpbnRvIGEgc3R5bGUgZnVuY3Rpb24uICBGdW5jdGlvbnMgcGFzc2VkIHRocm91Z2hcbiAqIHVuY2hhbmdlZC4gIEFycmF5cyBvZiBTdHlsZSBvciBzaW5nbGUgc3R5bGUgb2JqZWN0cyB3cmFwcGVkIGluIGFcbiAqIG5ldyBzdHlsZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7U3R5bGVGdW5jdGlvbnxBcnJheTxTdHlsZT58U3R5bGV9IG9ialxuICogICAgIEEgc3R5bGUgZnVuY3Rpb24sIGEgc2luZ2xlIHN0eWxlLCBvciBhbiBhcnJheSBvZiBzdHlsZXMuXG4gKiBAcmV0dXJuIHtTdHlsZUZ1bmN0aW9ufSBBIHN0eWxlIGZ1bmN0aW9uLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRnVuY3Rpb24ob2JqKSB7XG4gIHZhciBzdHlsZUZ1bmN0aW9uO1xuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nKSB7XG4gICAgc3R5bGVGdW5jdGlvbiA9IG9iajtcbiAgfSBlbHNlIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8U3R5bGU+fVxuICAgICAqL1xuICAgIHZhciBzdHlsZXNfMTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgIHN0eWxlc18xID0gb2JqO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQodHlwZW9mXG4gICAgICAvKiogQHR5cGUgez99ICovXG4gICAgICBvYmouZ2V0WkluZGV4ID09PSAnZnVuY3Rpb24nLCA0MSk7IC8vIEV4cGVjdGVkIGFuIGBTdHlsZWAgb3IgYW4gYXJyYXkgb2YgYFN0eWxlYFxuXG4gICAgICB2YXIgc3R5bGUgPVxuICAgICAgLyoqIEB0eXBlIHtTdHlsZX0gKi9cbiAgICAgIG9iajtcbiAgICAgIHN0eWxlc18xID0gW3N0eWxlXTtcbiAgICB9XG5cbiAgICBzdHlsZUZ1bmN0aW9uID0gZnVuY3Rpb24gc3R5bGVGdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzdHlsZXNfMTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHN0eWxlRnVuY3Rpb247XG59XG4vKipcbiAqIEB0eXBlIHtBcnJheTxTdHlsZT59XG4gKi9cblxudmFyIGRlZmF1bHRTdHlsZXMgPSBudWxsO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxTdHlsZT59IFN0eWxlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEZWZhdWx0U3R5bGUoZmVhdHVyZSwgcmVzb2x1dGlvbikge1xuICAvLyBXZSBkb24ndCB1c2UgYW4gaW1tZWRpYXRlbHktaW52b2tlZCBmdW5jdGlvblxuICAvLyBhbmQgYSBjbG9zdXJlIHNvIHdlIGRvbid0IGdldCBhbiBlcnJvciBhdCBzY3JpcHQgZXZhbHVhdGlvbiB0aW1lIGluXG4gIC8vIGJyb3dzZXJzIHRoYXQgZG8gbm90IHN1cHBvcnQgQ2FudmFzLiAoaW1wb3J0KFwiLi9DaXJjbGUuanNcIikuQ2lyY2xlU3R5bGUgZG9lc1xuICAvLyBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKSBhdCBjb25zdHJ1Y3Rpb24gdGltZSwgd2hpY2ggd2lsbCBjYXVzZSBhbi5lcnJvclxuICAvLyBpbiBzdWNoIGJyb3dzZXJzLilcbiAgaWYgKCFkZWZhdWx0U3R5bGVzKSB7XG4gICAgdmFyIGZpbGwgPSBuZXcgRmlsbCh7XG4gICAgICBjb2xvcjogJ3JnYmEoMjU1LDI1NSwyNTUsMC40KSdcbiAgICB9KTtcbiAgICB2YXIgc3Ryb2tlID0gbmV3IFN0cm9rZSh7XG4gICAgICBjb2xvcjogJyMzMzk5Q0MnLFxuICAgICAgd2lkdGg6IDEuMjVcbiAgICB9KTtcbiAgICBkZWZhdWx0U3R5bGVzID0gW25ldyBTdHlsZSh7XG4gICAgICBpbWFnZTogbmV3IENpcmNsZVN0eWxlKHtcbiAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gICAgICAgIHJhZGl1czogNVxuICAgICAgfSksXG4gICAgICBmaWxsOiBmaWxsLFxuICAgICAgc3Ryb2tlOiBzdHJva2VcbiAgICB9KV07XG4gIH1cblxuICByZXR1cm4gZGVmYXVsdFN0eWxlcztcbn1cbi8qKlxuICogRGVmYXVsdCBzdHlsZXMgZm9yIGVkaXRpbmcgZmVhdHVyZXMuXG4gKiBAcmV0dXJuIHtPYmplY3Q8aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdCwgQXJyYXk8U3R5bGU+Pn0gU3R5bGVzXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVkaXRpbmdTdHlsZSgpIHtcbiAgLyoqIEB0eXBlIHtPYmplY3Q8aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdCwgQXJyYXk8U3R5bGU+Pn0gKi9cbiAgdmFyIHN0eWxlcyA9IHt9O1xuICB2YXIgd2hpdGUgPSBbMjU1LCAyNTUsIDI1NSwgMV07XG4gIHZhciBibHVlID0gWzAsIDE1MywgMjU1LCAxXTtcbiAgdmFyIHdpZHRoID0gMztcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0xZR09OXSA9IFtuZXcgU3R5bGUoe1xuICAgIGZpbGw6IG5ldyBGaWxsKHtcbiAgICAgIGNvbG9yOiBbMjU1LCAyNTUsIDI1NSwgMC41XVxuICAgIH0pXG4gIH0pXTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OXSA9IHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9MWUdPTl07XG4gIHN0eWxlc1tHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddID0gW25ldyBTdHlsZSh7XG4gICAgc3Ryb2tlOiBuZXcgU3Ryb2tlKHtcbiAgICAgIGNvbG9yOiB3aGl0ZSxcbiAgICAgIHdpZHRoOiB3aWR0aCArIDJcbiAgICB9KVxuICB9KSwgbmV3IFN0eWxlKHtcbiAgICBzdHJva2U6IG5ldyBTdHJva2Uoe1xuICAgICAgY29sb3I6IGJsdWUsXG4gICAgICB3aWR0aDogd2lkdGhcbiAgICB9KVxuICB9KV07XG4gIHN0eWxlc1tHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkddID0gc3R5bGVzW0dlb21ldHJ5VHlwZS5MSU5FX1NUUklOR107XG4gIHN0eWxlc1tHZW9tZXRyeVR5cGUuQ0lSQ0xFXSA9IHN0eWxlc1tHZW9tZXRyeVR5cGUuUE9MWUdPTl0uY29uY2F0KHN0eWxlc1tHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddKTtcbiAgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0lOVF0gPSBbbmV3IFN0eWxlKHtcbiAgICBpbWFnZTogbmV3IENpcmNsZVN0eWxlKHtcbiAgICAgIHJhZGl1czogd2lkdGggKiAyLFxuICAgICAgZmlsbDogbmV3IEZpbGwoe1xuICAgICAgICBjb2xvcjogYmx1ZVxuICAgICAgfSksXG4gICAgICBzdHJva2U6IG5ldyBTdHJva2Uoe1xuICAgICAgICBjb2xvcjogd2hpdGUsXG4gICAgICAgIHdpZHRoOiB3aWR0aCAvIDJcbiAgICAgIH0pXG4gICAgfSksXG4gICAgekluZGV4OiBJbmZpbml0eVxuICB9KV07XG4gIHN0eWxlc1tHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlRdID0gc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0lOVF07XG4gIHN0eWxlc1tHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTl0gPSBzdHlsZXNbR2VvbWV0cnlUeXBlLlBPTFlHT05dLmNvbmNhdChzdHlsZXNbR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HXSwgc3R5bGVzW0dlb21ldHJ5VHlwZS5QT0lOVF0pO1xuICByZXR1cm4gc3R5bGVzO1xufVxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aXRoIGEgZmVhdHVyZSBhbmQgcmV0dXJucyBpdHMgZGVmYXVsdCBnZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlIHRvIGdldCB0aGUgZ2VvbWV0cnkgZm9yLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBHZW9tZXRyeSB0byByZW5kZXIuXG4gKi9cblxuZnVuY3Rpb24gZGVmYXVsdEdlb21ldHJ5RnVuY3Rpb24oZmVhdHVyZSkge1xuICByZXR1cm4gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBTdHlsZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL0Jhc2VWZWN0b3JcbiAqL1xuXG5cbmltcG9ydCBMYXllciBmcm9tICcuL0xheWVyLmpzJztcbmltcG9ydCBSQnVzaCBmcm9tICdyYnVzaCc7XG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgY3JlYXRlRGVmYXVsdFN0eWxlLCB0b0Z1bmN0aW9uIGFzIHRvU3R5bGVGdW5jdGlvbiB9IGZyb20gJy4uL3N0eWxlL1N0eWxlLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWxheWVyJ10gQSBDU1MgY2xhc3MgbmFtZSB0byBzZXQgdG8gdGhlIGxheWVyIGVsZW1lbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSAoMCwgMSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt2aXNpYmxlPXRydWVdIFZpc2liaWxpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBib3VuZGluZyBleHRlbnQgZm9yIGxheWVyIHJlbmRlcmluZy4gIFRoZSBsYXllciB3aWxsIG5vdCBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGlzIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBUaGUgei1pbmRleCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgQXQgcmVuZGVyaW5nIHRpbWUsIHRoZSBsYXllcnNcbiAqIHdpbGwgYmUgb3JkZXJlZCwgZmlyc3QgYnkgWi1pbmRleCBhbmQgdGhlbiBieSBwb3NpdGlvbi4gV2hlbiBgdW5kZWZpbmVkYCwgYSBgekluZGV4YCBvZiAwIGlzIGFzc3VtZWRcbiAqIGZvciBsYXllcnMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIG1hcCdzIGBsYXllcnNgIGNvbGxlY3Rpb24sIG9yIGBJbmZpbml0eWAgd2hlbiB0aGUgbGF5ZXIncyBgc2V0TWFwKClgXG4gKiBtZXRob2Qgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIChleGNsdXNpdmUpIGJlbG93IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcmVuZGVyLmpzXCIpLk9yZGVyRnVuY3Rpb259IFtyZW5kZXJPcmRlcl0gUmVuZGVyIG9yZGVyLiBGdW5jdGlvbiB0byBiZSB1c2VkIHdoZW4gc29ydGluZ1xuICogZmVhdHVyZXMgYmVmb3JlIHJlbmRlcmluZy4gQnkgZGVmYXVsdCBmZWF0dXJlcyBhcmUgZHJhd24gaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUgY3JlYXRlZC4gVXNlXG4gKiBgbnVsbGAgdG8gYXZvaWQgdGhlIHNvcnQsIGJ1dCBnZXQgYW4gdW5kZWZpbmVkIGRyYXcgb3JkZXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JlbmRlckJ1ZmZlcj0xMDBdIFRoZSBidWZmZXIgaW4gcGl4ZWxzIGFyb3VuZCB0aGUgdmlld3BvcnQgZXh0ZW50IHVzZWQgYnkgdGhlXG4gKiByZW5kZXJlciB3aGVuIGdldHRpbmcgZmVhdHVyZXMgZnJvbSB0aGUgdmVjdG9yIHNvdXJjZSBmb3IgdGhlIHJlbmRlcmluZyBvciBoaXQtZGV0ZWN0aW9uLlxuICogUmVjb21tZW5kZWQgdmFsdWU6IHRoZSBzaXplIG9mIHRoZSBsYXJnZXN0IHN5bWJvbCwgbGluZSB3aWR0aCBvciBsYWJlbC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc291cmNlL1ZlY3Rvci5qc1wiKS5kZWZhdWx0fSBbc291cmNlXSBTb3VyY2UuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBbbWFwXSBTZXRzIHRoZSBsYXllciBhcyBvdmVybGF5IG9uIGEgbWFwLiBUaGUgbWFwIHdpbGwgbm90IG1hbmFnZVxuICogdGhpcyBsYXllciBpbiBpdHMgbGF5ZXJzIGNvbGxlY3Rpb24sIGFuZCB0aGUgbGF5ZXIgd2lsbCBiZSByZW5kZXJlZCBvbiB0b3AuIFRoaXMgaXMgdXNlZnVsIGZvclxuICogdGVtcG9yYXJ5IGxheWVycy4gVGhlIHN0YW5kYXJkIHdheSB0byBhZGQgYSBsYXllciB0byBhIG1hcCBhbmQgaGF2ZSBpdCBtYW5hZ2VkIGJ5IHRoZSBtYXAgaXMgdG9cbiAqIHVzZSB7QGxpbmsgbW9kdWxlOm9sL01hcCNhZGRMYXllcn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkZWNsdXR0ZXI9ZmFsc2VdIERlY2x1dHRlciBpbWFnZXMgYW5kIHRleHQuIERlY2x1dHRlcmluZyBpcyBhcHBsaWVkIHRvIGFsbFxuICogaW1hZ2UgYW5kIHRleHQgc3R5bGVzIG9mIGFsbCBWZWN0b3IgYW5kIFZlY3RvclRpbGUgbGF5ZXJzIHRoYXQgaGF2ZSBzZXQgdGhpcyB0byBgdHJ1ZWAuIFRoZSBwcmlvcml0eVxuICogaXMgZGVmaW5lZCBieSB0aGUgei1pbmRleCBvZiB0aGUgbGF5ZXIsIHRoZSBgekluZGV4YCBvZiB0aGUgc3R5bGUgYW5kIHRoZSByZW5kZXIgb3JkZXIgb2YgZmVhdHVyZXMuXG4gKiBIaWdoZXIgei1pbmRleCBtZWFucyBoaWdoZXIgcHJpb3JpdHkuIFdpdGhpbiB0aGUgc2FtZSB6LWluZGV4LCBhIGZlYXR1cmUgcmVuZGVyZWQgYmVmb3JlIGFub3RoZXIgaGFzXG4gKiBoaWdoZXIgcHJpb3JpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlTGlrZXxudWxsfSBbc3R5bGVdIExheWVyIHN0eWxlLiBXaGVuIHNldCB0byBgbnVsbGAsIG9ubHlcbiAqIGZlYXR1cmVzIHRoYXQgaGF2ZSB0aGVpciBvd24gc3R5bGUgd2lsbCBiZSByZW5kZXJlZC4gU2VlIHtAbGluayBtb2R1bGU6b2wvc3R5bGV9IGZvciBkZWZhdWx0IHN0eWxlXG4gKiB3aGljaCB3aWxsIGJlIHVzZWQgaWYgdGhpcyBpcyBub3Qgc2V0LlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXBkYXRlV2hpbGVBbmltYXRpbmc9ZmFsc2VdIFdoZW4gc2V0IHRvIGB0cnVlYCwgZmVhdHVyZSBiYXRjaGVzIHdpbGxcbiAqIGJlIHJlY3JlYXRlZCBkdXJpbmcgYW5pbWF0aW9ucy4gVGhpcyBtZWFucyB0aGF0IG5vIHZlY3RvcnMgd2lsbCBiZSBzaG93biBjbGlwcGVkLCBidXQgdGhlXG4gKiBzZXR0aW5nIHdpbGwgaGF2ZSBhIHBlcmZvcm1hbmNlIGltcGFjdCBmb3IgbGFyZ2UgYW1vdW50cyBvZiB2ZWN0b3IgZGF0YS4gV2hlbiBzZXQgdG8gYGZhbHNlYCxcbiAqIGJhdGNoZXMgd2lsbCBiZSByZWNyZWF0ZWQgd2hlbiBubyBhbmltYXRpb24gaXMgYWN0aXZlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXBkYXRlV2hpbGVJbnRlcmFjdGluZz1mYWxzZV0gV2hlbiBzZXQgdG8gYHRydWVgLCBmZWF0dXJlIGJhdGNoZXMgd2lsbFxuICogYmUgcmVjcmVhdGVkIGR1cmluZyBpbnRlcmFjdGlvbnMuIFNlZSBhbHNvIGB1cGRhdGVXaGlsZUFuaW1hdGluZ2AuXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHByaXZhdGVcbiAqL1xuXG52YXIgUHJvcGVydHkgPSB7XG4gIFJFTkRFUl9PUkRFUjogJ3JlbmRlck9yZGVyJ1xufTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogVmVjdG9yIGRhdGEgdGhhdCBpcyByZW5kZXJlZCBjbGllbnQtc2lkZS5cbiAqIE5vdGUgdGhhdCBhbnkgcHJvcGVydHkgc2V0IGluIHRoZSBvcHRpb25zIGlzIHNldCBhcyBhIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9XG4gKiBwcm9wZXJ0eSBvbiB0aGUgbGF5ZXIgb2JqZWN0OyBmb3IgZXhhbXBsZSwgc2V0dGluZyBgdGl0bGU6ICdNeSBUaXRsZSdgIGluIHRoZVxuICogb3B0aW9ucyBtZWFucyB0aGF0IGB0aXRsZWAgaXMgb2JzZXJ2YWJsZSwgYW5kIGhhcyBnZXQvc2V0IGFjY2Vzc29ycy5cbiAqXG4gKiBAdGVtcGxhdGUge2ltcG9ydChcIi4uL3NvdXJjZS9WZWN0b3IuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9zb3VyY2UvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSBWZWN0b3JTb3VyY2VUeXBlXG4gKiBAZXh0ZW5kcyB7TGF5ZXI8VmVjdG9yU291cmNlVHlwZT59XG4gKiBAYXBpXG4gKi9cblxudmFyIEJhc2VWZWN0b3JMYXllciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhCYXNlVmVjdG9yTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEJhc2VWZWN0b3JMYXllcihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgYmFzZU9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy5zdHlsZTtcbiAgICBkZWxldGUgYmFzZU9wdGlvbnMucmVuZGVyQnVmZmVyO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy51cGRhdGVXaGlsZUFuaW1hdGluZztcbiAgICBkZWxldGUgYmFzZU9wdGlvbnMudXBkYXRlV2hpbGVJbnRlcmFjdGluZztcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGJhc2VPcHRpb25zKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWNsdXR0ZXJfID0gb3B0aW9ucy5kZWNsdXR0ZXIgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuZGVjbHV0dGVyIDogZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyQnVmZmVyXyA9IG9wdGlvbnMucmVuZGVyQnVmZmVyICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnJlbmRlckJ1ZmZlciA6IDEwMDtcbiAgICAvKipcbiAgICAgKiBVc2VyIHByb3ZpZGVkIHN0eWxlLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUxpa2V9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnN0eWxlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogU3R5bGUgZnVuY3Rpb24gZm9yIHVzZSB3aXRoaW4gdGhlIGxpYnJhcnkuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlRnVuY3Rpb258dW5kZWZpbmVkfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy5zdHlsZUZ1bmN0aW9uXyA9IHVuZGVmaW5lZDtcblxuICAgIF90aGlzLnNldFN0eWxlKG9wdGlvbnMuc3R5bGUpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLnVwZGF0ZVdoaWxlQW5pbWF0aW5nXyA9IG9wdGlvbnMudXBkYXRlV2hpbGVBbmltYXRpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudXBkYXRlV2hpbGVBbmltYXRpbmcgOiBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMudXBkYXRlV2hpbGVJbnRlcmFjdGluZ18gPSBvcHRpb25zLnVwZGF0ZVdoaWxlSW50ZXJhY3RpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudXBkYXRlV2hpbGVJbnRlcmFjdGluZyA6IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gRGVjbHV0dGVyLlxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuZ2V0RGVjbHV0dGVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmRlY2x1dHRlcl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRvcG1vc3QgZmVhdHVyZSB0aGF0IGludGVyc2VjdHMgdGhlIGdpdmVuIHBpeGVsIG9uIHRoZSB2aWV3cG9ydC4gUmV0dXJucyBhIHByb21pc2VcbiAgICogdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGZlYXR1cmVzLiBUaGUgYXJyYXkgd2lsbCBlaXRoZXIgY29udGFpbiB0aGUgdG9wbW9zdCBmZWF0dXJlXG4gICAqIHdoZW4gYSBoaXQgd2FzIGRldGVjdGVkLCBvciBpdCB3aWxsIGJlIGVtcHR5LlxuICAgKlxuICAgKiBUaGUgaGl0IGRldGVjdGlvbiBhbGdvcml0aG0gdXNlZCBmb3IgdGhpcyBtZXRob2QgaXMgb3B0aW1pemVkIGZvciBwZXJmb3JtYW5jZSwgYnV0IGlzIGxlc3NcbiAgICogYWNjdXJhdGUgdGhhbiB0aGUgb25lIHVzZWQgaW4ge0BsaW5rIGltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0I2dldEZlYXR1cmVzQXRQaXhlbH06IFRleHRcbiAgICogaXMgbm90IGNvbnNpZGVyZWQsIGFuZCBpY29ucyBhcmUgb25seSByZXByZXNlbnRlZCBieSB0aGVpciBib3VuZGluZyBib3ggaW5zdGVhZCBvZiB0aGUgZXhhY3RcbiAgICogaW1hZ2UuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PGltcG9ydChcIi4uL0ZlYXR1cmVcIikuZGVmYXVsdD4+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiBmZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcy5jYWxsKHRoaXMsIHBpeGVsKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcnx1bmRlZmluZWR9IFJlbmRlciBidWZmZXIuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRSZW5kZXJCdWZmZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVuZGVyQnVmZmVyXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0KTogbnVtYmVyfG51bGx8dW5kZWZpbmVkfSBSZW5kZXJcbiAgICogICAgIG9yZGVyLlxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuZ2V0UmVuZGVyT3JkZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyLmpzXCIpLk9yZGVyRnVuY3Rpb258bnVsbHx1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChQcm9wZXJ0eS5SRU5ERVJfT1JERVIpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3R5bGUgZm9yIGZlYXR1cmVzLiAgVGhpcyByZXR1cm5zIHdoYXRldmVyIHdhcyBwYXNzZWQgdG8gdGhlIGBzdHlsZWBcbiAgICogb3B0aW9uIGF0IGNvbnN0cnVjdGlvbiBvciB0byB0aGUgYHNldFN0eWxlYCBtZXRob2QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlTGlrZXxudWxsfHVuZGVmaW5lZH0gTGF5ZXIgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlVmVjdG9yTGF5ZXIucHJvdG90eXBlLmdldFN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0eWxlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3R5bGUgZnVuY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlRnVuY3Rpb258dW5kZWZpbmVkfSBMYXllciBzdHlsZSBmdW5jdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuZ2V0U3R5bGVGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdHlsZUZ1bmN0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlbmRlcmVkIGxheWVyIHNob3VsZCBiZSB1cGRhdGVkIHdoaWxlXG4gICAqICAgICBhbmltYXRpbmcuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRVcGRhdGVXaGlsZUFuaW1hdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVXaGlsZUFuaW1hdGluZ187XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSByZW5kZXJlZCBsYXllciBzaG91bGQgYmUgdXBkYXRlZCB3aGlsZVxuICAgKiAgICAgaW50ZXJhY3RpbmcuXG4gICAqL1xuXG5cbiAgQmFzZVZlY3RvckxheWVyLnByb3RvdHlwZS5nZXRVcGRhdGVXaGlsZUludGVyYWN0aW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZVdoaWxlSW50ZXJhY3RpbmdfO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGRlY2x1dHRlciBpdGVtcyBmb3IgdGhpcyBsYXllclxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUucmVuZGVyRGVjbHV0dGVyID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICBpZiAoIWZyYW1lU3RhdGUuZGVjbHV0dGVyVHJlZSkge1xuICAgICAgZnJhbWVTdGF0ZS5kZWNsdXR0ZXJUcmVlID0gbmV3IFJCdXNoKDkpO1xuICAgIH1cbiAgICAvKiogQHR5cGUgeyp9ICovXG5cblxuICAgIHRoaXMuZ2V0UmVuZGVyZXIoKS5yZW5kZXJEZWNsdXR0ZXIoZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci5qc1wiKS5PcmRlckZ1bmN0aW9ufG51bGx8dW5kZWZpbmVkfSByZW5kZXJPcmRlclxuICAgKiAgICAgUmVuZGVyIG9yZGVyLlxuICAgKi9cblxuXG4gIEJhc2VWZWN0b3JMYXllci5wcm90b3R5cGUuc2V0UmVuZGVyT3JkZXIgPSBmdW5jdGlvbiAocmVuZGVyT3JkZXIpIHtcbiAgICB0aGlzLnNldChQcm9wZXJ0eS5SRU5ERVJfT1JERVIsIHJlbmRlck9yZGVyKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgc3R5bGUgZm9yIGZlYXR1cmVzLiAgVGhpcyBjYW4gYmUgYSBzaW5nbGUgc3R5bGUgb2JqZWN0LCBhbiBhcnJheVxuICAgKiBvZiBzdHlsZXMsIG9yIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIGZlYXR1cmUgYW5kIHJlc29sdXRpb24gYW5kIHJldHVybnNcbiAgICogYW4gYXJyYXkgb2Ygc3R5bGVzLiBJZiBzZXQgdG8gYG51bGxgLCB0aGUgbGF5ZXIgaGFzIG5vIHN0eWxlIChhIGBudWxsYCBzdHlsZSksXG4gICAqIHNvIG9ubHkgZmVhdHVyZXMgdGhhdCBoYXZlIHRoZWlyIG93biBzdHlsZXMgd2lsbCBiZSByZW5kZXJlZCBpbiB0aGUgbGF5ZXIuIENhbGxcbiAgICogYHNldFN0eWxlKClgIHdpdGhvdXQgYXJndW1lbnRzIHRvIHJlc2V0IHRvIHRoZSBkZWZhdWx0IHN0eWxlLiBTZWVcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9zdHlsZX0gZm9yIGluZm9ybWF0aW9uIG9uIHRoZSBkZWZhdWx0IHN0eWxlLlxuICAgKiBAcGFyYW0geyhpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUxpa2V8bnVsbCk9fSBvcHRfc3R5bGUgTGF5ZXIgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlVmVjdG9yTGF5ZXIucHJvdG90eXBlLnNldFN0eWxlID0gZnVuY3Rpb24gKG9wdF9zdHlsZSkge1xuICAgIHRoaXMuc3R5bGVfID0gb3B0X3N0eWxlICE9PSB1bmRlZmluZWQgPyBvcHRfc3R5bGUgOiBjcmVhdGVEZWZhdWx0U3R5bGU7XG4gICAgdGhpcy5zdHlsZUZ1bmN0aW9uXyA9IG9wdF9zdHlsZSA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvU3R5bGVGdW5jdGlvbih0aGlzLnN0eWxlXyk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG5cbiAgcmV0dXJuIEJhc2VWZWN0b3JMYXllcjtcbn0oTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBCYXNlVmVjdG9yTGF5ZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvSW5zdHJ1Y3Rpb25cbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbnZhciBJbnN0cnVjdGlvbiA9IHtcbiAgQkVHSU5fR0VPTUVUUlk6IDAsXG4gIEJFR0lOX1BBVEg6IDEsXG4gIENJUkNMRTogMixcbiAgQ0xPU0VfUEFUSDogMyxcbiAgQ1VTVE9NOiA0LFxuICBEUkFXX0NIQVJTOiA1LFxuICBEUkFXX0lNQUdFOiA2LFxuICBFTkRfR0VPTUVUUlk6IDcsXG4gIEZJTEw6IDgsXG4gIE1PVkVfVE9fTElORV9UTzogOSxcbiAgU0VUX0ZJTExfU1RZTEU6IDEwLFxuICBTRVRfU1RST0tFX1NUWUxFOiAxMSxcbiAgU1RST0tFOiAxMlxufTtcbi8qKlxuICogQHR5cGUge0FycmF5PEluc3RydWN0aW9uPn1cbiAqL1xuXG5leHBvcnQgdmFyIGZpbGxJbnN0cnVjdGlvbiA9IFtJbnN0cnVjdGlvbi5GSUxMXTtcbi8qKlxuICogQHR5cGUge0FycmF5PEluc3RydWN0aW9uPn1cbiAqL1xuXG5leHBvcnQgdmFyIHN0cm9rZUluc3RydWN0aW9uID0gW0luc3RydWN0aW9uLlNUUk9LRV07XG4vKipcbiAqIEB0eXBlIHtBcnJheTxJbnN0cnVjdGlvbj59XG4gKi9cblxuZXhwb3J0IHZhciBiZWdpblBhdGhJbnN0cnVjdGlvbiA9IFtJbnN0cnVjdGlvbi5CRUdJTl9QQVRIXTtcbi8qKlxuICogQHR5cGUge0FycmF5PEluc3RydWN0aW9uPn1cbiAqL1xuXG5leHBvcnQgdmFyIGNsb3NlUGF0aEluc3RydWN0aW9uID0gW0luc3RydWN0aW9uLkNMT1NFX1BBVEhdO1xuZXhwb3J0IGRlZmF1bHQgSW5zdHJ1Y3Rpb247IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9WZWN0b3JDb250ZXh0XG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBDb250ZXh0IGZvciBkcmF3aW5nIGdlb21ldHJpZXMuICBBIHZlY3RvciBjb250ZXh0IGlzIGF2YWlsYWJsZSBvbiByZW5kZXJcbiAqIGV2ZW50cyBhbmQgZG9lcyBub3QgbmVlZCB0byBiZSBjb25zdHJ1Y3RlZCBkaXJlY3RseS5cbiAqIEBhcGlcbiAqL1xudmFyIFZlY3RvckNvbnRleHQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBWZWN0b3JDb250ZXh0KCkge31cbiAgLyoqXG4gICAqIFJlbmRlciBhIGdlb21ldHJ5IHdpdGggYSBjdXN0b20gcmVuZGVyZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlbmRlcmVyIFJlbmRlcmVyLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdDdXN0b20gPSBmdW5jdGlvbiAoZ2VvbWV0cnksIGZlYXR1cmUsIHJlbmRlcmVyKSB7fTtcbiAgLyoqXG4gICAqIFJlbmRlciBhIGdlb21ldHJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgVGhlIGdlb21ldHJ5IHRvIHJlbmRlci5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3R2VvbWV0cnkgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHt9O1xuICAvKipcbiAgICogU2V0IHRoZSByZW5kZXJpbmcgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgVGhlIHJlbmRlcmluZyBzdHlsZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5zZXRTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGNpcmNsZUdlb21ldHJ5IENpcmNsZSBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3Q2lyY2xlID0gZnVuY3Rpb24gKGNpcmNsZUdlb21ldHJ5LCBmZWF0dXJlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd0ZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSwgc3R5bGUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5Q29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeUNvbGxlY3Rpb25HZW9tZXRyeSBHZW9tZXRyeSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdHZW9tZXRyeUNvbGxlY3Rpb24gPSBmdW5jdGlvbiAoZ2VvbWV0cnlDb2xsZWN0aW9uR2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gbGluZVN0cmluZ0dlb21ldHJ5IExpbmUgc3RyaW5nIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5kcmF3TGluZVN0cmluZyA9IGZ1bmN0aW9uIChsaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeSBNdWx0aUxpbmVTdHJpbmcgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdNdWx0aUxpbmVTdHJpbmcgPSBmdW5jdGlvbiAobXVsdGlMaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL011bHRpUG9pbnQuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gbXVsdGlQb2ludEdlb21ldHJ5IE11bHRpUG9pbnQgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdNdWx0aVBvaW50ID0gZnVuY3Rpb24gKG11bHRpUG9pbnRHZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9IG11bHRpUG9seWdvbkdlb21ldHJ5IE11bHRpUG9seWdvbiBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd011bHRpUG9seWdvbiA9IGZ1bmN0aW9uIChtdWx0aVBvbHlnb25HZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vUG9pbnQuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gcG9pbnRHZW9tZXRyeSBQb2ludCBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgVmVjdG9yQ29udGV4dC5wcm90b3R5cGUuZHJhd1BvaW50ID0gZnVuY3Rpb24gKHBvaW50R2VvbWV0cnksIGZlYXR1cmUpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gcG9seWdvbkdlb21ldHJ5IFBvbHlnb24gZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdQb2x5Z29uID0gZnVuY3Rpb24gKHBvbHlnb25HZW9tZXRyeSwgZmVhdHVyZSkge307XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLmRyYXdUZXh0ID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBmZWF0dXJlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvRmlsbC5qc1wiKS5kZWZhdWx0fSBmaWxsU3R5bGUgRmlsbCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHJva2UuanNcIikuZGVmYXVsdH0gc3Ryb2tlU3R5bGUgU3Ryb2tlIHN0eWxlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLnNldEZpbGxTdHJva2VTdHlsZSA9IGZ1bmN0aW9uIChmaWxsU3R5bGUsIHN0cm9rZVN0eWxlKSB7fTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvSW1hZ2UuanNcIikuZGVmYXVsdH0gaW1hZ2VTdHlsZSBJbWFnZSBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHQ9fSBvcHRfZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCBTaGFyZWQgZGF0YSBmb3IgY29tYmluZWQgZGVjbHV0dGVyaW5nIHdpdGggYSB0ZXh0IHN0eWxlLlxuICAgKi9cblxuXG4gIFZlY3RvckNvbnRleHQucHJvdG90eXBlLnNldEltYWdlU3R5bGUgPSBmdW5jdGlvbiAoaW1hZ2VTdHlsZSwgb3B0X2RlY2x1dHRlckltYWdlV2l0aFRleHQpIHt9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9UZXh0LmpzXCIpLmRlZmF1bHR9IHRleHRTdHlsZSBUZXh0IHN0eWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMuanNcIikuRGVjbHV0dGVySW1hZ2VXaXRoVGV4dD19IG9wdF9kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0IFNoYXJlZCBkYXRhIGZvciBjb21iaW5lZCBkZWNsdXR0ZXJpbmcgd2l0aCBhbiBpbWFnZSBzdHlsZS5cbiAgICovXG5cblxuICBWZWN0b3JDb250ZXh0LnByb3RvdHlwZS5zZXRUZXh0U3R5bGUgPSBmdW5jdGlvbiAodGV4dFN0eWxlLCBvcHRfZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCkge307XG5cbiAgcmV0dXJuIFZlY3RvckNvbnRleHQ7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvckNvbnRleHQ7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL0J1aWxkZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNJbnN0cnVjdGlvbiBmcm9tICcuL0luc3RydWN0aW9uLmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFJlbGF0aW9uc2hpcCBmcm9tICcuLi8uLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzJztcbmltcG9ydCBWZWN0b3JDb250ZXh0IGZyb20gJy4uL1ZlY3RvckNvbnRleHQuanMnO1xuaW1wb3J0IHsgYXNDb2xvckxpa2UgfSBmcm9tICcuLi8uLi9jb2xvcmxpa2UuanMnO1xuaW1wb3J0IHsgYnVmZmVyLCBjbG9uZSwgY29udGFpbnNDb29yZGluYXRlLCBjb29yZGluYXRlUmVsYXRpb25zaGlwIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmF1bHRGaWxsU3R5bGUsIGRlZmF1bHRMaW5lQ2FwLCBkZWZhdWx0TGluZURhc2gsIGRlZmF1bHRMaW5lRGFzaE9mZnNldCwgZGVmYXVsdExpbmVKb2luLCBkZWZhdWx0TGluZVdpZHRoLCBkZWZhdWx0TWl0ZXJMaW1pdCwgZGVmYXVsdFN0cm9rZVN0eWxlIH0gZnJvbSAnLi4vY2FudmFzLmpzJztcbmltcG9ydCB7IGVxdWFscywgcmV2ZXJzZVN1YkFycmF5IH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzLCBpbmZsYXRlQ29vcmRpbmF0ZXNBcnJheSwgaW5mbGF0ZU11bHRpQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4uLy4uL2dlb20vZmxhdC9pbmZsYXRlLmpzJztcblxudmFyIENhbnZhc0J1aWxkZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzQnVpbGRlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heEV4dGVudCBNYXhpbXVtIGV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzQnVpbGRlcih0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cblxuICAgIF90aGlzLnRvbGVyYW5jZSA9IHRvbGVyYW5jZTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQGNvbnN0XG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5tYXhFeHRlbnQgPSBtYXhFeHRlbnQ7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5waXhlbFJhdGlvID0gcGl4ZWxSYXRpbztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heExpbmVXaWR0aCA9IDA7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEBjb25zdFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTwqPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmJlZ2luR2VvbWV0cnlJbnN0cnVjdGlvbjFfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTwqPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmJlZ2luR2VvbWV0cnlJbnN0cnVjdGlvbjJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYnVmZmVyZWRNYXhFeHRlbnRfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0FycmF5PCo+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW5zdHJ1Y3Rpb25zID0gW107XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29vcmRpbmF0ZXMgPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50bXBDb29yZGluYXRlXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8Kj59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMgPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdGF0ZSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSAqL1xuICAgIHt9O1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGRhc2hBcnJheSBEYXNoIGFycmF5LlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBEYXNoIGFycmF5IHdpdGggcGl4ZWwgcmF0aW8gYXBwbGllZFxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmFwcGx5UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChkYXNoQXJyYXkpIHtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IHRoaXMucGl4ZWxSYXRpbztcbiAgICByZXR1cm4gcGl4ZWxSYXRpbyA9PSAxID8gZGFzaEFycmF5IDogZGFzaEFycmF5Lm1hcChmdW5jdGlvbiAoZGFzaCkge1xuICAgICAgcmV0dXJuIGRhc2ggKiBwaXhlbFJhdGlvO1xuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7bnVtYmVyfSBNeSBlbmRcbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5hcHBlbmRGbGF0UG9pbnRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIHN0cmlkZSkge1xuICAgIHZhciBleHRlbnQgPSB0aGlzLmdldEJ1ZmZlcmVkTWF4RXh0ZW50KCk7XG4gICAgdmFyIHRtcENvb3JkID0gdGhpcy50bXBDb29yZGluYXRlXztcbiAgICB2YXIgY29vcmRpbmF0ZXMgPSB0aGlzLmNvb3JkaW5hdGVzO1xuICAgIHZhciBteUVuZCA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHRtcENvb3JkWzBdID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdG1wQ29vcmRbMV0gPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuXG4gICAgICBpZiAoY29udGFpbnNDb29yZGluYXRlKGV4dGVudCwgdG1wQ29vcmQpKSB7XG4gICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gdG1wQ29vcmRbMF07XG4gICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gdG1wQ29vcmRbMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG15RW5kO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBjbG9zZWQgTGFzdCBpbnB1dCBjb29yZGluYXRlIGVxdWFscyBmaXJzdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBza2lwRmlyc3QgU2tpcCBmaXJzdCBjb29yZGluYXRlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge251bWJlcn0gTXkgZW5kLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLmFwcGVuZEZsYXRMaW5lQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCBjbG9zZWQsIHNraXBGaXJzdCkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IHRoaXMuY29vcmRpbmF0ZXM7XG4gICAgdmFyIG15RW5kID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHZhciBleHRlbnQgPSB0aGlzLmdldEJ1ZmZlcmVkTWF4RXh0ZW50KCk7XG5cbiAgICBpZiAoc2tpcEZpcnN0KSB7XG4gICAgICBvZmZzZXQgKz0gc3RyaWRlO1xuICAgIH1cblxuICAgIHZhciBsYXN0WENvb3JkID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gICAgdmFyIGxhc3RZQ29vcmQgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgdmFyIG5leHRDb29yZCA9IHRoaXMudG1wQ29vcmRpbmF0ZV87XG4gICAgdmFyIHNraXBwZWQgPSB0cnVlO1xuICAgIHZhciBpLCBsYXN0UmVsLCBuZXh0UmVsO1xuXG4gICAgZm9yIChpID0gb2Zmc2V0ICsgc3RyaWRlOyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgICAgbmV4dENvb3JkWzBdID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgbmV4dENvb3JkWzFdID0gZmxhdENvb3JkaW5hdGVzW2kgKyAxXTtcbiAgICAgIG5leHRSZWwgPSBjb29yZGluYXRlUmVsYXRpb25zaGlwKGV4dGVudCwgbmV4dENvb3JkKTtcblxuICAgICAgaWYgKG5leHRSZWwgIT09IGxhc3RSZWwpIHtcbiAgICAgICAgaWYgKHNraXBwZWQpIHtcbiAgICAgICAgICBjb29yZGluYXRlc1tteUVuZCsrXSA9IGxhc3RYQ29vcmQ7XG4gICAgICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSBsYXN0WUNvb3JkO1xuICAgICAgICAgIHNraXBwZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbmV4dENvb3JkWzBdO1xuICAgICAgICBjb29yZGluYXRlc1tteUVuZCsrXSA9IG5leHRDb29yZFsxXTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dFJlbCA9PT0gUmVsYXRpb25zaGlwLklOVEVSU0VDVElORykge1xuICAgICAgICBjb29yZGluYXRlc1tteUVuZCsrXSA9IG5leHRDb29yZFswXTtcbiAgICAgICAgY29vcmRpbmF0ZXNbbXlFbmQrK10gPSBuZXh0Q29vcmRbMV07XG4gICAgICAgIHNraXBwZWQgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNraXBwZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBsYXN0WENvb3JkID0gbmV4dENvb3JkWzBdO1xuICAgICAgbGFzdFlDb29yZCA9IG5leHRDb29yZFsxXTtcbiAgICAgIGxhc3RSZWwgPSBuZXh0UmVsO1xuICAgIH0gLy8gTGFzdCBjb29yZGluYXRlIGVxdWFscyBmaXJzdCBvciBvbmx5IG9uZSBwb2ludCB0byBhcHBlbmQ6XG5cblxuICAgIGlmIChjbG9zZWQgJiYgc2tpcHBlZCB8fCBpID09PSBvZmZzZXQgKyBzdHJpZGUpIHtcbiAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbGFzdFhDb29yZDtcbiAgICAgIGNvb3JkaW5hdGVzW215RW5kKytdID0gbGFzdFlDb29yZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbXlFbmQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBlbmRzIEVuZHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGJ1aWxkZXJFbmRzIEJ1aWxkZXIgZW5kcy5cbiAgICogQHJldHVybiB7bnVtYmVyfSBPZmZzZXQuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuZHJhd0N1c3RvbUNvb3JkaW5hdGVzXyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlLCBidWlsZGVyRW5kcykge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgICB2YXIgYnVpbGRlckVuZCA9IHRoaXMuYXBwZW5kRmxhdExpbmVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGZhbHNlLCBmYWxzZSk7XG4gICAgICBidWlsZGVyRW5kcy5wdXNoKGJ1aWxkZXJFbmQpO1xuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZW5kZXJlciBSZW5kZXJlci5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5kcmF3Q3VzdG9tID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBmZWF0dXJlLCByZW5kZXJlcikge1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShnZW9tZXRyeSwgZmVhdHVyZSk7XG4gICAgdmFyIHR5cGUgPSBnZW9tZXRyeS5nZXRUeXBlKCk7XG4gICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHZhciBidWlsZGVyQmVnaW4gPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzLCBidWlsZGVyRW5kLCBidWlsZGVyRW5kcywgYnVpbGRlckVuZHNzO1xuICAgIHZhciBvZmZzZXQ7XG5cbiAgICBpZiAodHlwZSA9PSBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTikge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICBidWlsZGVyRW5kc3MgPSBbXTtcbiAgICAgIHZhciBlbmRzcyA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBnZW9tZXRyeS5nZXRFbmRzcygpO1xuICAgICAgb2Zmc2V0ID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgbXlFbmRzID0gW107XG4gICAgICAgIG9mZnNldCA9IHRoaXMuZHJhd0N1c3RvbUNvb3JkaW5hdGVzXyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc3NbaV0sIHN0cmlkZSwgbXlFbmRzKTtcbiAgICAgICAgYnVpbGRlckVuZHNzLnB1c2gobXlFbmRzKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uQ1VTVE9NLCBidWlsZGVyQmVnaW4sIGJ1aWxkZXJFbmRzcywgZ2VvbWV0cnksIHJlbmRlcmVyLCBpbmZsYXRlTXVsdGlDb29yZGluYXRlc0FycmF5XSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09IEdlb21ldHJ5VHlwZS5QT0xZR09OIHx8IHR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HKSB7XG4gICAgICBidWlsZGVyRW5kcyA9IFtdO1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gdHlwZSA9PSBHZW9tZXRyeVR5cGUuUE9MWUdPTiA/XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSA6IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgICAgb2Zmc2V0ID0gdGhpcy5kcmF3Q3VzdG9tQ29vcmRpbmF0ZXNfKGZsYXRDb29yZGluYXRlcywgMCxcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LmdldEVuZHMoKSwgc3RyaWRlLCBidWlsZGVyRW5kcyk7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5DVVNUT00sIGJ1aWxkZXJCZWdpbiwgYnVpbGRlckVuZHMsIGdlb21ldHJ5LCByZW5kZXJlciwgaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXldKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HIHx8IHR5cGUgPT0gR2VvbWV0cnlUeXBlLkNJUkNMRSkge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICBidWlsZGVyRW5kID0gdGhpcy5hcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uQ1VTVE9NLCBidWlsZGVyQmVnaW4sIGJ1aWxkZXJFbmQsIGdlb21ldHJ5LCByZW5kZXJlciwgaW5mbGF0ZUNvb3JkaW5hdGVzXSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09IEdlb21ldHJ5VHlwZS5NVUxUSV9QT0lOVCkge1xuICAgICAgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICBidWlsZGVyRW5kID0gdGhpcy5hcHBlbmRGbGF0UG9pbnRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIHN0cmlkZSk7XG5cbiAgICAgIGlmIChidWlsZGVyRW5kID4gYnVpbGRlckJlZ2luKSB7XG4gICAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkNVU1RPTSwgYnVpbGRlckJlZ2luLCBidWlsZGVyRW5kLCBnZW9tZXRyeSwgcmVuZGVyZXIsIGluZmxhdGVDb29yZGluYXRlc10pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PSBHZW9tZXRyeVR5cGUuUE9JTlQpIHtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgICAgdGhpcy5jb29yZGluYXRlcy5wdXNoKGZsYXRDb29yZGluYXRlc1swXSwgZmxhdENvb3JkaW5hdGVzWzFdKTtcbiAgICAgIGJ1aWxkZXJFbmQgPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkNVU1RPTSwgYnVpbGRlckJlZ2luLCBidWlsZGVyRW5kLCBnZW9tZXRyeSwgcmVuZGVyZXJdKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vR2VvbWV0cnlcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IFRoZSBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuYmVnaW5HZW9tZXRyeSA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMV8gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uQkVHSU5fR0VPTUVUUlksIGZlYXR1cmUsIDAsIGdlb21ldHJ5XTtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMV8pO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMl8gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uQkVHSU5fR0VPTUVUUlksIGZlYXR1cmUsIDAsIGdlb21ldHJ5XTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMl8pO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9uc30gdGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnMuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpbnN0cnVjdGlvbnM6IHRoaXMuaW5zdHJ1Y3Rpb25zLFxuICAgICAgaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zOiB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucyxcbiAgICAgIGNvb3JkaW5hdGVzOiB0aGlzLmNvb3JkaW5hdGVzXG4gICAgfTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldmVyc2UgdGhlIGhpdCBkZXRlY3Rpb24gaW5zdHJ1Y3Rpb25zLlxuICAgKi9cblxuXG4gIENhbnZhc0J1aWxkZXIucHJvdG90eXBlLnJldmVyc2VIaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGhpdERldGVjdGlvbkluc3RydWN0aW9ucyA9IHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zOyAvLyBzdGVwIDEgLSByZXZlcnNlIGFycmF5XG5cbiAgICBoaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucmV2ZXJzZSgpOyAvLyBzdGVwIDIgLSByZXZlcnNlIGluc3RydWN0aW9ucyB3aXRoaW4gZ2VvbWV0cnkgYmxvY2tzXG5cbiAgICB2YXIgaTtcbiAgICB2YXIgbiA9IGhpdERldGVjdGlvbkluc3RydWN0aW9ucy5sZW5ndGg7XG4gICAgdmFyIGluc3RydWN0aW9uO1xuICAgIHZhciB0eXBlO1xuICAgIHZhciBiZWdpbiA9IC0xO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaW5zdHJ1Y3Rpb24gPSBoaXREZXRlY3Rpb25JbnN0cnVjdGlvbnNbaV07XG4gICAgICB0eXBlID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9JbnN0cnVjdGlvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgaW5zdHJ1Y3Rpb25bMF07XG5cbiAgICAgIGlmICh0eXBlID09IENhbnZhc0luc3RydWN0aW9uLkVORF9HRU9NRVRSWSkge1xuICAgICAgICBiZWdpbiA9IGk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gQ2FudmFzSW5zdHJ1Y3Rpb24uQkVHSU5fR0VPTUVUUlkpIHtcbiAgICAgICAgaW5zdHJ1Y3Rpb25bMl0gPSBpO1xuICAgICAgICByZXZlcnNlU3ViQXJyYXkodGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMsIGJlZ2luLCBpKTtcbiAgICAgICAgYmVnaW4gPSAtMTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL0ZpbGwuanNcIikuZGVmYXVsdH0gZmlsbFN0eWxlIEZpbGwgc3R5bGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IHN0cm9rZVN0eWxlIFN0cm9rZSBzdHlsZS5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5zZXRGaWxsU3Ryb2tlU3R5bGUgPSBmdW5jdGlvbiAoZmlsbFN0eWxlLCBzdHJva2VTdHlsZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG5cbiAgICBpZiAoZmlsbFN0eWxlKSB7XG4gICAgICB2YXIgZmlsbFN0eWxlQ29sb3IgPSBmaWxsU3R5bGUuZ2V0Q29sb3IoKTtcbiAgICAgIHN0YXRlLmZpbGxTdHlsZSA9IGFzQ29sb3JMaWtlKGZpbGxTdHlsZUNvbG9yID8gZmlsbFN0eWxlQ29sb3IgOiBkZWZhdWx0RmlsbFN0eWxlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuZmlsbFN0eWxlID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChzdHJva2VTdHlsZSkge1xuICAgICAgdmFyIHN0cm9rZVN0eWxlQ29sb3IgPSBzdHJva2VTdHlsZS5nZXRDb2xvcigpO1xuICAgICAgc3RhdGUuc3Ryb2tlU3R5bGUgPSBhc0NvbG9yTGlrZShzdHJva2VTdHlsZUNvbG9yID8gc3Ryb2tlU3R5bGVDb2xvciA6IGRlZmF1bHRTdHJva2VTdHlsZSk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lQ2FwID0gc3Ryb2tlU3R5bGUuZ2V0TGluZUNhcCgpO1xuICAgICAgc3RhdGUubGluZUNhcCA9IHN0cm9rZVN0eWxlTGluZUNhcCAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVMaW5lQ2FwIDogZGVmYXVsdExpbmVDYXA7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lRGFzaCA9IHN0cm9rZVN0eWxlLmdldExpbmVEYXNoKCk7XG4gICAgICBzdGF0ZS5saW5lRGFzaCA9IHN0cm9rZVN0eWxlTGluZURhc2ggPyBzdHJva2VTdHlsZUxpbmVEYXNoLnNsaWNlKCkgOiBkZWZhdWx0TGluZURhc2g7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lRGFzaE9mZnNldCA9IHN0cm9rZVN0eWxlLmdldExpbmVEYXNoT2Zmc2V0KCk7XG4gICAgICBzdGF0ZS5saW5lRGFzaE9mZnNldCA9IHN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgPyBzdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0IDogZGVmYXVsdExpbmVEYXNoT2Zmc2V0O1xuICAgICAgdmFyIHN0cm9rZVN0eWxlTGluZUpvaW4gPSBzdHJva2VTdHlsZS5nZXRMaW5lSm9pbigpO1xuICAgICAgc3RhdGUubGluZUpvaW4gPSBzdHJva2VTdHlsZUxpbmVKb2luICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZUxpbmVKb2luIDogZGVmYXVsdExpbmVKb2luO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlV2lkdGggPSBzdHJva2VTdHlsZS5nZXRXaWR0aCgpO1xuICAgICAgc3RhdGUubGluZVdpZHRoID0gc3Ryb2tlU3R5bGVXaWR0aCAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVXaWR0aCA6IGRlZmF1bHRMaW5lV2lkdGg7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVNaXRlckxpbWl0ID0gc3Ryb2tlU3R5bGUuZ2V0TWl0ZXJMaW1pdCgpO1xuICAgICAgc3RhdGUubWl0ZXJMaW1pdCA9IHN0cm9rZVN0eWxlTWl0ZXJMaW1pdCAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVNaXRlckxpbWl0IDogZGVmYXVsdE1pdGVyTGltaXQ7XG5cbiAgICAgIGlmIChzdGF0ZS5saW5lV2lkdGggPiB0aGlzLm1heExpbmVXaWR0aCkge1xuICAgICAgICB0aGlzLm1heExpbmVXaWR0aCA9IHN0YXRlLmxpbmVXaWR0aDsgLy8gaW52YWxpZGF0ZSB0aGUgYnVmZmVyZWQgbWF4IGV4dGVudCBjYWNoZVxuXG4gICAgICAgIHRoaXMuYnVmZmVyZWRNYXhFeHRlbnRfID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUuc3Ryb2tlU3R5bGUgPSB1bmRlZmluZWQ7XG4gICAgICBzdGF0ZS5saW5lQ2FwID0gdW5kZWZpbmVkO1xuICAgICAgc3RhdGUubGluZURhc2ggPSBudWxsO1xuICAgICAgc3RhdGUubGluZURhc2hPZmZzZXQgPSB1bmRlZmluZWQ7XG4gICAgICBzdGF0ZS5saW5lSm9pbiA9IHVuZGVmaW5lZDtcbiAgICAgIHN0YXRlLmxpbmVXaWR0aCA9IHVuZGVmaW5lZDtcbiAgICAgIHN0YXRlLm1pdGVyTGltaXQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSBzdGF0ZSBTdGF0ZS5cbiAgICogQHJldHVybiB7QXJyYXk8Kj59IEZpbGwgaW5zdHJ1Y3Rpb24uXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuY3JlYXRlRmlsbCA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgIHZhciBmaWxsU3R5bGUgPSBzdGF0ZS5maWxsU3R5bGU7XG4gICAgLyoqIEB0eXBlIHtBcnJheTwqPn0gKi9cblxuICAgIHZhciBmaWxsSW5zdHJ1Y3Rpb24gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX0ZJTExfU1RZTEUsIGZpbGxTdHlsZV07XG5cbiAgICBpZiAodHlwZW9mIGZpbGxTdHlsZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIEZpbGwgaXMgYSBwYXR0ZXJuIG9yIGdyYWRpZW50IC0gYWxpZ24gaXQhXG4gICAgICBmaWxsSW5zdHJ1Y3Rpb24ucHVzaCh0cnVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmlsbEluc3RydWN0aW9uO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSBzdGF0ZSBTdGF0ZS5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5hcHBseVN0cm9rZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2godGhpcy5jcmVhdGVTdHJva2Uoc3RhdGUpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdHJva2VTdGF0ZX0gc3RhdGUgU3RhdGUuXG4gICAqIEByZXR1cm4ge0FycmF5PCo+fSBTdHJva2UgaW5zdHJ1Y3Rpb24uXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuY3JlYXRlU3Ryb2tlID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgcmV0dXJuIFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfU1RST0tFX1NUWUxFLCBzdGF0ZS5zdHJva2VTdHlsZSwgc3RhdGUubGluZVdpZHRoICogdGhpcy5waXhlbFJhdGlvLCBzdGF0ZS5saW5lQ2FwLCBzdGF0ZS5saW5lSm9pbiwgc3RhdGUubWl0ZXJMaW1pdCwgdGhpcy5hcHBseVBpeGVsUmF0aW8oc3RhdGUubGluZURhc2gpLCBzdGF0ZS5saW5lRGFzaE9mZnNldCAqIHRoaXMucGl4ZWxSYXRpb107XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGV9IHN0YXRlIFN0YXRlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKHRoaXM6Q2FudmFzQnVpbGRlciwgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdHJva2VTdGF0ZSk6QXJyYXk8Kj59IGNyZWF0ZUZpbGwgQ3JlYXRlIGZpbGwuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUudXBkYXRlRmlsbFN0eWxlID0gZnVuY3Rpb24gKHN0YXRlLCBjcmVhdGVGaWxsKSB7XG4gICAgdmFyIGZpbGxTdHlsZSA9IHN0YXRlLmZpbGxTdHlsZTtcblxuICAgIGlmICh0eXBlb2YgZmlsbFN0eWxlICE9PSAnc3RyaW5nJyB8fCBzdGF0ZS5jdXJyZW50RmlsbFN0eWxlICE9IGZpbGxTdHlsZSkge1xuICAgICAgaWYgKGZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goY3JlYXRlRmlsbC5jYWxsKHRoaXMsIHN0YXRlKSk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLmN1cnJlbnRGaWxsU3R5bGUgPSBmaWxsU3R5bGU7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSBzdGF0ZSBTdGF0ZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOkNhbnZhc0J1aWxkZXIsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3Ryb2tlU3RhdGUpOiB2b2lkfSBhcHBseVN0cm9rZSBBcHBseSBzdHJva2UuXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUudXBkYXRlU3Ryb2tlU3R5bGUgPSBmdW5jdGlvbiAoc3RhdGUsIGFwcGx5U3Ryb2tlKSB7XG4gICAgdmFyIHN0cm9rZVN0eWxlID0gc3RhdGUuc3Ryb2tlU3R5bGU7XG4gICAgdmFyIGxpbmVDYXAgPSBzdGF0ZS5saW5lQ2FwO1xuICAgIHZhciBsaW5lRGFzaCA9IHN0YXRlLmxpbmVEYXNoO1xuICAgIHZhciBsaW5lRGFzaE9mZnNldCA9IHN0YXRlLmxpbmVEYXNoT2Zmc2V0O1xuICAgIHZhciBsaW5lSm9pbiA9IHN0YXRlLmxpbmVKb2luO1xuICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGg7XG4gICAgdmFyIG1pdGVyTGltaXQgPSBzdGF0ZS5taXRlckxpbWl0O1xuXG4gICAgaWYgKHN0YXRlLmN1cnJlbnRTdHJva2VTdHlsZSAhPSBzdHJva2VTdHlsZSB8fCBzdGF0ZS5jdXJyZW50TGluZUNhcCAhPSBsaW5lQ2FwIHx8IGxpbmVEYXNoICE9IHN0YXRlLmN1cnJlbnRMaW5lRGFzaCAmJiAhZXF1YWxzKHN0YXRlLmN1cnJlbnRMaW5lRGFzaCwgbGluZURhc2gpIHx8IHN0YXRlLmN1cnJlbnRMaW5lRGFzaE9mZnNldCAhPSBsaW5lRGFzaE9mZnNldCB8fCBzdGF0ZS5jdXJyZW50TGluZUpvaW4gIT0gbGluZUpvaW4gfHwgc3RhdGUuY3VycmVudExpbmVXaWR0aCAhPSBsaW5lV2lkdGggfHwgc3RhdGUuY3VycmVudE1pdGVyTGltaXQgIT0gbWl0ZXJMaW1pdCkge1xuICAgICAgaWYgKHN0cm9rZVN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXBwbHlTdHJva2UuY2FsbCh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLmN1cnJlbnRTdHJva2VTdHlsZSA9IHN0cm9rZVN0eWxlO1xuICAgICAgc3RhdGUuY3VycmVudExpbmVDYXAgPSBsaW5lQ2FwO1xuICAgICAgc3RhdGUuY3VycmVudExpbmVEYXNoID0gbGluZURhc2g7XG4gICAgICBzdGF0ZS5jdXJyZW50TGluZURhc2hPZmZzZXQgPSBsaW5lRGFzaE9mZnNldDtcbiAgICAgIHN0YXRlLmN1cnJlbnRMaW5lSm9pbiA9IGxpbmVKb2luO1xuICAgICAgc3RhdGUuY3VycmVudExpbmVXaWR0aCA9IGxpbmVXaWR0aDtcbiAgICAgIHN0YXRlLmN1cnJlbnRNaXRlckxpbWl0ID0gbWl0ZXJMaW1pdDtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICovXG5cblxuICBDYW52YXNCdWlsZGVyLnByb3RvdHlwZS5lbmRHZW9tZXRyeSA9IGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5SW5zdHJ1Y3Rpb24xX1syXSA9IHRoaXMuaW5zdHJ1Y3Rpb25zLmxlbmd0aDtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnlJbnN0cnVjdGlvbjFfID0gbnVsbDtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnlJbnN0cnVjdGlvbjJfWzJdID0gdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMubGVuZ3RoO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeUluc3RydWN0aW9uMl8gPSBudWxsO1xuICAgIHZhciBlbmRHZW9tZXRyeUluc3RydWN0aW9uID0gW0NhbnZhc0luc3RydWN0aW9uLkVORF9HRU9NRVRSWSwgZmVhdHVyZV07XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChlbmRHZW9tZXRyeUluc3RydWN0aW9uKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGVuZEdlb21ldHJ5SW5zdHJ1Y3Rpb24pO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBidWZmZXJlZCByZW5kZXJpbmcgZXh0ZW50LiAgUmVuZGVyaW5nIHdpbGwgYmUgY2xpcHBlZCB0byB0aGUgZXh0ZW50XG4gICAqIHByb3ZpZGVkIHRvIHRoZSBjb25zdHJ1Y3Rvci4gIFRvIGFjY291bnQgZm9yIHN5bWJvbGl6ZXJzIHRoYXQgbWF5IGludGVyc2VjdFxuICAgKiB0aGlzIGV4dGVudCwgd2UgY2FsY3VsYXRlIGEgYnVmZmVyZWQgZXh0ZW50IChlLmcuIGJhc2VkIG9uIHN0cm9rZSB3aWR0aCkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFRoZSBidWZmZXJlZCByZW5kZXJpbmcgZXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzQnVpbGRlci5wcm90b3R5cGUuZ2V0QnVmZmVyZWRNYXhFeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmJ1ZmZlcmVkTWF4RXh0ZW50Xykge1xuICAgICAgdGhpcy5idWZmZXJlZE1heEV4dGVudF8gPSBjbG9uZSh0aGlzLm1heEV4dGVudCk7XG5cbiAgICAgIGlmICh0aGlzLm1heExpbmVXaWR0aCA+IDApIHtcbiAgICAgICAgdmFyIHdpZHRoID0gdGhpcy5yZXNvbHV0aW9uICogKHRoaXMubWF4TGluZVdpZHRoICsgMSkgLyAyO1xuICAgICAgICBidWZmZXIodGhpcy5idWZmZXJlZE1heEV4dGVudF8sIHdpZHRoLCB0aGlzLmJ1ZmZlcmVkTWF4RXh0ZW50Xyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYnVmZmVyZWRNYXhFeHRlbnRfO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNCdWlsZGVyO1xufShWZWN0b3JDb250ZXh0KTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzQnVpbGRlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvSW1hZ2VCdWlsZGVyXG4gKi9cblxuXG5pbXBvcnQgQ2FudmFzQnVpbGRlciBmcm9tICcuL0J1aWxkZXIuanMnO1xuaW1wb3J0IENhbnZhc0luc3RydWN0aW9uIGZyb20gJy4vSW5zdHJ1Y3Rpb24uanMnO1xuXG52YXIgQ2FudmFzSW1hZ2VCdWlsZGVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc0ltYWdlQnVpbGRlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IG1heEV4dGVudCBNYXhpbXVtIGV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzSW1hZ2VCdWlsZGVyKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdG9sZXJhbmNlLCBtYXhFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlUGl4ZWxSYXRpb18gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvclhfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmNob3JZXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuaGVpZ2h0XyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMub3BhY2l0eV8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLm9yaWdpblhfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmlnaW5ZXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJvdGF0ZVdpdGhWaWV3XyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMucm90YXRpb25fID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZXx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zY2FsZV8gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLndpZHRoXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBEYXRhIHNoYXJlZCB3aXRoIGEgdGV4dCBidWlsZGVyIGZvciBjb21iaW5lZCBkZWNsdXR0ZXJpbmcuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XyA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gcG9pbnRHZW9tZXRyeSBQb2ludCBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1hZ2VCdWlsZGVyLnByb3RvdHlwZS5kcmF3UG9pbnQgPSBmdW5jdGlvbiAocG9pbnRHZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIGlmICghdGhpcy5pbWFnZV8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmJlZ2luR2VvbWV0cnkocG9pbnRHZW9tZXRyeSwgZmVhdHVyZSk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHBvaW50R2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IHBvaW50R2VvbWV0cnkuZ2V0U3RyaWRlKCk7XG4gICAgdmFyIG15QmVnaW4gPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB2YXIgbXlFbmQgPSB0aGlzLmFwcGVuZEZsYXRQb2ludENvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgc3RyaWRlKTtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0lNQUdFLCBteUJlZ2luLCBteUVuZCwgdGhpcy5pbWFnZV8sIC8vIFJlbWFpbmluZyBhcmd1bWVudHMgdG8gRFJBV19JTUFHRSBhcmUgaW4gYWxwaGFiZXRpY2FsIG9yZGVyXG4gICAgdGhpcy5hbmNob3JYXyAqIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXywgdGhpcy5hbmNob3JZXyAqIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXywgTWF0aC5jZWlsKHRoaXMuaGVpZ2h0XyAqIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXyksIHRoaXMub3BhY2l0eV8sIHRoaXMub3JpZ2luWF8sIHRoaXMub3JpZ2luWV8sIHRoaXMucm90YXRlV2l0aFZpZXdfLCB0aGlzLnJvdGF0aW9uXywgW3RoaXMuc2NhbGVfWzBdICogdGhpcy5waXhlbFJhdGlvIC8gdGhpcy5pbWFnZVBpeGVsUmF0aW9fLCB0aGlzLnNjYWxlX1sxXSAqIHRoaXMucGl4ZWxSYXRpbyAvIHRoaXMuaW1hZ2VQaXhlbFJhdGlvX10sIE1hdGguY2VpbCh0aGlzLndpZHRoXyAqIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXyksIHRoaXMuZGVjbHV0dGVySW1hZ2VXaXRoVGV4dF9dKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0lNQUdFLCBteUJlZ2luLCBteUVuZCwgdGhpcy5oaXREZXRlY3Rpb25JbWFnZV8sIC8vIFJlbWFpbmluZyBhcmd1bWVudHMgdG8gRFJBV19JTUFHRSBhcmUgaW4gYWxwaGFiZXRpY2FsIG9yZGVyXG4gICAgdGhpcy5hbmNob3JYXywgdGhpcy5hbmNob3JZXywgdGhpcy5oZWlnaHRfLCB0aGlzLm9wYWNpdHlfLCB0aGlzLm9yaWdpblhfLCB0aGlzLm9yaWdpbllfLCB0aGlzLnJvdGF0ZVdpdGhWaWV3XywgdGhpcy5yb3RhdGlvbl8sIHRoaXMuc2NhbGVfLCB0aGlzLndpZHRoXywgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0X10pO1xuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gbXVsdGlQb2ludEdlb21ldHJ5IE11bHRpUG9pbnQgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc0ltYWdlQnVpbGRlci5wcm90b3R5cGUuZHJhd011bHRpUG9pbnQgPSBmdW5jdGlvbiAobXVsdGlQb2ludEdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgaWYgKCF0aGlzLmltYWdlXykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShtdWx0aVBvaW50R2VvbWV0cnksIGZlYXR1cmUpO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBtdWx0aVBvaW50R2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IG11bHRpUG9pbnRHZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICB2YXIgbXlCZWdpbiA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHZhciBteUVuZCA9IHRoaXMuYXBwZW5kRmxhdFBvaW50Q29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBzdHJpZGUpO1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIG15QmVnaW4sIG15RW5kLCB0aGlzLmltYWdlXywgLy8gUmVtYWluaW5nIGFyZ3VtZW50cyB0byBEUkFXX0lNQUdFIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXJcbiAgICB0aGlzLmFuY2hvclhfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fLCB0aGlzLmFuY2hvcllfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fLCBNYXRoLmNlaWwodGhpcy5oZWlnaHRfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fKSwgdGhpcy5vcGFjaXR5XywgdGhpcy5vcmlnaW5YXywgdGhpcy5vcmlnaW5ZXywgdGhpcy5yb3RhdGVXaXRoVmlld18sIHRoaXMucm90YXRpb25fLCBbdGhpcy5zY2FsZV9bMF0gKiB0aGlzLnBpeGVsUmF0aW8gLyB0aGlzLmltYWdlUGl4ZWxSYXRpb18sIHRoaXMuc2NhbGVfWzFdICogdGhpcy5waXhlbFJhdGlvIC8gdGhpcy5pbWFnZVBpeGVsUmF0aW9fXSwgTWF0aC5jZWlsKHRoaXMud2lkdGhfICogdGhpcy5pbWFnZVBpeGVsUmF0aW9fKSwgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0X10pO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfSU1BR0UsIG15QmVnaW4sIG15RW5kLCB0aGlzLmhpdERldGVjdGlvbkltYWdlXywgLy8gUmVtYWluaW5nIGFyZ3VtZW50cyB0byBEUkFXX0lNQUdFIGFyZSBpbiBhbHBoYWJldGljYWwgb3JkZXJcbiAgICB0aGlzLmFuY2hvclhfLCB0aGlzLmFuY2hvcllfLCB0aGlzLmhlaWdodF8sIHRoaXMub3BhY2l0eV8sIHRoaXMub3JpZ2luWF8sIHRoaXMub3JpZ2luWV8sIHRoaXMucm90YXRlV2l0aFZpZXdfLCB0aGlzLnJvdGF0aW9uXywgdGhpcy5zY2FsZV8sIHRoaXMud2lkdGhfLCB0aGlzLmRlY2x1dHRlckltYWdlV2l0aFRleHRfXSk7XG4gICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TZXJpYWxpemFibGVJbnN0cnVjdGlvbnN9IHRoZSBzZXJpYWxpemFibGUgaW5zdHJ1Y3Rpb25zLlxuICAgKi9cblxuXG4gIENhbnZhc0ltYWdlQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmV2ZXJzZUhpdERldGVjdGlvbkluc3RydWN0aW9ucygpOyAvLyBGSVhNRSB0aGlzIGRvZXNuJ3QgcmVhbGx5IHByb3RlY3QgdXMgYWdhaW5zdCBmdXJ0aGVyIGNhbGxzIHRvIGRyYXcqR2VvbWV0cnlcblxuICAgIHRoaXMuYW5jaG9yWF8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5hbmNob3JZXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlXyA9IG51bGw7XG4gICAgdGhpcy5pbWFnZV8gPSBudWxsO1xuICAgIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmhlaWdodF8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5zY2FsZV8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5vcGFjaXR5XyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLm9yaWdpblhfID0gdW5kZWZpbmVkO1xuICAgIHRoaXMub3JpZ2luWV8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yb3RhdGVXaXRoVmlld18gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5yb3RhdGlvbl8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy53aWR0aF8gPSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZmluaXNoLmNhbGwodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL0ltYWdlLmpzXCIpLmRlZmF1bHR9IGltYWdlU3R5bGUgSW1hZ2Ugc3R5bGUuXG4gICAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0X3NoYXJlZERhdGEgU2hhcmVkIGRhdGEuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1hZ2VCdWlsZGVyLnByb3RvdHlwZS5zZXRJbWFnZVN0eWxlID0gZnVuY3Rpb24gKGltYWdlU3R5bGUsIG9wdF9zaGFyZWREYXRhKSB7XG4gICAgdmFyIGFuY2hvciA9IGltYWdlU3R5bGUuZ2V0QW5jaG9yKCk7XG4gICAgdmFyIHNpemUgPSBpbWFnZVN0eWxlLmdldFNpemUoKTtcbiAgICB2YXIgaGl0RGV0ZWN0aW9uSW1hZ2UgPSBpbWFnZVN0eWxlLmdldEhpdERldGVjdGlvbkltYWdlKCk7XG4gICAgdmFyIGltYWdlID0gaW1hZ2VTdHlsZS5nZXRJbWFnZSh0aGlzLnBpeGVsUmF0aW8pO1xuICAgIHZhciBvcmlnaW4gPSBpbWFnZVN0eWxlLmdldE9yaWdpbigpO1xuICAgIHRoaXMuaW1hZ2VQaXhlbFJhdGlvXyA9IGltYWdlU3R5bGUuZ2V0UGl4ZWxSYXRpbyh0aGlzLnBpeGVsUmF0aW8pO1xuICAgIHRoaXMuYW5jaG9yWF8gPSBhbmNob3JbMF07XG4gICAgdGhpcy5hbmNob3JZXyA9IGFuY2hvclsxXTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlXyA9IGhpdERldGVjdGlvbkltYWdlO1xuICAgIHRoaXMuaW1hZ2VfID0gaW1hZ2U7XG4gICAgdGhpcy5oZWlnaHRfID0gc2l6ZVsxXTtcbiAgICB0aGlzLm9wYWNpdHlfID0gaW1hZ2VTdHlsZS5nZXRPcGFjaXR5KCk7XG4gICAgdGhpcy5vcmlnaW5YXyA9IG9yaWdpblswXTtcbiAgICB0aGlzLm9yaWdpbllfID0gb3JpZ2luWzFdO1xuICAgIHRoaXMucm90YXRlV2l0aFZpZXdfID0gaW1hZ2VTdHlsZS5nZXRSb3RhdGVXaXRoVmlldygpO1xuICAgIHRoaXMucm90YXRpb25fID0gaW1hZ2VTdHlsZS5nZXRSb3RhdGlvbigpO1xuICAgIHRoaXMuc2NhbGVfID0gaW1hZ2VTdHlsZS5nZXRTY2FsZUFycmF5KCk7XG4gICAgdGhpcy53aWR0aF8gPSBzaXplWzBdO1xuICAgIHRoaXMuZGVjbHV0dGVySW1hZ2VXaXRoVGV4dF8gPSBvcHRfc2hhcmVkRGF0YTtcbiAgfTtcblxuICByZXR1cm4gQ2FudmFzSW1hZ2VCdWlsZGVyO1xufShDYW52YXNCdWlsZGVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzSW1hZ2VCdWlsZGVyOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9MaW5lU3RyaW5nQnVpbGRlclxuICovXG5cblxuaW1wb3J0IENhbnZhc0J1aWxkZXIgZnJvbSAnLi9CdWlsZGVyLmpzJztcbmltcG9ydCBDYW52YXNJbnN0cnVjdGlvbiwgeyBiZWdpblBhdGhJbnN0cnVjdGlvbiwgc3Ryb2tlSW5zdHJ1Y3Rpb24gfSBmcm9tICcuL0luc3RydWN0aW9uLmpzJztcblxudmFyIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heGltdW0gZXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNMaW5lU3RyaW5nQnVpbGRlcih0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykge1xuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCB0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykgfHwgdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7bnVtYmVyfSBlbmQuXG4gICAqL1xuXG5cbiAgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIucHJvdG90eXBlLmRyYXdGbGF0Q29vcmRpbmF0ZXNfID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICAgIHZhciBteUJlZ2luID0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGg7XG4gICAgdmFyIG15RW5kID0gdGhpcy5hcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgZmFsc2UsIGZhbHNlKTtcbiAgICB2YXIgbW92ZVRvTGluZVRvSW5zdHJ1Y3Rpb24gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uTU9WRV9UT19MSU5FX1RPLCBteUJlZ2luLCBteUVuZF07XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChtb3ZlVG9MaW5lVG9JbnN0cnVjdGlvbik7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChtb3ZlVG9MaW5lVG9JbnN0cnVjdGlvbik7XG4gICAgcmV0dXJuIGVuZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9MaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBsaW5lU3RyaW5nR2VvbWV0cnkgTGluZSBzdHJpbmcgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyLnByb3RvdHlwZS5kcmF3TGluZVN0cmluZyA9IGZ1bmN0aW9uIChsaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBzdHJva2VTdHlsZSA9IHN0YXRlLnN0cm9rZVN0eWxlO1xuICAgIHZhciBsaW5lV2lkdGggPSBzdGF0ZS5saW5lV2lkdGg7XG5cbiAgICBpZiAoc3Ryb2tlU3R5bGUgPT09IHVuZGVmaW5lZCB8fCBsaW5lV2lkdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlU3Ryb2tlU3R5bGUoc3RhdGUsIHRoaXMuYXBwbHlTdHJva2UpO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShsaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9TVFJPS0VfU1RZTEUsIHN0YXRlLnN0cm9rZVN0eWxlLCBzdGF0ZS5saW5lV2lkdGgsIHN0YXRlLmxpbmVDYXAsIHN0YXRlLmxpbmVKb2luLCBzdGF0ZS5taXRlckxpbWl0LCBzdGF0ZS5saW5lRGFzaCwgc3RhdGUubGluZURhc2hPZmZzZXRdLCBiZWdpblBhdGhJbnN0cnVjdGlvbik7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IGxpbmVTdHJpbmdHZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gbGluZVN0cmluZ0dlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHRoaXMuZHJhd0ZsYXRDb29yZGluYXRlc18oZmxhdENvb3JkaW5hdGVzLCAwLCBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCBzdHJpZGUpO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeSBNdWx0aUxpbmVTdHJpbmcgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyLnByb3RvdHlwZS5kcmF3TXVsdGlMaW5lU3RyaW5nID0gZnVuY3Rpb24gKG11bHRpTGluZVN0cmluZ0dlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICB2YXIgc3Ryb2tlU3R5bGUgPSBzdGF0ZS5zdHJva2VTdHlsZTtcbiAgICB2YXIgbGluZVdpZHRoID0gc3RhdGUubGluZVdpZHRoO1xuXG4gICAgaWYgKHN0cm9rZVN0eWxlID09PSB1bmRlZmluZWQgfHwgbGluZVdpZHRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZVN0cm9rZVN0eWxlKHN0YXRlLCB0aGlzLmFwcGx5U3Ryb2tlKTtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnkobXVsdGlMaW5lU3RyaW5nR2VvbWV0cnksIGZlYXR1cmUpO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLlNFVF9TVFJPS0VfU1RZTEUsIHN0YXRlLnN0cm9rZVN0eWxlLCBzdGF0ZS5saW5lV2lkdGgsIHN0YXRlLmxpbmVDYXAsIHN0YXRlLmxpbmVKb2luLCBzdGF0ZS5taXRlckxpbWl0LCBzdGF0ZS5saW5lRGFzaCwgc3RhdGUubGluZURhc2hPZmZzZXRdLCBiZWdpblBhdGhJbnN0cnVjdGlvbik7XG4gICAgdmFyIGVuZHMgPSBtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeS5nZXRFbmRzKCk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IG11bHRpTGluZVN0cmluZ0dlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgIHZhciBzdHJpZGUgPSBtdWx0aUxpbmVTdHJpbmdHZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICB2YXIgb2Zmc2V0ID0gMDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgb2Zmc2V0ID0gdGhpcy5kcmF3RmxhdENvb3JkaW5hdGVzXyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCxcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgZW5kc1tpXSwgc3RyaWRlKTtcbiAgICB9XG5cbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9uc30gdGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnMuXG4gICAqL1xuXG5cbiAgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuXG4gICAgaWYgKHN0YXRlLmxhc3RTdHJva2UgIT0gdW5kZWZpbmVkICYmIHN0YXRlLmxhc3RTdHJva2UgIT0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgIH1cblxuICAgIHRoaXMucmV2ZXJzZUhpdERldGVjdGlvbkluc3RydWN0aW9ucygpO1xuICAgIHRoaXMuc3RhdGUgPSBudWxsO1xuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmZpbmlzaC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0cm9rZVN0YXRlfSBzdGF0ZSBTdGF0ZS5cbiAgICovXG5cblxuICBDYW52YXNMaW5lU3RyaW5nQnVpbGRlci5wcm90b3R5cGUuYXBwbHlTdHJva2UgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUubGFzdFN0cm9rZSAhPSB1bmRlZmluZWQgJiYgc3RhdGUubGFzdFN0cm9rZSAhPSB0aGlzLmNvb3JkaW5hdGVzLmxlbmd0aCkge1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgICBzdGF0ZS5sYXN0U3Ryb2tlID0gdGhpcy5jb29yZGluYXRlcy5sZW5ndGg7XG4gICAgfVxuXG4gICAgc3RhdGUubGFzdFN0cm9rZSA9IDA7XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLmFwcGx5U3Ryb2tlLmNhbGwodGhpcywgc3RhdGUpO1xuXG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChiZWdpblBhdGhJbnN0cnVjdGlvbik7XG4gIH07XG5cbiAgcmV0dXJuIENhbnZhc0xpbmVTdHJpbmdCdWlsZGVyO1xufShDYW52YXNCdWlsZGVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzTGluZVN0cmluZ0J1aWxkZXI7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL1BvbHlnb25CdWlsZGVyXG4gKi9cblxuXG5pbXBvcnQgQ2FudmFzQnVpbGRlciBmcm9tICcuL0J1aWxkZXIuanMnO1xuaW1wb3J0IENhbnZhc0luc3RydWN0aW9uLCB7IGJlZ2luUGF0aEluc3RydWN0aW9uLCBjbG9zZVBhdGhJbnN0cnVjdGlvbiwgZmlsbEluc3RydWN0aW9uLCBzdHJva2VJbnN0cnVjdGlvbiB9IGZyb20gJy4vSW5zdHJ1Y3Rpb24uanMnO1xuaW1wb3J0IHsgZGVmYXVsdEZpbGxTdHlsZSB9IGZyb20gJy4uL2NhbnZhcy5qcyc7XG5pbXBvcnQgeyBzbmFwIH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L3NpbXBsaWZ5LmpzJztcblxudmFyIENhbnZhc1BvbHlnb25CdWlsZGVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc1BvbHlnb25CdWlsZGVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heGltdW0gZXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNQb2x5Z29uQnVpbGRlcih0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykge1xuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCB0b2xlcmFuY2UsIG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykgfHwgdGhpcztcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7bnVtYmVyfSBFbmQuXG4gICAqL1xuXG5cbiAgQ2FudmFzUG9seWdvbkJ1aWxkZXIucHJvdG90eXBlLmRyYXdGbGF0Q29vcmRpbmF0ZXNzXyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kcywgc3RyaWRlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICB2YXIgZmlsbCA9IHN0YXRlLmZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBzdHJva2UgPSBzdGF0ZS5zdHJva2VTdHlsZSAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBudW1FbmRzID0gZW5kcy5sZW5ndGg7XG4gICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChiZWdpblBhdGhJbnN0cnVjdGlvbik7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChiZWdpblBhdGhJbnN0cnVjdGlvbik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG51bUVuZHM7ICsraSkge1xuICAgICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgICB2YXIgbXlCZWdpbiA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgdmFyIG15RW5kID0gdGhpcy5hcHBlbmRGbGF0TGluZUNvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgdHJ1ZSwgIXN0cm9rZSk7XG4gICAgICB2YXIgbW92ZVRvTGluZVRvSW5zdHJ1Y3Rpb24gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uTU9WRV9UT19MSU5FX1RPLCBteUJlZ2luLCBteUVuZF07XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKG1vdmVUb0xpbmVUb0luc3RydWN0aW9uKTtcbiAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLnB1c2gobW92ZVRvTGluZVRvSW5zdHJ1Y3Rpb24pO1xuXG4gICAgICBpZiAoc3Ryb2tlKSB7XG4gICAgICAgIC8vIFBlcmZvcm1hbmNlIG9wdGltaXphdGlvbjogb25seSBjYWxsIGNsb3NlUGF0aCgpIHdoZW4gd2UgaGF2ZSBhIHN0cm9rZS5cbiAgICAgICAgLy8gT3RoZXJ3aXNlIHRoZSByaW5nIGlzIGNsb3NlZCBhbHJlYWR5IChzZWUgYXBwZW5kRmxhdExpbmVDb29yZGluYXRlcyBhYm92ZSkuXG4gICAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goY2xvc2VQYXRoSW5zdHJ1Y3Rpb24pO1xuICAgICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGNsb3NlUGF0aEluc3RydWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIGlmIChmaWxsKSB7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGZpbGxJbnN0cnVjdGlvbik7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGZpbGxJbnN0cnVjdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKHN0cm9rZSkge1xuICAgICAgdGhpcy5pbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0NpcmNsZS5qc1wiKS5kZWZhdWx0fSBjaXJjbGVHZW9tZXRyeSBDaXJjbGUgZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzUG9seWdvbkJ1aWxkZXIucHJvdG90eXBlLmRyYXdDaXJjbGUgPSBmdW5jdGlvbiAoY2lyY2xlR2VvbWV0cnksIGZlYXR1cmUpIHtcbiAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgIHZhciBmaWxsU3R5bGUgPSBzdGF0ZS5maWxsU3R5bGU7XG4gICAgdmFyIHN0cm9rZVN0eWxlID0gc3RhdGUuc3Ryb2tlU3R5bGU7XG5cbiAgICBpZiAoZmlsbFN0eWxlID09PSB1bmRlZmluZWQgJiYgc3Ryb2tlU3R5bGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2V0RmlsbFN0cm9rZVN0eWxlc18oKTtcbiAgICB0aGlzLmJlZ2luR2VvbWV0cnkoY2lyY2xlR2VvbWV0cnksIGZlYXR1cmUpO1xuXG4gICAgaWYgKHN0YXRlLmZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfRklMTF9TVFlMRSwgZGVmYXVsdEZpbGxTdHlsZV0pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5zdHJva2VTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfU1RST0tFX1NUWUxFLCBzdGF0ZS5zdHJva2VTdHlsZSwgc3RhdGUubGluZVdpZHRoLCBzdGF0ZS5saW5lQ2FwLCBzdGF0ZS5saW5lSm9pbiwgc3RhdGUubWl0ZXJMaW1pdCwgc3RhdGUubGluZURhc2gsIHN0YXRlLmxpbmVEYXNoT2Zmc2V0XSk7XG4gICAgfVxuXG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IGNpcmNsZUdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgIHZhciBzdHJpZGUgPSBjaXJjbGVHZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICB2YXIgbXlCZWdpbiA9IHRoaXMuY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHRoaXMuYXBwZW5kRmxhdExpbmVDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIDAsIGZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHN0cmlkZSwgZmFsc2UsIGZhbHNlKTtcbiAgICB2YXIgY2lyY2xlSW5zdHJ1Y3Rpb24gPSBbQ2FudmFzSW5zdHJ1Y3Rpb24uQ0lSQ0xFLCBteUJlZ2luXTtcbiAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGJlZ2luUGF0aEluc3RydWN0aW9uLCBjaXJjbGVJbnN0cnVjdGlvbik7XG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChiZWdpblBhdGhJbnN0cnVjdGlvbiwgY2lyY2xlSW5zdHJ1Y3Rpb24pO1xuXG4gICAgaWYgKHN0YXRlLmZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKGZpbGxJbnN0cnVjdGlvbik7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKGZpbGxJbnN0cnVjdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLnN0cm9rZVN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goc3Ryb2tlSW5zdHJ1Y3Rpb24pO1xuICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgfVxuXG4gICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBwb2x5Z29uR2VvbWV0cnkgUG9seWdvbiBnZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgQ2FudmFzUG9seWdvbkJ1aWxkZXIucHJvdG90eXBlLmRyYXdQb2x5Z29uID0gZnVuY3Rpb24gKHBvbHlnb25HZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgdmFyIGZpbGxTdHlsZSA9IHN0YXRlLmZpbGxTdHlsZTtcbiAgICB2YXIgc3Ryb2tlU3R5bGUgPSBzdGF0ZS5zdHJva2VTdHlsZTtcblxuICAgIGlmIChmaWxsU3R5bGUgPT09IHVuZGVmaW5lZCAmJiBzdHJva2VTdHlsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRGaWxsU3Ryb2tlU3R5bGVzXygpO1xuICAgIHRoaXMuYmVnaW5HZW9tZXRyeShwb2x5Z29uR2VvbWV0cnksIGZlYXR1cmUpO1xuXG4gICAgaWYgKHN0YXRlLmZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfRklMTF9TVFlMRSwgZGVmYXVsdEZpbGxTdHlsZV0pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5zdHJva2VTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5TRVRfU1RST0tFX1NUWUxFLCBzdGF0ZS5zdHJva2VTdHlsZSwgc3RhdGUubGluZVdpZHRoLCBzdGF0ZS5saW5lQ2FwLCBzdGF0ZS5saW5lSm9pbiwgc3RhdGUubWl0ZXJMaW1pdCwgc3RhdGUubGluZURhc2gsIHN0YXRlLmxpbmVEYXNoT2Zmc2V0XSk7XG4gICAgfVxuXG4gICAgdmFyIGVuZHMgPSBwb2x5Z29uR2VvbWV0cnkuZ2V0RW5kcygpO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBwb2x5Z29uR2VvbWV0cnkuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKTtcbiAgICB2YXIgc3RyaWRlID0gcG9seWdvbkdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHRoaXMuZHJhd0ZsYXRDb29yZGluYXRlc3NfKGZsYXRDb29yZGluYXRlcywgMCxcbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgZW5kcywgc3RyaWRlKTtcbiAgICB0aGlzLmVuZEdlb21ldHJ5KGZlYXR1cmUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSBtdWx0aVBvbHlnb25HZW9tZXRyeSBNdWx0aVBvbHlnb24gZ2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc1BvbHlnb25CdWlsZGVyLnByb3RvdHlwZS5kcmF3TXVsdGlQb2x5Z29uID0gZnVuY3Rpb24gKG11bHRpUG9seWdvbkdlb21ldHJ5LCBmZWF0dXJlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICB2YXIgZmlsbFN0eWxlID0gc3RhdGUuZmlsbFN0eWxlO1xuICAgIHZhciBzdHJva2VTdHlsZSA9IHN0YXRlLnN0cm9rZVN0eWxlO1xuXG4gICAgaWYgKGZpbGxTdHlsZSA9PT0gdW5kZWZpbmVkICYmIHN0cm9rZVN0eWxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEZpbGxTdHJva2VTdHlsZXNfKCk7XG4gICAgdGhpcy5iZWdpbkdlb21ldHJ5KG11bHRpUG9seWdvbkdlb21ldHJ5LCBmZWF0dXJlKTtcblxuICAgIGlmIChzdGF0ZS5maWxsU3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX0ZJTExfU1RZTEUsIGRlZmF1bHRGaWxsU3R5bGVdKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuc3Ryb2tlU3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaChbQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX1NUUk9LRV9TVFlMRSwgc3RhdGUuc3Ryb2tlU3R5bGUsIHN0YXRlLmxpbmVXaWR0aCwgc3RhdGUubGluZUNhcCwgc3RhdGUubGluZUpvaW4sIHN0YXRlLm1pdGVyTGltaXQsIHN0YXRlLmxpbmVEYXNoLCBzdGF0ZS5saW5lRGFzaE9mZnNldF0pO1xuICAgIH1cblxuICAgIHZhciBlbmRzcyA9IG11bHRpUG9seWdvbkdlb21ldHJ5LmdldEVuZHNzKCk7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IG11bHRpUG9seWdvbkdlb21ldHJ5LmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IG11bHRpUG9seWdvbkdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgb2Zmc2V0ID0gdGhpcy5kcmF3RmxhdENvb3JkaW5hdGVzc18oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzW2ldLCBzdHJpZGUpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kR2VvbWV0cnkoZmVhdHVyZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zfSB0aGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9ucy5cbiAgICovXG5cblxuICBDYW52YXNQb2x5Z29uQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucmV2ZXJzZUhpdERldGVjdGlvbkluc3RydWN0aW9ucygpO1xuICAgIHRoaXMuc3RhdGUgPSBudWxsOyAvLyBXZSB3YW50IHRvIHByZXNlcnZlIHRvcG9sb2d5IHdoZW4gZHJhd2luZyBwb2x5Z29ucy4gIFBvbHlnb25zIGFyZVxuICAgIC8vIHNpbXBsaWZpZWQgdXNpbmcgcXVhbnRpemF0aW9uIGFuZCBwb2ludCBlbGltaW5hdGlvbi4gSG93ZXZlciwgd2UgbWlnaHRcbiAgICAvLyBoYXZlIHJlY2VpdmVkIGEgbWl4IG9mIHF1YW50aXplZCBhbmQgbm9uLXF1YW50aXplZCBnZW9tZXRyaWVzLCBzbyBlbnN1cmVcbiAgICAvLyB0aGF0IGFsbCBhcmUgcXVhbnRpemVkIGJ5IHF1YW50aXppbmcgYWxsIGNvb3JkaW5hdGVzIGluIHRoZSBiYXRjaC5cblxuICAgIHZhciB0b2xlcmFuY2UgPSB0aGlzLnRvbGVyYW5jZTtcblxuICAgIGlmICh0b2xlcmFuY2UgIT09IDApIHtcbiAgICAgIHZhciBjb29yZGluYXRlcyA9IHRoaXMuY29vcmRpbmF0ZXM7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgY29vcmRpbmF0ZXNbaV0gPSBzbmFwKGNvb3JkaW5hdGVzW2ldLCB0b2xlcmFuY2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmZpbmlzaC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNQb2x5Z29uQnVpbGRlci5wcm90b3R5cGUuc2V0RmlsbFN0cm9rZVN0eWxlc18gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICB2YXIgZmlsbFN0eWxlID0gc3RhdGUuZmlsbFN0eWxlO1xuXG4gICAgaWYgKGZpbGxTdHlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnVwZGF0ZUZpbGxTdHlsZShzdGF0ZSwgdGhpcy5jcmVhdGVGaWxsKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuc3Ryb2tlU3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy51cGRhdGVTdHJva2VTdHlsZShzdGF0ZSwgdGhpcy5hcHBseVN0cm9rZSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBDYW52YXNQb2x5Z29uQnVpbGRlcjtcbn0oQ2FudmFzQnVpbGRlcik7XG5cbmV4cG9ydCBkZWZhdWx0IENhbnZhc1BvbHlnb25CdWlsZGVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9UZXh0UGxhY2VtZW50XG4gKi9cblxuLyoqXG4gKiBUZXh0IHBsYWNlbWVudC4gT25lIG9mIGAncG9pbnQnYCwgYCdsaW5lJ2AuIERlZmF1bHQgaXMgYCdwb2ludCdgLiBOb3RlIHRoYXRcbiAqIGAnbGluZSdgIHJlcXVpcmVzIHRoZSB1bmRlcmx5aW5nIGdlb21ldHJ5IHRvIGJlIGEge0BsaW5rIG1vZHVsZTpvbC9nZW9tL0xpbmVTdHJpbmd+TGluZVN0cmluZ30sXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2dlb20vUG9seWdvbn5Qb2x5Z29ufSwge0BsaW5rIG1vZHVsZTpvbC9nZW9tL011bHRpTGluZVN0cmluZ35NdWx0aUxpbmVTdHJpbmd9IG9yXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2dlb20vTXVsdGlQb2x5Z29ufk11bHRpUG9seWdvbn0uXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFBPSU5UOiAncG9pbnQnLFxuICBMSU5FOiAnbGluZSdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vZmxhdC9zdHJhaWdodGNodW5rXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4QW5nbGUgTWF4aW11bSBhY2NlcHRhYmxlIGFuZ2xlIGRlbHRhIGJldHdlZW4gc2VnbWVudHMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gU3RhcnQgYW5kIGVuZCBvZiB0aGUgZmlyc3Qgc3VpdGFibGUgY2h1bmsgb2YgdGhlXG4gKiBnaXZlbiBgZmxhdENvb3JkaW5hdGVzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoaW5nQ2h1bmsobWF4QW5nbGUsIGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICB2YXIgY2h1bmtTdGFydCA9IG9mZnNldDtcbiAgdmFyIGNodW5rRW5kID0gb2Zmc2V0O1xuICB2YXIgY2h1bmtNID0gMDtcbiAgdmFyIG0gPSAwO1xuICB2YXIgc3RhcnQgPSBvZmZzZXQ7XG4gIHZhciBhY29zLCBpLCBtMTIsIG0yMywgeDEsIHkxLCB4MTIsIHkxMiwgeDIzLCB5MjM7XG5cbiAgZm9yIChpID0gb2Zmc2V0OyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tpXTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuXG4gICAgaWYgKHgxICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHgyMyA9IHgyIC0geDE7XG4gICAgICB5MjMgPSB5MiAtIHkxO1xuICAgICAgbTIzID0gTWF0aC5zcXJ0KHgyMyAqIHgyMyArIHkyMyAqIHkyMyk7XG5cbiAgICAgIGlmICh4MTIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtICs9IG0xMjtcbiAgICAgICAgYWNvcyA9IE1hdGguYWNvcygoeDEyICogeDIzICsgeTEyICogeTIzKSAvIChtMTIgKiBtMjMpKTtcblxuICAgICAgICBpZiAoYWNvcyA+IG1heEFuZ2xlKSB7XG4gICAgICAgICAgaWYgKG0gPiBjaHVua00pIHtcbiAgICAgICAgICAgIGNodW5rTSA9IG07XG4gICAgICAgICAgICBjaHVua1N0YXJ0ID0gc3RhcnQ7XG4gICAgICAgICAgICBjaHVua0VuZCA9IGk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbSA9IDA7XG4gICAgICAgICAgc3RhcnQgPSBpIC0gc3RyaWRlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIG0xMiA9IG0yMztcbiAgICAgIHgxMiA9IHgyMztcbiAgICAgIHkxMiA9IHkyMztcbiAgICB9XG5cbiAgICB4MSA9IHgyO1xuICAgIHkxID0geTI7XG4gIH1cblxuICBtICs9IG0yMztcbiAgcmV0dXJuIG0gPiBjaHVua00gPyBbc3RhcnQsIGldIDogW2NodW5rU3RhcnQsIGNodW5rRW5kXTtcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvVGV4dEJ1aWxkZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNCdWlsZGVyIGZyb20gJy4vQnVpbGRlci5qcyc7XG5pbXBvcnQgQ2FudmFzSW5zdHJ1Y3Rpb24gZnJvbSAnLi9JbnN0cnVjdGlvbi5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4uLy4uL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBUZXh0UGxhY2VtZW50IGZyb20gJy4uLy4uL3N0eWxlL1RleHRQbGFjZW1lbnQuanMnO1xuaW1wb3J0IHsgYXNDb2xvckxpa2UgfSBmcm9tICcuLi8uLi9jb2xvcmxpa2UuanMnO1xuaW1wb3J0IHsgZGVmYXVsdEZpbGxTdHlsZSwgZGVmYXVsdEZvbnQsIGRlZmF1bHRMaW5lQ2FwLCBkZWZhdWx0TGluZURhc2gsIGRlZmF1bHRMaW5lRGFzaE9mZnNldCwgZGVmYXVsdExpbmVKb2luLCBkZWZhdWx0TGluZVdpZHRoLCBkZWZhdWx0TWl0ZXJMaW1pdCwgZGVmYXVsdFBhZGRpbmcsIGRlZmF1bHRTdHJva2VTdHlsZSwgZGVmYXVsdFRleHRBbGlnbiwgZGVmYXVsdFRleHRCYXNlbGluZSwgcmVnaXN0ZXJGb250IH0gZnJvbSAnLi4vY2FudmFzLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uLy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0cyB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBtYXRjaGluZ0NodW5rIH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L3N0cmFpZ2h0Y2h1bmsuanMnO1xuLyoqXG4gKiBAY29uc3RcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cblxuZXhwb3J0IHZhciBURVhUX0FMSUdOID0ge1xuICAnbGVmdCc6IDAsXG4gICdlbmQnOiAwLFxuICAnY2VudGVyJzogMC41LFxuICAncmlnaHQnOiAxLFxuICAnc3RhcnQnOiAxLFxuICAndG9wJzogMCxcbiAgJ21pZGRsZSc6IDAuNSxcbiAgJ2hhbmdpbmcnOiAwLjIsXG4gICdhbHBoYWJldGljJzogMC44LFxuICAnaWRlb2dyYXBoaWMnOiAwLjgsXG4gICdib3R0b20nOiAxXG59O1xuXG52YXIgQ2FudmFzVGV4dEJ1aWxkZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoQ2FudmFzVGV4dEJ1aWxkZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdG9sZXJhbmNlIFRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBtYXhFeHRlbnQgTWF4aW11bSBleHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc1RleHRCdWlsZGVyKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdG9sZXJhbmNlLCBtYXhFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8SFRNTENhbnZhc0VsZW1lbnQ+fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5sYWJlbHNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0XyA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRPZmZzZXRYXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dE9mZnNldFlfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRSb3RhdGVXaXRoVmlld18gPSB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFJvdGF0aW9uXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0RmlsbFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0YXRlPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZpbGxTdGF0ZXMgPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFN0cm9rZVN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU3Ryb2tlU3RhdGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3Ryb2tlU3RhdGVzID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlRleHRTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRTdGF0ZV8gPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlRleHRTdGF0ZX0gKi9cbiAgICB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5UZXh0U3RhdGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dFN0YXRlcyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRLZXlfID0gJyc7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmlsbEtleV8gPSAnJztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHJva2VLZXlfID0gJyc7XG4gICAgLyoqXG4gICAgICogRGF0YSBzaGFyZWQgd2l0aCBhbiBpbWFnZSBidWlsZGVyIGZvciBjb21iaW5lZCBkZWNsdXR0ZXJpbmcuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XyA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TZXJpYWxpemFibGVJbnN0cnVjdGlvbnN9IHRoZSBzZXJpYWxpemFibGUgaW5zdHJ1Y3Rpb25zLlxuICAgKi9cblxuXG4gIENhbnZhc1RleHRCdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGluc3RydWN0aW9ucyA9IF9zdXBlci5wcm90b3R5cGUuZmluaXNoLmNhbGwodGhpcyk7XG5cbiAgICBpbnN0cnVjdGlvbnMudGV4dFN0YXRlcyA9IHRoaXMudGV4dFN0YXRlcztcbiAgICBpbnN0cnVjdGlvbnMuZmlsbFN0YXRlcyA9IHRoaXMuZmlsbFN0YXRlcztcbiAgICBpbnN0cnVjdGlvbnMuc3Ryb2tlU3RhdGVzID0gdGhpcy5zdHJva2VTdGF0ZXM7XG4gICAgcmV0dXJuIGluc3RydWN0aW9ucztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIENhbnZhc1RleHRCdWlsZGVyLnByb3RvdHlwZS5kcmF3VGV4dCA9IGZ1bmN0aW9uIChnZW9tZXRyeSwgZmVhdHVyZSkge1xuICAgIHZhciBmaWxsU3RhdGUgPSB0aGlzLnRleHRGaWxsU3RhdGVfO1xuICAgIHZhciBzdHJva2VTdGF0ZSA9IHRoaXMudGV4dFN0cm9rZVN0YXRlXztcbiAgICB2YXIgdGV4dFN0YXRlID0gdGhpcy50ZXh0U3RhdGVfO1xuXG4gICAgaWYgKHRoaXMudGV4dF8gPT09ICcnIHx8ICF0ZXh0U3RhdGUgfHwgIWZpbGxTdGF0ZSAmJiAhc3Ryb2tlU3RhdGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRpbmF0ZXMgPSB0aGlzLmNvb3JkaW5hdGVzO1xuICAgIHZhciBiZWdpbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB2YXIgZ2VvbWV0cnlUeXBlID0gZ2VvbWV0cnkuZ2V0VHlwZSgpO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBudWxsO1xuICAgIHZhciBzdHJpZGUgPSBnZW9tZXRyeS5nZXRTdHJpZGUoKTtcblxuICAgIGlmICh0ZXh0U3RhdGUucGxhY2VtZW50ID09PSBUZXh0UGxhY2VtZW50LkxJTkUgJiYgKGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkcgfHwgZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORyB8fCBnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLlBPTFlHT04gfHwgZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OKSkge1xuICAgICAgaWYgKCFpbnRlcnNlY3RzKHRoaXMuZ2V0QnVmZmVyZWRNYXhFeHRlbnQoKSwgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGVuZHMgPSB2b2lkIDA7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRGbGF0Q29vcmRpbmF0ZXMoKTtcblxuICAgICAgaWYgKGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkcpIHtcbiAgICAgICAgZW5kcyA9IFtmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoXTtcbiAgICAgIH0gZWxzZSBpZiAoZ2VvbWV0cnlUeXBlID09IEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORykge1xuICAgICAgICBlbmRzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRFbmRzKCk7XG4gICAgICB9IGVsc2UgaWYgKGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuUE9MWUdPTikge1xuICAgICAgICBlbmRzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkuZ2V0RW5kcygpLnNsaWNlKDAsIDEpO1xuICAgICAgfSBlbHNlIGlmIChnZW9tZXRyeVR5cGUgPT0gR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT04pIHtcbiAgICAgICAgdmFyIGVuZHNzID1cbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeS5nZXRFbmRzcygpO1xuICAgICAgICBlbmRzID0gW107XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIGVuZHMucHVzaChlbmRzc1tpXVswXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5iZWdpbkdlb21ldHJ5KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgICAgIHZhciB0ZXh0QWxpZ24gPSB0ZXh0U3RhdGUudGV4dEFsaWduO1xuICAgICAgdmFyIGZsYXRPZmZzZXQgPSAwO1xuICAgICAgdmFyIGZsYXRFbmQgPSB2b2lkIDA7XG5cbiAgICAgIGZvciAodmFyIG8gPSAwLCBvbyA9IGVuZHMubGVuZ3RoOyBvIDwgb287ICsrbykge1xuICAgICAgICBpZiAodGV4dEFsaWduID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhciByYW5nZSA9IG1hdGNoaW5nQ2h1bmsodGV4dFN0YXRlLm1heEFuZ2xlLCBmbGF0Q29vcmRpbmF0ZXMsIGZsYXRPZmZzZXQsIGVuZHNbb10sIHN0cmlkZSk7XG4gICAgICAgICAgZmxhdE9mZnNldCA9IHJhbmdlWzBdO1xuICAgICAgICAgIGZsYXRFbmQgPSByYW5nZVsxXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmbGF0RW5kID0gZW5kc1tvXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAodmFyIGkgPSBmbGF0T2Zmc2V0OyBpIDwgZmxhdEVuZDsgaSArPSBzdHJpZGUpIHtcbiAgICAgICAgICBjb29yZGluYXRlcy5wdXNoKGZsYXRDb29yZGluYXRlc1tpXSwgZmxhdENvb3JkaW5hdGVzW2kgKyAxXSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZW5kID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgICBmbGF0T2Zmc2V0ID0gZW5kc1tvXTtcbiAgICAgICAgdGhpcy5kcmF3Q2hhcnNfKGJlZ2luLCBlbmQpO1xuICAgICAgICBiZWdpbiA9IGVuZDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGdlb21ldHJ5V2lkdGhzID0gdGV4dFN0YXRlLm92ZXJmbG93ID8gbnVsbCA6IFtdO1xuXG4gICAgICBzd2l0Y2ggKGdlb21ldHJ5VHlwZSkge1xuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0lOVDpcbiAgICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ6XG4gICAgICAgICAgZmxhdENvb3JkaW5hdGVzID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLkxJTkVfU1RSSU5HOlxuICAgICAgICAgIGZsYXRDb29yZGluYXRlcyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBnZW9tZXRyeS5nZXRGbGF0TWlkcG9pbnQoKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5DSVJDTEU6XG4gICAgICAgICAgZmxhdENvb3JkaW5hdGVzID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZ2VvbWV0cnkuZ2V0Q2VudGVyKCk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkc6XG4gICAgICAgICAgZmxhdENvb3JkaW5hdGVzID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZ2VvbWV0cnkuZ2V0RmxhdE1pZHBvaW50cygpO1xuICAgICAgICAgIHN0cmlkZSA9IDI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9MWUdPTjpcbiAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgICAgZ2VvbWV0cnkuZ2V0RmxhdEludGVyaW9yUG9pbnQoKTtcblxuICAgICAgICAgIGlmICghdGV4dFN0YXRlLm92ZXJmbG93KSB7XG4gICAgICAgICAgICBnZW9tZXRyeVdpZHRocy5wdXNoKGZsYXRDb29yZGluYXRlc1syXSAvIHRoaXMucmVzb2x1dGlvbik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3RyaWRlID0gMztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OOlxuICAgICAgICAgIHZhciBpbnRlcmlvclBvaW50cyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIGdlb21ldHJ5LmdldEZsYXRJbnRlcmlvclBvaW50cygpO1xuICAgICAgICAgIGZsYXRDb29yZGluYXRlcyA9IFtdO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gaW50ZXJpb3JQb2ludHMubGVuZ3RoOyBpIDwgaWk7IGkgKz0gMykge1xuICAgICAgICAgICAgaWYgKCF0ZXh0U3RhdGUub3ZlcmZsb3cpIHtcbiAgICAgICAgICAgICAgZ2VvbWV0cnlXaWR0aHMucHVzaChpbnRlcmlvclBvaW50c1tpICsgMl0gLyB0aGlzLnJlc29sdXRpb24pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbGF0Q29vcmRpbmF0ZXMucHVzaChpbnRlcmlvclBvaW50c1tpXSwgaW50ZXJpb3JQb2ludHNbaSArIDFdKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0cmlkZSA9IDI7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgIH1cblxuICAgICAgdmFyIGVuZCA9IHRoaXMuYXBwZW5kRmxhdFBvaW50Q29vcmRpbmF0ZXMoZmxhdENvb3JkaW5hdGVzLCBzdHJpZGUpO1xuXG4gICAgICBpZiAoZW5kID09PSBiZWdpbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2F2ZVRleHRTdGF0ZXNfKCk7XG5cbiAgICAgIGlmICh0ZXh0U3RhdGUuYmFja2dyb3VuZEZpbGwgfHwgdGV4dFN0YXRlLmJhY2tncm91bmRTdHJva2UpIHtcbiAgICAgICAgdGhpcy5zZXRGaWxsU3Ryb2tlU3R5bGUodGV4dFN0YXRlLmJhY2tncm91bmRGaWxsLCB0ZXh0U3RhdGUuYmFja2dyb3VuZFN0cm9rZSk7XG5cbiAgICAgICAgaWYgKHRleHRTdGF0ZS5iYWNrZ3JvdW5kRmlsbCkge1xuICAgICAgICAgIHRoaXMudXBkYXRlRmlsbFN0eWxlKHRoaXMuc3RhdGUsIHRoaXMuY3JlYXRlRmlsbCk7XG4gICAgICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMucHVzaCh0aGlzLmNyZWF0ZUZpbGwodGhpcy5zdGF0ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRleHRTdGF0ZS5iYWNrZ3JvdW5kU3Ryb2tlKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVTdHJva2VTdHlsZSh0aGlzLnN0YXRlLCB0aGlzLmFwcGx5U3Ryb2tlKTtcbiAgICAgICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKHRoaXMuY3JlYXRlU3Ryb2tlKHRoaXMuc3RhdGUpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmJlZ2luR2VvbWV0cnkoZ2VvbWV0cnksIGZlYXR1cmUpOyAvLyBhZGp1c3QgcGFkZGluZyBmb3IgbmVnYXRpdmUgc2NhbGVcblxuICAgICAgdmFyIHBhZGRpbmcgPSB0ZXh0U3RhdGUucGFkZGluZztcblxuICAgICAgaWYgKHBhZGRpbmcgIT0gZGVmYXVsdFBhZGRpbmcgJiYgKHRleHRTdGF0ZS5zY2FsZVswXSA8IDAgfHwgdGV4dFN0YXRlLnNjYWxlWzFdIDwgMCkpIHtcbiAgICAgICAgdmFyIHAwID0gdGV4dFN0YXRlLnBhZGRpbmdbMF07XG4gICAgICAgIHZhciBwMSA9IHRleHRTdGF0ZS5wYWRkaW5nWzFdO1xuICAgICAgICB2YXIgcDIgPSB0ZXh0U3RhdGUucGFkZGluZ1syXTtcbiAgICAgICAgdmFyIHAzID0gdGV4dFN0YXRlLnBhZGRpbmdbM107XG5cbiAgICAgICAgaWYgKHRleHRTdGF0ZS5zY2FsZVswXSA8IDApIHtcbiAgICAgICAgICBwMSA9IC1wMTtcbiAgICAgICAgICBwMyA9IC1wMztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0U3RhdGUuc2NhbGVbMV0gPCAwKSB7XG4gICAgICAgICAgcDAgPSAtcDA7XG4gICAgICAgICAgcDIgPSAtcDI7XG4gICAgICAgIH1cblxuICAgICAgICBwYWRkaW5nID0gW3AwLCBwMSwgcDIsIHAzXTtcbiAgICAgIH0gLy8gVGhlIGltYWdlIGlzIHVua25vd24gYXQgdGhpcyBzdGFnZSBzbyB3ZSBwYXNzIG51bGw7IGl0IHdpbGwgYmUgY29tcHV0ZWQgYXQgcmVuZGVyIHRpbWUuXG4gICAgICAvLyBGb3IgY2xhcml0eSwgd2UgcGFzcyBOYU4gZm9yIG9mZnNldFgsIG9mZnNldFksIHdpZHRoIGFuZCBoZWlnaHQsIHdoaWNoIHdpbGwgYmUgY29tcHV0ZWQgYXRcbiAgICAgIC8vIHJlbmRlciB0aW1lLlxuXG5cbiAgICAgIHZhciBwaXhlbFJhdGlvXzEgPSB0aGlzLnBpeGVsUmF0aW87XG4gICAgICB0aGlzLmluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0lNQUdFLCBiZWdpbiwgZW5kLCBudWxsLCBOYU4sIE5hTiwgTmFOLCAxLCAwLCAwLCB0aGlzLnRleHRSb3RhdGVXaXRoVmlld18sIHRoaXMudGV4dFJvdGF0aW9uXywgWzEsIDFdLCBOYU4sIHRoaXMuZGVjbHV0dGVySW1hZ2VXaXRoVGV4dF8sIHBhZGRpbmcgPT0gZGVmYXVsdFBhZGRpbmcgPyBkZWZhdWx0UGFkZGluZyA6IHBhZGRpbmcubWFwKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgIHJldHVybiBwICogcGl4ZWxSYXRpb18xO1xuICAgICAgfSksICEhdGV4dFN0YXRlLmJhY2tncm91bmRGaWxsLCAhIXRleHRTdGF0ZS5iYWNrZ3JvdW5kU3Ryb2tlLCB0aGlzLnRleHRfLCB0aGlzLnRleHRLZXlfLCB0aGlzLnN0cm9rZUtleV8sIHRoaXMuZmlsbEtleV8sIHRoaXMudGV4dE9mZnNldFhfLCB0aGlzLnRleHRPZmZzZXRZXywgZ2VvbWV0cnlXaWR0aHNdKTtcbiAgICAgIHZhciBzY2FsZSA9IDEgLyBwaXhlbFJhdGlvXzE7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0lNQUdFLCBiZWdpbiwgZW5kLCBudWxsLCBOYU4sIE5hTiwgTmFOLCAxLCAwLCAwLCB0aGlzLnRleHRSb3RhdGVXaXRoVmlld18sIHRoaXMudGV4dFJvdGF0aW9uXywgW3NjYWxlLCBzY2FsZV0sIE5hTiwgdGhpcy5kZWNsdXR0ZXJJbWFnZVdpdGhUZXh0XywgcGFkZGluZywgISF0ZXh0U3RhdGUuYmFja2dyb3VuZEZpbGwsICEhdGV4dFN0YXRlLmJhY2tncm91bmRTdHJva2UsIHRoaXMudGV4dF8sIHRoaXMudGV4dEtleV8sIHRoaXMuc3Ryb2tlS2V5XywgdGhpcy5maWxsS2V5XywgdGhpcy50ZXh0T2Zmc2V0WF8sIHRoaXMudGV4dE9mZnNldFlfLCBnZW9tZXRyeVdpZHRoc10pO1xuICAgICAgdGhpcy5lbmRHZW9tZXRyeShmZWF0dXJlKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1RleHRCdWlsZGVyLnByb3RvdHlwZS5zYXZlVGV4dFN0YXRlc18gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0cm9rZVN0YXRlID0gdGhpcy50ZXh0U3Ryb2tlU3RhdGVfO1xuICAgIHZhciB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZV87XG4gICAgdmFyIGZpbGxTdGF0ZSA9IHRoaXMudGV4dEZpbGxTdGF0ZV87XG4gICAgdmFyIHN0cm9rZUtleSA9IHRoaXMuc3Ryb2tlS2V5XztcblxuICAgIGlmIChzdHJva2VTdGF0ZSkge1xuICAgICAgaWYgKCEoc3Ryb2tlS2V5IGluIHRoaXMuc3Ryb2tlU3RhdGVzKSkge1xuICAgICAgICB0aGlzLnN0cm9rZVN0YXRlc1tzdHJva2VLZXldID0ge1xuICAgICAgICAgIHN0cm9rZVN0eWxlOiBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZSxcbiAgICAgICAgICBsaW5lQ2FwOiBzdHJva2VTdGF0ZS5saW5lQ2FwLFxuICAgICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCxcbiAgICAgICAgICBsaW5lV2lkdGg6IHN0cm9rZVN0YXRlLmxpbmVXaWR0aCxcbiAgICAgICAgICBsaW5lSm9pbjogc3Ryb2tlU3RhdGUubGluZUpvaW4sXG4gICAgICAgICAgbWl0ZXJMaW1pdDogc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdCxcbiAgICAgICAgICBsaW5lRGFzaDogc3Ryb2tlU3RhdGUubGluZURhc2hcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdGV4dEtleSA9IHRoaXMudGV4dEtleV87XG5cbiAgICBpZiAoISh0ZXh0S2V5IGluIHRoaXMudGV4dFN0YXRlcykpIHtcbiAgICAgIHRoaXMudGV4dFN0YXRlc1t0ZXh0S2V5XSA9IHtcbiAgICAgICAgZm9udDogdGV4dFN0YXRlLmZvbnQsXG4gICAgICAgIHRleHRBbGlnbjogdGV4dFN0YXRlLnRleHRBbGlnbiB8fCBkZWZhdWx0VGV4dEFsaWduLFxuICAgICAgICB0ZXh0QmFzZWxpbmU6IHRleHRTdGF0ZS50ZXh0QmFzZWxpbmUgfHwgZGVmYXVsdFRleHRCYXNlbGluZSxcbiAgICAgICAgc2NhbGU6IHRleHRTdGF0ZS5zY2FsZVxuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgZmlsbEtleSA9IHRoaXMuZmlsbEtleV87XG5cbiAgICBpZiAoZmlsbFN0YXRlKSB7XG4gICAgICBpZiAoIShmaWxsS2V5IGluIHRoaXMuZmlsbFN0YXRlcykpIHtcbiAgICAgICAgdGhpcy5maWxsU3RhdGVzW2ZpbGxLZXldID0ge1xuICAgICAgICAgIGZpbGxTdHlsZTogZmlsbFN0YXRlLmZpbGxTdHlsZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBiZWdpbiBCZWdpbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGV4dEJ1aWxkZXIucHJvdG90eXBlLmRyYXdDaGFyc18gPSBmdW5jdGlvbiAoYmVnaW4sIGVuZCkge1xuICAgIHZhciBzdHJva2VTdGF0ZSA9IHRoaXMudGV4dFN0cm9rZVN0YXRlXztcbiAgICB2YXIgdGV4dFN0YXRlID0gdGhpcy50ZXh0U3RhdGVfO1xuICAgIHZhciBzdHJva2VLZXkgPSB0aGlzLnN0cm9rZUtleV87XG4gICAgdmFyIHRleHRLZXkgPSB0aGlzLnRleHRLZXlfO1xuICAgIHZhciBmaWxsS2V5ID0gdGhpcy5maWxsS2V5XztcbiAgICB0aGlzLnNhdmVUZXh0U3RhdGVzXygpO1xuICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5waXhlbFJhdGlvO1xuICAgIHZhciBiYXNlbGluZSA9IFRFWFRfQUxJR05bdGV4dFN0YXRlLnRleHRCYXNlbGluZV07XG4gICAgdmFyIG9mZnNldFkgPSB0aGlzLnRleHRPZmZzZXRZXyAqIHBpeGVsUmF0aW87XG4gICAgdmFyIHRleHQgPSB0aGlzLnRleHRfO1xuICAgIHZhciBzdHJva2VXaWR0aCA9IHN0cm9rZVN0YXRlID8gc3Ryb2tlU3RhdGUubGluZVdpZHRoICogTWF0aC5hYnModGV4dFN0YXRlLnNjYWxlWzBdKSAvIDIgOiAwO1xuICAgIHRoaXMuaW5zdHJ1Y3Rpb25zLnB1c2goW0NhbnZhc0luc3RydWN0aW9uLkRSQVdfQ0hBUlMsIGJlZ2luLCBlbmQsIGJhc2VsaW5lLCB0ZXh0U3RhdGUub3ZlcmZsb3csIGZpbGxLZXksIHRleHRTdGF0ZS5tYXhBbmdsZSwgcGl4ZWxSYXRpbywgb2Zmc2V0WSwgc3Ryb2tlS2V5LCBzdHJva2VXaWR0aCAqIHBpeGVsUmF0aW8sIHRleHQsIHRleHRLZXksIDFdKTtcbiAgICB0aGlzLmhpdERldGVjdGlvbkluc3RydWN0aW9ucy5wdXNoKFtDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0NIQVJTLCBiZWdpbiwgZW5kLCBiYXNlbGluZSwgdGV4dFN0YXRlLm92ZXJmbG93LCBmaWxsS2V5LCB0ZXh0U3RhdGUubWF4QW5nbGUsIDEsIG9mZnNldFksIHN0cm9rZUtleSwgc3Ryb2tlV2lkdGgsIHRleHQsIHRleHRLZXksIDEgLyBwaXhlbFJhdGlvXSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL1RleHQuanNcIikuZGVmYXVsdH0gdGV4dFN0eWxlIFRleHQgc3R5bGUuXG4gICAqIEBwYXJhbSB7T2JqZWN0PX0gb3B0X3NoYXJlZERhdGEgU2hhcmVkIGRhdGEuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGV4dEJ1aWxkZXIucHJvdG90eXBlLnNldFRleHRTdHlsZSA9IGZ1bmN0aW9uICh0ZXh0U3R5bGUsIG9wdF9zaGFyZWREYXRhKSB7XG4gICAgdmFyIHRleHRTdGF0ZSwgZmlsbFN0YXRlLCBzdHJva2VTdGF0ZTtcblxuICAgIGlmICghdGV4dFN0eWxlKSB7XG4gICAgICB0aGlzLnRleHRfID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB0ZXh0RmlsbFN0eWxlID0gdGV4dFN0eWxlLmdldEZpbGwoKTtcblxuICAgICAgaWYgKCF0ZXh0RmlsbFN0eWxlKSB7XG4gICAgICAgIGZpbGxTdGF0ZSA9IG51bGw7XG4gICAgICAgIHRoaXMudGV4dEZpbGxTdGF0ZV8gPSBmaWxsU3RhdGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmaWxsU3RhdGUgPSB0aGlzLnRleHRGaWxsU3RhdGVfO1xuXG4gICAgICAgIGlmICghZmlsbFN0YXRlKSB7XG4gICAgICAgICAgZmlsbFN0YXRlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9ICovXG4gICAgICAgICAge307XG4gICAgICAgICAgdGhpcy50ZXh0RmlsbFN0YXRlXyA9IGZpbGxTdGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZpbGxTdGF0ZS5maWxsU3R5bGUgPSBhc0NvbG9yTGlrZSh0ZXh0RmlsbFN0eWxlLmdldENvbG9yKCkgfHwgZGVmYXVsdEZpbGxTdHlsZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGUgPSB0ZXh0U3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgICAgIGlmICghdGV4dFN0cm9rZVN0eWxlKSB7XG4gICAgICAgIHN0cm9rZVN0YXRlID0gbnVsbDtcbiAgICAgICAgdGhpcy50ZXh0U3Ryb2tlU3RhdGVfID0gc3Ryb2tlU3RhdGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJva2VTdGF0ZSA9IHRoaXMudGV4dFN0cm9rZVN0YXRlXztcblxuICAgICAgICBpZiAoIXN0cm9rZVN0YXRlKSB7XG4gICAgICAgICAgc3Ryb2tlU3RhdGUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlfSAqL1xuICAgICAgICAgIHt9O1xuICAgICAgICAgIHRoaXMudGV4dFN0cm9rZVN0YXRlXyA9IHN0cm9rZVN0YXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxpbmVEYXNoID0gdGV4dFN0cm9rZVN0eWxlLmdldExpbmVEYXNoKCk7XG4gICAgICAgIHZhciBsaW5lRGFzaE9mZnNldCA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lRGFzaE9mZnNldCgpO1xuICAgICAgICB2YXIgbGluZVdpZHRoID0gdGV4dFN0cm9rZVN0eWxlLmdldFdpZHRoKCk7XG4gICAgICAgIHZhciBtaXRlckxpbWl0ID0gdGV4dFN0cm9rZVN0eWxlLmdldE1pdGVyTGltaXQoKTtcbiAgICAgICAgc3Ryb2tlU3RhdGUubGluZUNhcCA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lQ2FwKCkgfHwgZGVmYXVsdExpbmVDYXA7XG4gICAgICAgIHN0cm9rZVN0YXRlLmxpbmVEYXNoID0gbGluZURhc2ggPyBsaW5lRGFzaC5zbGljZSgpIDogZGVmYXVsdExpbmVEYXNoO1xuICAgICAgICBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldCA9IGxpbmVEYXNoT2Zmc2V0ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0TGluZURhc2hPZmZzZXQgOiBsaW5lRGFzaE9mZnNldDtcbiAgICAgICAgc3Ryb2tlU3RhdGUubGluZUpvaW4gPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TGluZUpvaW4oKSB8fCBkZWZhdWx0TGluZUpvaW47XG4gICAgICAgIHN0cm9rZVN0YXRlLmxpbmVXaWR0aCA9IGxpbmVXaWR0aCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdExpbmVXaWR0aCA6IGxpbmVXaWR0aDtcbiAgICAgICAgc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdCA9IG1pdGVyTGltaXQgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRNaXRlckxpbWl0IDogbWl0ZXJMaW1pdDtcbiAgICAgICAgc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGUgPSBhc0NvbG9yTGlrZSh0ZXh0U3Ryb2tlU3R5bGUuZ2V0Q29sb3IoKSB8fCBkZWZhdWx0U3Ryb2tlU3R5bGUpO1xuICAgICAgfVxuXG4gICAgICB0ZXh0U3RhdGUgPSB0aGlzLnRleHRTdGF0ZV87XG4gICAgICB2YXIgZm9udCA9IHRleHRTdHlsZS5nZXRGb250KCkgfHwgZGVmYXVsdEZvbnQ7XG4gICAgICByZWdpc3RlckZvbnQoZm9udCk7XG4gICAgICB2YXIgdGV4dFNjYWxlID0gdGV4dFN0eWxlLmdldFNjYWxlQXJyYXkoKTtcbiAgICAgIHRleHRTdGF0ZS5vdmVyZmxvdyA9IHRleHRTdHlsZS5nZXRPdmVyZmxvdygpO1xuICAgICAgdGV4dFN0YXRlLmZvbnQgPSBmb250O1xuICAgICAgdGV4dFN0YXRlLm1heEFuZ2xlID0gdGV4dFN0eWxlLmdldE1heEFuZ2xlKCk7XG4gICAgICB0ZXh0U3RhdGUucGxhY2VtZW50ID0gdGV4dFN0eWxlLmdldFBsYWNlbWVudCgpO1xuICAgICAgdGV4dFN0YXRlLnRleHRBbGlnbiA9IHRleHRTdHlsZS5nZXRUZXh0QWxpZ24oKTtcbiAgICAgIHRleHRTdGF0ZS50ZXh0QmFzZWxpbmUgPSB0ZXh0U3R5bGUuZ2V0VGV4dEJhc2VsaW5lKCkgfHwgZGVmYXVsdFRleHRCYXNlbGluZTtcbiAgICAgIHRleHRTdGF0ZS5iYWNrZ3JvdW5kRmlsbCA9IHRleHRTdHlsZS5nZXRCYWNrZ3JvdW5kRmlsbCgpO1xuICAgICAgdGV4dFN0YXRlLmJhY2tncm91bmRTdHJva2UgPSB0ZXh0U3R5bGUuZ2V0QmFja2dyb3VuZFN0cm9rZSgpO1xuICAgICAgdGV4dFN0YXRlLnBhZGRpbmcgPSB0ZXh0U3R5bGUuZ2V0UGFkZGluZygpIHx8IGRlZmF1bHRQYWRkaW5nO1xuICAgICAgdGV4dFN0YXRlLnNjYWxlID0gdGV4dFNjYWxlID09PSB1bmRlZmluZWQgPyBbMSwgMV0gOiB0ZXh0U2NhbGU7XG4gICAgICB2YXIgdGV4dE9mZnNldFggPSB0ZXh0U3R5bGUuZ2V0T2Zmc2V0WCgpO1xuICAgICAgdmFyIHRleHRPZmZzZXRZID0gdGV4dFN0eWxlLmdldE9mZnNldFkoKTtcbiAgICAgIHZhciB0ZXh0Um90YXRlV2l0aFZpZXcgPSB0ZXh0U3R5bGUuZ2V0Um90YXRlV2l0aFZpZXcoKTtcbiAgICAgIHZhciB0ZXh0Um90YXRpb24gPSB0ZXh0U3R5bGUuZ2V0Um90YXRpb24oKTtcbiAgICAgIHRoaXMudGV4dF8gPSB0ZXh0U3R5bGUuZ2V0VGV4dCgpIHx8ICcnO1xuICAgICAgdGhpcy50ZXh0T2Zmc2V0WF8gPSB0ZXh0T2Zmc2V0WCA9PT0gdW5kZWZpbmVkID8gMCA6IHRleHRPZmZzZXRYO1xuICAgICAgdGhpcy50ZXh0T2Zmc2V0WV8gPSB0ZXh0T2Zmc2V0WSA9PT0gdW5kZWZpbmVkID8gMCA6IHRleHRPZmZzZXRZO1xuICAgICAgdGhpcy50ZXh0Um90YXRlV2l0aFZpZXdfID0gdGV4dFJvdGF0ZVdpdGhWaWV3ID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IHRleHRSb3RhdGVXaXRoVmlldztcbiAgICAgIHRoaXMudGV4dFJvdGF0aW9uXyA9IHRleHRSb3RhdGlvbiA9PT0gdW5kZWZpbmVkID8gMCA6IHRleHRSb3RhdGlvbjtcbiAgICAgIHRoaXMuc3Ryb2tlS2V5XyA9IHN0cm9rZVN0YXRlID8gKHR5cGVvZiBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZSA9PSAnc3RyaW5nJyA/IHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlIDogZ2V0VWlkKHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlKSkgKyBzdHJva2VTdGF0ZS5saW5lQ2FwICsgc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQgKyAnfCcgKyBzdHJva2VTdGF0ZS5saW5lV2lkdGggKyBzdHJva2VTdGF0ZS5saW5lSm9pbiArIHN0cm9rZVN0YXRlLm1pdGVyTGltaXQgKyAnWycgKyBzdHJva2VTdGF0ZS5saW5lRGFzaC5qb2luKCkgKyAnXScgOiAnJztcbiAgICAgIHRoaXMudGV4dEtleV8gPSB0ZXh0U3RhdGUuZm9udCArIHRleHRTdGF0ZS5zY2FsZSArICh0ZXh0U3RhdGUudGV4dEFsaWduIHx8ICc/JykgKyAodGV4dFN0YXRlLnRleHRCYXNlbGluZSB8fCAnPycpO1xuICAgICAgdGhpcy5maWxsS2V5XyA9IGZpbGxTdGF0ZSA/IHR5cGVvZiBmaWxsU3RhdGUuZmlsbFN0eWxlID09ICdzdHJpbmcnID8gZmlsbFN0YXRlLmZpbGxTdHlsZSA6ICd8JyArIGdldFVpZChmaWxsU3RhdGUuZmlsbFN0eWxlKSA6ICcnO1xuICAgIH1cblxuICAgIHRoaXMuZGVjbHV0dGVySW1hZ2VXaXRoVGV4dF8gPSBvcHRfc2hhcmVkRGF0YTtcbiAgfTtcblxuICByZXR1cm4gQ2FudmFzVGV4dEJ1aWxkZXI7XG59KENhbnZhc0J1aWxkZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBDYW52YXNUZXh0QnVpbGRlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXBcbiAqL1xuaW1wb3J0IEJ1aWxkZXIgZnJvbSAnLi9CdWlsZGVyLmpzJztcbmltcG9ydCBJbWFnZUJ1aWxkZXIgZnJvbSAnLi9JbWFnZUJ1aWxkZXIuanMnO1xuaW1wb3J0IExpbmVTdHJpbmdCdWlsZGVyIGZyb20gJy4vTGluZVN0cmluZ0J1aWxkZXIuanMnO1xuaW1wb3J0IFBvbHlnb25CdWlsZGVyIGZyb20gJy4vUG9seWdvbkJ1aWxkZXIuanMnO1xuaW1wb3J0IFRleHRCdWlsZGVyIGZyb20gJy4vVGV4dEJ1aWxkZXIuanMnO1xuLyoqXG4gKiBAdHlwZSB7T2JqZWN0PGltcG9ydChcIi4vQnVpbGRlclR5cGVcIikuZGVmYXVsdCwgdHlwZW9mIEJ1aWxkZXI+fVxuICovXG5cbnZhciBCQVRDSF9DT05TVFJVQ1RPUlMgPSB7XG4gICdDaXJjbGUnOiBQb2x5Z29uQnVpbGRlcixcbiAgJ0RlZmF1bHQnOiBCdWlsZGVyLFxuICAnSW1hZ2UnOiBJbWFnZUJ1aWxkZXIsXG4gICdMaW5lU3RyaW5nJzogTGluZVN0cmluZ0J1aWxkZXIsXG4gICdQb2x5Z29uJzogUG9seWdvbkJ1aWxkZXIsXG4gICdUZXh0JzogVGV4dEJ1aWxkZXJcbn07XG5cbnZhciBCdWlsZGVyR3JvdXAgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRvbGVyYW5jZSBUb2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4RXh0ZW50IE1heCBleHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKi9cbiAgZnVuY3Rpb24gQnVpbGRlckdyb3VwKHRvbGVyYW5jZSwgbWF4RXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMudG9sZXJhbmNlXyA9IHRvbGVyYW5jZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgdGhpcy5tYXhFeHRlbnRfID0gbWF4RXh0ZW50O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucGl4ZWxSYXRpb18gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCAhT2JqZWN0PGltcG9ydChcIi4vQnVpbGRlclR5cGVcIikuZGVmYXVsdCwgQnVpbGRlcj4+fVxuICAgICAqL1xuXG4gICAgdGhpcy5idWlsZGVyc0J5WkluZGV4XyA9IHt9O1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHshT2JqZWN0PHN0cmluZywgIU9iamVjdDxpbXBvcnQoXCIuL0J1aWxkZXJUeXBlXCIpLmRlZmF1bHQsIGltcG9ydChcIi4vQnVpbGRlci5qc1wiKS5TZXJpYWxpemFibGVJbnN0cnVjdGlvbnM+Pn0gVGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnNcbiAgICovXG5cblxuICBCdWlsZGVyR3JvdXAucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYnVpbGRlckluc3RydWN0aW9ucyA9IHt9O1xuXG4gICAgZm9yICh2YXIgektleSBpbiB0aGlzLmJ1aWxkZXJzQnlaSW5kZXhfKSB7XG4gICAgICBidWlsZGVySW5zdHJ1Y3Rpb25zW3pLZXldID0gYnVpbGRlckluc3RydWN0aW9uc1t6S2V5XSB8fCB7fTtcbiAgICAgIHZhciBidWlsZGVycyA9IHRoaXMuYnVpbGRlcnNCeVpJbmRleF9bektleV07XG5cbiAgICAgIGZvciAodmFyIGJ1aWxkZXJLZXkgaW4gYnVpbGRlcnMpIHtcbiAgICAgICAgdmFyIGJ1aWxkZXJJbnN0cnVjdGlvbiA9IGJ1aWxkZXJzW2J1aWxkZXJLZXldLmZpbmlzaCgpO1xuICAgICAgICBidWlsZGVySW5zdHJ1Y3Rpb25zW3pLZXldW2J1aWxkZXJLZXldID0gYnVpbGRlckluc3RydWN0aW9uO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBidWlsZGVySW5zdHJ1Y3Rpb25zO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ8dW5kZWZpbmVkfSB6SW5kZXggWiBpbmRleC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0J1aWxkZXJUeXBlLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJUeXBlIFJlcGxheSB0eXBlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9WZWN0b3JDb250ZXh0LmpzXCIpLmRlZmF1bHR9IFJlcGxheS5cbiAgICovXG5cblxuICBCdWlsZGVyR3JvdXAucHJvdG90eXBlLmdldEJ1aWxkZXIgPSBmdW5jdGlvbiAoekluZGV4LCBidWlsZGVyVHlwZSkge1xuICAgIHZhciB6SW5kZXhLZXkgPSB6SW5kZXggIT09IHVuZGVmaW5lZCA/IHpJbmRleC50b1N0cmluZygpIDogJzAnO1xuICAgIHZhciByZXBsYXlzID0gdGhpcy5idWlsZGVyc0J5WkluZGV4X1t6SW5kZXhLZXldO1xuXG4gICAgaWYgKHJlcGxheXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVwbGF5cyA9IHt9O1xuICAgICAgdGhpcy5idWlsZGVyc0J5WkluZGV4X1t6SW5kZXhLZXldID0gcmVwbGF5cztcbiAgICB9XG5cbiAgICB2YXIgcmVwbGF5ID0gcmVwbGF5c1tidWlsZGVyVHlwZV07XG5cbiAgICBpZiAocmVwbGF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZhciBDb25zdHJ1Y3RvciA9IEJBVENIX0NPTlNUUlVDVE9SU1tidWlsZGVyVHlwZV07XG4gICAgICByZXBsYXkgPSBuZXcgQ29uc3RydWN0b3IodGhpcy50b2xlcmFuY2VfLCB0aGlzLm1heEV4dGVudF8sIHRoaXMucmVzb2x1dGlvbl8sIHRoaXMucGl4ZWxSYXRpb18pO1xuICAgICAgcmVwbGF5c1tidWlsZGVyVHlwZV0gPSByZXBsYXk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcGxheTtcbiAgfTtcblxuICByZXR1cm4gQnVpbGRlckdyb3VwO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBCdWlsZGVyR3JvdXA7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXJlci9MYXllclxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbWFnZVN0YXRlIGZyb20gJy4uL0ltYWdlU3RhdGUuanMnO1xuaW1wb3J0IE9ic2VydmFibGUgZnJvbSAnLi4vT2JzZXJ2YWJsZS5qcyc7XG5pbXBvcnQgU291cmNlU3RhdGUgZnJvbSAnLi4vc291cmNlL1N0YXRlLmpzJztcbmltcG9ydCB7IGFic3RyYWN0IH0gZnJvbSAnLi4vdXRpbC5qcyc7XG4vKipcbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gTGF5ZXJUeXBlXG4gKi9cblxudmFyIExheWVyUmVuZGVyZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTGF5ZXJSZW5kZXJlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7TGF5ZXJUeXBlfSBsYXllciBMYXllci5cbiAgICovXG5cblxuICBmdW5jdGlvbiBMYXllclJlbmRlcmVyKGxheWVyKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKiogQHByaXZhdGUgKi9cblxuXG4gICAgX3RoaXMuYm91bmRIYW5kbGVJbWFnZUNoYW5nZV8gPSBfdGhpcy5oYW5kbGVJbWFnZUNoYW5nZV8uYmluZChfdGhpcyk7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtMYXllclR5cGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5sYXllcl8gPSBsYXllcjtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwID0gbnVsbDtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEFzeW5jaHJvbm91cyBsYXllciBsZXZlbCBoaXQgZGV0ZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlXCIpLmRlZmF1bHQ+Pn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGhcbiAgICogYW4gYXJyYXkgb2YgZmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIERldGVybWluZSB3aGV0aGVyIHJlbmRlciBzaG91bGQgYmUgY2FsbGVkLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gTGF5ZXIgaXMgcmVhZHkgdG8gYmUgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucHJlcGFyZUZyYW1lID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgbGF5ZXIuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YXJnZXQgVGFyZ2V0IHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVuZGVyIGNvbnRlbnQgdG8uXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgcmVuZGVyZWQgZWxlbWVudC5cbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0YXJnZXQpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0PG51bWJlciwgT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0Pj59IHRpbGVzIExvb2t1cCBvZiBsb2FkZWQgdGlsZXMgYnkgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gWm9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbnx2b2lkfSBJZiBgZmFsc2VgLCB0aGUgdGlsZSB3aWxsIG5vdCBiZSBjb25zaWRlcmVkIGxvYWRlZC5cbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5sb2FkZWRUaWxlQ2FsbGJhY2sgPSBmdW5jdGlvbiAodGlsZXMsIHpvb20sIHRpbGUpIHtcbiAgICBpZiAoIXRpbGVzW3pvb21dKSB7XG4gICAgICB0aWxlc1t6b29tXSA9IHt9O1xuICAgIH1cblxuICAgIHRpbGVzW3pvb21dW3RpbGUudGlsZUNvb3JkLnRvU3RyaW5nKCldID0gdGlsZTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQ3JlYXRlIGEgZnVuY3Rpb24gdGhhdCBhZGRzIGxvYWRlZCB0aWxlcyB0byB0aGUgdGlsZSBsb29rdXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc291cmNlL1RpbGUuanNcIikuZGVmYXVsdH0gc291cmNlIFRpbGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24gb2YgdGhlIHRpbGVzLlxuICAgKiBAcGFyYW0ge09iamVjdDxudW1iZXIsIE9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdD4+fSB0aWxlcyBMb29rdXAgb2YgbG9hZGVkIHRpbGVzIGJ5IHpvb20gbGV2ZWwuXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG51bWJlciwgaW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHQpOmJvb2xlYW59IEEgZnVuY3Rpb24gdGhhdCBjYW4gYmVcbiAgICogICAgIGNhbGxlZCB3aXRoIGEgem9vbSBsZXZlbCBhbmQgYSB0aWxlIHJhbmdlIHRvIGFkZCBsb2FkZWQgdGlsZXMgdG8gdGhlIGxvb2t1cC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmNyZWF0ZUxvYWRlZFRpbGVGaW5kZXIgPSBmdW5jdGlvbiAoc291cmNlLCBwcm9qZWN0aW9uLCB0aWxlcykge1xuICAgIHJldHVybiAoXG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFpvb20gbGV2ZWwuXG4gICAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0fSB0aWxlUmFuZ2UgVGlsZSByYW5nZS5cbiAgICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB0aWxlIHJhbmdlIGlzIGZ1bGx5IGxvYWRlZC5cbiAgICAgICAqIEB0aGlzIHtMYXllclJlbmRlcmVyfVxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiAoem9vbSwgdGlsZVJhbmdlKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IHRoaXMubG9hZGVkVGlsZUNhbGxiYWNrLmJpbmQodGhpcywgdGlsZXMsIHpvb20pO1xuICAgICAgICByZXR1cm4gc291cmNlLmZvckVhY2hMb2FkZWRUaWxlKHByb2plY3Rpb24sIHpvb20sIHRpbGVSYW5nZSwgY2FsbGJhY2spO1xuICAgICAgfS5iaW5kKHRoaXMpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdmVjdG9yLmpzXCIpLkZlYXR1cmVDYWxsYmFjazxUPn0gY2FsbGJhY2sgRmVhdHVyZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL01hcC5qc1wiKS5IaXRNYXRjaDxUPj59IG1hdGNoZXMgVGhlIGhpdCBkZXRlY3RlZCBtYXRjaGVzIHdpdGggdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIGZyYW1lU3RhdGUsIGhpdFRvbGVyYW5jZSwgY2FsbGJhY2ssIG1hdGNoZXMpIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lU3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoaXRUb2xlcmFuY2UgSGl0IHRvbGVyYW5jZSBpbiBwaXhlbHMuXG4gICAqIEByZXR1cm4ge1VpbnQ4Q2xhbXBlZEFycmF5fFVpbnQ4QXJyYXl9IFRoZSByZXN1bHQuICBJZiB0aGVyZSBpcyBubyBkYXRhIGF0IHRoZSBwaXhlbFxuICAgKiAgICBsb2NhdGlvbiwgbnVsbCB3aWxsIGJlIHJldHVybmVkLiAgSWYgdGhlcmUgaXMgZGF0YSwgYnV0IHBpeGVsIHZhbHVlcyBjYW5ub3QgYmVcbiAgICogICAgcmV0dXJuZWQsIGFuZCBlbXB0eSBhcnJheSB3aWxsIGJlIHJldHVybmVkLlxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldERhdGFBdFBpeGVsID0gZnVuY3Rpb24gKHBpeGVsLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0xheWVyVHlwZX0gTGF5ZXIuXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0TGF5ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGF5ZXJfO1xuICB9O1xuICAvKipcbiAgICogUGVyZm9ybSBhY3Rpb24gbmVjZXNzYXJ5IHRvIGdldCB0aGUgbGF5ZXIgcmVuZGVyZWQgYWZ0ZXIgbmV3IGZvbnRzIGhhdmUgbG9hZGVkXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cblxuXG4gIExheWVyUmVuZGVyZXIucHJvdG90eXBlLmhhbmRsZUZvbnRzQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHt9O1xuICAvKipcbiAgICogSGFuZGxlIGNoYW5nZXMgaW4gaW1hZ2Ugc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEltYWdlIGNoYW5nZSBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBMYXllclJlbmRlcmVyLnByb3RvdHlwZS5oYW5kbGVJbWFnZUNoYW5nZV8gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgaW1hZ2UgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vSW1hZ2UuanNcIikuZGVmYXVsdH0gKi9cbiAgICBldmVudC50YXJnZXQ7XG5cbiAgICBpZiAoaW1hZ2UuZ2V0U3RhdGUoKSA9PT0gSW1hZ2VTdGF0ZS5MT0FERUQpIHtcbiAgICAgIHRoaXMucmVuZGVySWZSZWFkeUFuZFZpc2libGUoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpbWFnZSBpZiBub3QgYWxyZWFkeSBsb2FkZWQsIGFuZCByZWdpc3RlciB0aGUgaW1hZ2UgY2hhbmdlXG4gICAqIGxpc3RlbmVyIGlmIG5lZWRlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9JbWFnZUJhc2UuanNcIikuZGVmYXVsdH0gaW1hZ2UgSW1hZ2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgaW1hZ2UgaXMgYWxyZWFkeSBsb2FkZWQsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUubG9hZEltYWdlID0gZnVuY3Rpb24gKGltYWdlKSB7XG4gICAgdmFyIGltYWdlU3RhdGUgPSBpbWFnZS5nZXRTdGF0ZSgpO1xuXG4gICAgaWYgKGltYWdlU3RhdGUgIT0gSW1hZ2VTdGF0ZS5MT0FERUQgJiYgaW1hZ2VTdGF0ZSAhPSBJbWFnZVN0YXRlLkVSUk9SKSB7XG4gICAgICBpbWFnZS5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMuYm91bmRIYW5kbGVJbWFnZUNoYW5nZV8pO1xuICAgIH1cblxuICAgIGlmIChpbWFnZVN0YXRlID09IEltYWdlU3RhdGUuSURMRSkge1xuICAgICAgaW1hZ2UubG9hZCgpO1xuICAgICAgaW1hZ2VTdGF0ZSA9IGltYWdlLmdldFN0YXRlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGltYWdlU3RhdGUgPT0gSW1hZ2VTdGF0ZS5MT0FERUQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVySWZSZWFkeUFuZFZpc2libGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuXG4gICAgaWYgKGxheWVyLmdldFZpc2libGUoKSAmJiBsYXllci5nZXRTb3VyY2VTdGF0ZSgpID09IFNvdXJjZVN0YXRlLlJFQURZKSB7XG4gICAgICBsYXllci5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBMYXllclJlbmRlcmVyO1xufShPYnNlcnZhYmxlKTtcblxuZXhwb3J0IGRlZmF1bHQgTGF5ZXJSZW5kZXJlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL2NhbnZhcy9MYXllclxuICovXG5cblxuaW1wb3J0IExheWVyUmVuZGVyZXIgZnJvbSAnLi4vTGF5ZXIuanMnO1xuaW1wb3J0IFJlbmRlckV2ZW50IGZyb20gJy4uLy4uL3JlbmRlci9FdmVudC5qcyc7XG5pbXBvcnQgUmVuZGVyRXZlbnRUeXBlIGZyb20gJy4uLy4uL3JlbmRlci9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgYXBwbHkgYXMgYXBwbHlUcmFuc2Zvcm0sIGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBjb250YWluc0Nvb3JkaW5hdGUsIGdldEJvdHRvbUxlZnQsIGdldEJvdHRvbVJpZ2h0LCBnZXRUb3BMZWZ0LCBnZXRUb3BSaWdodCB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDYW52YXNDb250ZXh0MkQgfSBmcm9tICcuLi8uLi9kb20uanMnO1xuaW1wb3J0IHsgcm90YXRlQXRPZmZzZXQgfSBmcm9tICcuLi8uLi9yZW5kZXIvY2FudmFzLmpzJztcbi8qKlxuICogQGFic3RyYWN0XG4gKiBAdGVtcGxhdGUge2ltcG9ydChcIi4uLy4uL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IExheWVyVHlwZVxuICovXG5cbnZhciBDYW52YXNMYXllclJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc0xheWVyUmVuZGVyZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0xheWVyVHlwZX0gbGF5ZXIgTGF5ZXIuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzTGF5ZXJSZW5kZXJlcihsYXllcikge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGxheWVyKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICovXG5cblxuICAgIF90aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQSB0ZW1wb3JhcnkgdHJhbnNmb3JtLiAgVGhlIHZhbHVlcyBpbiB0aGlzIHRyYW5zZm9ybSBzaG91bGQgb25seSBiZSB1c2VkIGluIGFcbiAgICAgKiBmdW5jdGlvbiB0aGF0IHNldHMgdGhlIHZhbHVlcy5cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy50ZW1wVHJhbnNmb3JtID0gY3JlYXRlVHJhbnNmb3JtKCk7XG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zZm9ybSBmb3IgcmVuZGVyZWQgcGl4ZWxzIHRvIHZpZXdwb3J0IENTUyBwaXhlbHMuICBUaGlzIHRyYW5zZm9ybSBtdXN0XG4gICAgICogYmUgc2V0IHdoZW4gcmVuZGVyaW5nIGEgZnJhbWUgYW5kIG1heSBiZSB1c2VkIGJ5IG90aGVyIGZ1bmN0aW9ucyBhZnRlciByZW5kZXJpbmcuXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxUcmFuc2Zvcm0gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICAvKipcbiAgICAgKiBUaGUgdHJhbnNmb3JtIGZvciB2aWV3cG9ydCBDU1MgcGl4ZWxzIHRvIHJlbmRlcmVkIHBpeGVscy4gIFRoaXMgdHJhbnNmb3JtIG11c3RcbiAgICAgKiBiZSBzZXQgd2hlbiByZW5kZXJpbmcgYSBmcmFtZSBhbmQgbWF5IGJlIHVzZWQgYnkgb3RoZXIgZnVuY3Rpb25zIGFmdGVyIHJlbmRlcmluZy5cbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy5pbnZlcnNlUGl4ZWxUcmFuc2Zvcm0gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29udGV4dCA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250YWluZXJSZXVzZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIHJlbmRlcmluZyBjb250YWluZXIgZnJvbSBhbiBleGlzdGluZyB0YXJnZXQsIGlmIGNvbXBhdGlibGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBQb3RlbnRpYWwgcmVuZGVyIHRhcmdldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRyYW5zZm9ybSBDU1MgVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3BhY2l0eSBPcGFjaXR5LlxuICAgKi9cblxuXG4gIENhbnZhc0xheWVyUmVuZGVyZXIucHJvdG90eXBlLnVzZUNvbnRhaW5lciA9IGZ1bmN0aW9uICh0YXJnZXQsIHRyYW5zZm9ybSwgb3BhY2l0eSkge1xuICAgIHZhciBsYXllckNsYXNzTmFtZSA9IHRoaXMuZ2V0TGF5ZXIoKS5nZXRDbGFzc05hbWUoKTtcbiAgICB2YXIgY29udGFpbmVyLCBjb250ZXh0O1xuXG4gICAgaWYgKHRhcmdldCAmJiB0YXJnZXQuc3R5bGUub3BhY2l0eSA9PT0gJycgJiYgdGFyZ2V0LmNsYXNzTmFtZSA9PT0gbGF5ZXJDbGFzc05hbWUpIHtcbiAgICAgIHZhciBjYW52YXMgPSB0YXJnZXQuZmlyc3RFbGVtZW50Q2hpbGQ7XG5cbiAgICAgIGlmIChjYW52YXMgaW5zdGFuY2VvZiBIVE1MQ2FudmFzRWxlbWVudCkge1xuICAgICAgICBjb250ZXh0ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQgJiYgKGNvbnRleHQuY2FudmFzLndpZHRoID09PSAwIHx8IGNvbnRleHQuY2FudmFzLnN0eWxlLnRyYW5zZm9ybSA9PT0gdHJhbnNmb3JtKSkge1xuICAgICAgLy8gQ29udGFpbmVyIG9mIHRoZSBwcmV2aW91cyBsYXllciByZW5kZXJlciBjYW4gYmUgdXNlZC5cbiAgICAgIHRoaXMuY29udGFpbmVyID0gdGFyZ2V0O1xuICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgIHRoaXMuY29udGFpbmVyUmV1c2VkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29udGFpbmVyUmV1c2VkKSB7XG4gICAgICAvLyBQcmV2aW91c2x5IHJldXNlZCBjb250YWluZXIgY2Fubm90IGJlIHVzZWQgYW55IG1vcmUuXG4gICAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgICB0aGlzLmNvbnRleHQgPSBudWxsO1xuICAgICAgdGhpcy5jb250YWluZXJSZXVzZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGNvbnRhaW5lci5jbGFzc05hbWUgPSBsYXllckNsYXNzTmFtZTtcbiAgICAgIHZhciBzdHlsZSA9IGNvbnRhaW5lci5zdHlsZTtcbiAgICAgIHN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHN0eWxlLndpZHRoID0gJzEwMCUnO1xuICAgICAgc3R5bGUuaGVpZ2h0ID0gJzEwMCUnO1xuICAgICAgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCgpO1xuICAgICAgdmFyIGNhbnZhcyA9IGNvbnRleHQuY2FudmFzO1xuICAgICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNhbnZhcyk7XG4gICAgICBzdHlsZSA9IGNhbnZhcy5zdHlsZTtcbiAgICAgIHN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgIHN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICBzdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSAndG9wIGxlZnQnO1xuICAgICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IENsaXAgZXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuY2xpcCA9IGZ1bmN0aW9uIChjb250ZXh0LCBmcmFtZVN0YXRlLCBleHRlbnQpIHtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgaGFsZldpZHRoID0gZnJhbWVTdGF0ZS5zaXplWzBdICogcGl4ZWxSYXRpbyAvIDI7XG4gICAgdmFyIGhhbGZIZWlnaHQgPSBmcmFtZVN0YXRlLnNpemVbMV0gKiBwaXhlbFJhdGlvIC8gMjtcbiAgICB2YXIgcm90YXRpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgdG9wTGVmdCA9IGdldFRvcExlZnQoZXh0ZW50KTtcbiAgICB2YXIgdG9wUmlnaHQgPSBnZXRUb3BSaWdodChleHRlbnQpO1xuICAgIHZhciBib3R0b21SaWdodCA9IGdldEJvdHRvbVJpZ2h0KGV4dGVudCk7XG4gICAgdmFyIGJvdHRvbUxlZnQgPSBnZXRCb3R0b21MZWZ0KGV4dGVudCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgdG9wTGVmdCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgdG9wUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0sIGJvdHRvbVJpZ2h0KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCBib3R0b21MZWZ0KTtcbiAgICBjb250ZXh0LnNhdmUoKTtcbiAgICByb3RhdGVBdE9mZnNldChjb250ZXh0LCAtcm90YXRpb24sIGhhbGZXaWR0aCwgaGFsZkhlaWdodCk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICBjb250ZXh0Lm1vdmVUbyh0b3BMZWZ0WzBdICogcGl4ZWxSYXRpbywgdG9wTGVmdFsxXSAqIHBpeGVsUmF0aW8pO1xuICAgIGNvbnRleHQubGluZVRvKHRvcFJpZ2h0WzBdICogcGl4ZWxSYXRpbywgdG9wUmlnaHRbMV0gKiBwaXhlbFJhdGlvKTtcbiAgICBjb250ZXh0LmxpbmVUbyhib3R0b21SaWdodFswXSAqIHBpeGVsUmF0aW8sIGJvdHRvbVJpZ2h0WzFdICogcGl4ZWxSYXRpbyk7XG4gICAgY29udGV4dC5saW5lVG8oYm90dG9tTGVmdFswXSAqIHBpeGVsUmF0aW8sIGJvdHRvbUxlZnRbMV0gKiBwaXhlbFJhdGlvKTtcbiAgICBjb250ZXh0LmNsaXAoKTtcbiAgICByb3RhdGVBdE9mZnNldChjb250ZXh0LCByb3RhdGlvbiwgaGFsZldpZHRoLCBoYWxmSGVpZ2h0KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IENsaXAgZXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuY2xpcFVucm90YXRlZCA9IGZ1bmN0aW9uIChjb250ZXh0LCBmcmFtZVN0YXRlLCBleHRlbnQpIHtcbiAgICB2YXIgdG9wTGVmdCA9IGdldFRvcExlZnQoZXh0ZW50KTtcbiAgICB2YXIgdG9wUmlnaHQgPSBnZXRUb3BSaWdodChleHRlbnQpO1xuICAgIHZhciBib3R0b21SaWdodCA9IGdldEJvdHRvbVJpZ2h0KGV4dGVudCk7XG4gICAgdmFyIGJvdHRvbUxlZnQgPSBnZXRCb3R0b21MZWZ0KGV4dGVudCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgdG9wTGVmdCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oZnJhbWVTdGF0ZS5jb29yZGluYXRlVG9QaXhlbFRyYW5zZm9ybSwgdG9wUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGZyYW1lU3RhdGUuY29vcmRpbmF0ZVRvUGl4ZWxUcmFuc2Zvcm0sIGJvdHRvbVJpZ2h0KTtcbiAgICBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLmNvb3JkaW5hdGVUb1BpeGVsVHJhbnNmb3JtLCBib3R0b21MZWZ0KTtcbiAgICB2YXIgaW52ZXJ0ZWQgPSB0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybTtcbiAgICBhcHBseVRyYW5zZm9ybShpbnZlcnRlZCwgdG9wTGVmdCk7XG4gICAgYXBwbHlUcmFuc2Zvcm0oaW52ZXJ0ZWQsIHRvcFJpZ2h0KTtcbiAgICBhcHBseVRyYW5zZm9ybShpbnZlcnRlZCwgYm90dG9tUmlnaHQpO1xuICAgIGFwcGx5VHJhbnNmb3JtKGludmVydGVkLCBib3R0b21MZWZ0KTtcbiAgICBjb250ZXh0LnNhdmUoKTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKE1hdGgucm91bmQodG9wTGVmdFswXSksIE1hdGgucm91bmQodG9wTGVmdFsxXSkpO1xuICAgIGNvbnRleHQubGluZVRvKE1hdGgucm91bmQodG9wUmlnaHRbMF0pLCBNYXRoLnJvdW5kKHRvcFJpZ2h0WzFdKSk7XG4gICAgY29udGV4dC5saW5lVG8oTWF0aC5yb3VuZChib3R0b21SaWdodFswXSksIE1hdGgucm91bmQoYm90dG9tUmlnaHRbMV0pKTtcbiAgICBjb250ZXh0LmxpbmVUbyhNYXRoLnJvdW5kKGJvdHRvbUxlZnRbMF0pLCBNYXRoLnJvdW5kKGJvdHRvbUxlZnRbMV0pKTtcbiAgICBjb250ZXh0LmNsaXAoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVuZGVyL0V2ZW50VHlwZS5qc1wiKS5kZWZhdWx0fSB0eXBlIEV2ZW50IHR5cGUuXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZGlzcGF0Y2hSZW5kZXJFdmVudF8gPSBmdW5jdGlvbiAodHlwZSwgY29udGV4dCwgZnJhbWVTdGF0ZSkge1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcblxuICAgIGlmIChsYXllci5oYXNMaXN0ZW5lcih0eXBlKSkge1xuICAgICAgdmFyIGV2ZW50XzEgPSBuZXcgUmVuZGVyRXZlbnQodHlwZSwgdGhpcy5pbnZlcnNlUGl4ZWxUcmFuc2Zvcm0sIGZyYW1lU3RhdGUsIGNvbnRleHQpO1xuICAgICAgbGF5ZXIuZGlzcGF0Y2hFdmVudChldmVudF8xKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucHJlUmVuZGVyID0gZnVuY3Rpb24gKGNvbnRleHQsIGZyYW1lU3RhdGUpIHtcbiAgICB0aGlzLmRpc3BhdGNoUmVuZGVyRXZlbnRfKFJlbmRlckV2ZW50VHlwZS5QUkVSRU5ERVIsIGNvbnRleHQsIGZyYW1lU3RhdGUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIENhbnZhc0xheWVyUmVuZGVyZXIucHJvdG90eXBlLnBvc3RSZW5kZXIgPSBmdW5jdGlvbiAoY29udGV4dCwgZnJhbWVTdGF0ZSkge1xuICAgIHRoaXMuZGlzcGF0Y2hSZW5kZXJFdmVudF8oUmVuZGVyRXZlbnRUeXBlLlBPU1RSRU5ERVIsIGNvbnRleHQsIGZyYW1lU3RhdGUpO1xuICB9O1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHRyYW5zZm9ybSBmb3IgcmVuZGVyaW5nIHRvIGFuIGVsZW1lbnQgdGhhdCB3aWxsIGJlIHJvdGF0ZWQgYWZ0ZXIgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2VudGVyIENlbnRlci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFdpZHRoIG9mIHRoZSByZW5kZXJlZCBlbGVtZW50IChpbiBwaXhlbHMpLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IEhlaWdodCBvZiB0aGUgcmVuZGVyZWQgZWxlbWVudCAoaW4gcGl4ZWxzKS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFggT2Zmc2V0IG9uIHRoZSB4LWF4aXMgaW4gdmlldyBjb29yZGluYXRlcy5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAcmV0dXJuIHshaW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gVHJhbnNmb3JtLlxuICAgKi9cblxuXG4gIENhbnZhc0xheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldFJlbmRlclRyYW5zZm9ybSA9IGZ1bmN0aW9uIChjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBwaXhlbFJhdGlvLCB3aWR0aCwgaGVpZ2h0LCBvZmZzZXRYKSB7XG4gICAgdmFyIGR4MSA9IHdpZHRoIC8gMjtcbiAgICB2YXIgZHkxID0gaGVpZ2h0IC8gMjtcbiAgICB2YXIgc3ggPSBwaXhlbFJhdGlvIC8gcmVzb2x1dGlvbjtcbiAgICB2YXIgc3kgPSAtc3g7XG4gICAgdmFyIGR4MiA9IC1jZW50ZXJbMF0gKyBvZmZzZXRYO1xuICAgIHZhciBkeTIgPSAtY2VudGVyWzFdO1xuICAgIHJldHVybiBjb21wb3NlVHJhbnNmb3JtKHRoaXMudGVtcFRyYW5zZm9ybSwgZHgxLCBkeTEsIHN4LCBzeSwgLXJvdGF0aW9uLCBkeDIsIGR5Mik7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZVN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcmV0dXJuIHtVaW50OENsYW1wZWRBcnJheXxVaW50OEFycmF5fSBUaGUgcmVzdWx0LiAgSWYgdGhlcmUgaXMgbm8gZGF0YSBhdCB0aGUgcGl4ZWxcbiAgICogICAgbG9jYXRpb24sIG51bGwgd2lsbCBiZSByZXR1cm5lZC4gIElmIHRoZXJlIGlzIGRhdGEsIGJ1dCBwaXhlbCB2YWx1ZXMgY2Fubm90IGJlXG4gICAqICAgIHJldHVybmVkLCBhbmQgZW1wdHkgYXJyYXkgd2lsbCBiZSByZXR1cm5lZC5cbiAgICovXG5cblxuICBDYW52YXNMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXREYXRhQXRQaXhlbCA9IGZ1bmN0aW9uIChwaXhlbCwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlKSB7XG4gICAgdmFyIHJlbmRlclBpeGVsID0gYXBwbHlUcmFuc2Zvcm0odGhpcy5pbnZlcnNlUGl4ZWxUcmFuc2Zvcm0sIHBpeGVsLnNsaWNlKCkpO1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgbGF5ZXJFeHRlbnQgPSBsYXllci5nZXRFeHRlbnQoKTtcblxuICAgIGlmIChsYXllckV4dGVudCkge1xuICAgICAgdmFyIHJlbmRlckNvb3JkaW5hdGUgPSBhcHBseVRyYW5zZm9ybShmcmFtZVN0YXRlLnBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtLCBwaXhlbC5zbGljZSgpKTtcbiAgICAgIC8qKiBnZXQgb25seSBkYXRhIGluc2lkZSBvZiB0aGUgbGF5ZXIgZXh0ZW50ICovXG5cbiAgICAgIGlmICghY29udGFpbnNDb29yZGluYXRlKGxheWVyRXh0ZW50LCByZW5kZXJDb29yZGluYXRlKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZGF0YTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgeCA9IE1hdGgucm91bmQocmVuZGVyUGl4ZWxbMF0pO1xuICAgICAgdmFyIHkgPSBNYXRoLnJvdW5kKHJlbmRlclBpeGVsWzFdKTtcbiAgICAgIHZhciBuZXdDYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgIHZhciBuZXdDb250ZXh0ID0gbmV3Q2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICBuZXdDYW52YXMud2lkdGggPSAxO1xuICAgICAgbmV3Q2FudmFzLmhlaWdodCA9IDE7XG4gICAgICBuZXdDb250ZXh0LmNsZWFyUmVjdCgwLCAwLCAxLCAxKTtcbiAgICAgIG5ld0NvbnRleHQuZHJhd0ltYWdlKGNvbnRleHQuY2FudmFzLCB4LCB5LCAxLCAxLCAwLCAwLCAxLCAxKTtcbiAgICAgIGRhdGEgPSBuZXdDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKS5kYXRhO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGVyci5uYW1lID09PSAnU2VjdXJpdHlFcnJvcicpIHtcbiAgICAgICAgLy8gdGFpbnRlZCBjYW52YXMsIHdlIGFzc3VtZSB0aGVyZSBpcyBkYXRhIGF0IHRoZSBnaXZlbiBwaXhlbCAoYWx0aG91Z2ggdGhlcmUgbWlnaHQgbm90IGJlKVxuICAgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKGRhdGFbM10gPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBkYXRhO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNMYXllclJlbmRlcmVyO1xufShMYXllclJlbmRlcmVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzTGF5ZXJSZW5kZXJlcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyL2NhbnZhcy9CdWlsZGVyVHlwZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGRlZmF1bHQge1xuICBDSVJDTEU6ICdDaXJjbGUnLFxuICBERUZBVUxUOiAnRGVmYXVsdCcsXG4gIElNQUdFOiAnSW1hZ2UnLFxuICBMSU5FX1NUUklORzogJ0xpbmVTdHJpbmcnLFxuICBQT0xZR09OOiAnUG9seWdvbicsXG4gIFRFWFQ6ICdUZXh0J1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L3RleHRwYXRoXG4gKi9cbmltcG9ydCB7IGxlcnAgfSBmcm9tICcuLi8uLi9tYXRoLmpzJztcbmltcG9ydCB7IHJvdGF0ZSB9IGZyb20gJy4vdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgUGF0aCB0byBwdXQgdGV4dCBvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgU3RhcnQgb2Zmc2V0IG9mIHRoZSBgZmxhdENvb3JkaW5hdGVzYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kIG9mZnNldCBvZiB0aGUgYGZsYXRDb29yZGluYXRlc2AuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0IFRleHQgdG8gcGxhY2Ugb24gdGhlIHBhdGguXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnRNIG0gYWxvbmcgdGhlIHBhdGggd2hlcmUgdGhlIHRleHQgc3RhcnRzLlxuICogQHBhcmFtIHtudW1iZXJ9IG1heEFuZ2xlIE1heCBhbmdsZSBiZXR3ZWVuIGFkamFjZW50IGNoYXJzIGluIHJhZGlhbnMuXG4gKiBAcGFyYW0ge251bWJlcn0gc2NhbGUgVGhlIHByb2R1Y3Qgb2YgdGhlIHRleHQgc2NhbGUgYW5kIHRoZSBkZXZpY2UgcGl4ZWwgcmF0aW8uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHN0cmluZywgc3RyaW5nLCBPYmplY3Q8c3RyaW5nLCBudW1iZXI+KTpudW1iZXJ9IG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aCBNZWFzdXJlIGFuZCBjYWNoZSB0ZXh0IHdpZHRoLlxuICogQHBhcmFtIHtzdHJpbmd9IGZvbnQgVGhlIGZvbnQuXG4gKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsIG51bWJlcj59IGNhY2hlIEEgY2FjaGUgb2YgbWVhc3VyZWQgd2lkdGhzLlxuICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uIHRvIGFwcGx5IHRvIHRoZSBmbGF0Q29vcmRpbmF0ZXMgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGV4dCBuZWVkcyB0byBiZSByZXZlcnNlZC5cbiAqIEByZXR1cm4ge0FycmF5PEFycmF5PCo+Pn0gVGhlIHJlc3VsdCBhcnJheSAob3IgbnVsbCBpZiBgbWF4QW5nbGVgIHdhc1xuICogZXhjZWVkZWQpLiBFbnRyaWVzIG9mIHRoZSBhcnJheSBhcmUgeCwgeSwgYW5jaG9yWCwgYW5nbGUsIGNodW5rLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkcmF3VGV4dE9uUGF0aChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHRleHQsIHN0YXJ0TSwgbWF4QW5nbGUsIHNjYWxlLCBtZWFzdXJlQW5kQ2FjaGVUZXh0V2lkdGgsIGZvbnQsIGNhY2hlLCByb3RhdGlvbikge1xuICB2YXIgeDIgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICB2YXIgeDEgPSAwO1xuICB2YXIgeTEgPSAwO1xuICB2YXIgc2VnbWVudExlbmd0aCA9IDA7XG4gIHZhciBzZWdtZW50TSA9IDA7XG5cbiAgZnVuY3Rpb24gYWR2YW5jZSgpIHtcbiAgICB4MSA9IHgyO1xuICAgIHkxID0geTI7XG4gICAgb2Zmc2V0ICs9IHN0cmlkZTtcbiAgICB4MiA9IGZsYXRDb29yZGluYXRlc1tvZmZzZXRdO1xuICAgIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICAgIHNlZ21lbnRNICs9IHNlZ21lbnRMZW5ndGg7XG4gICAgc2VnbWVudExlbmd0aCA9IE1hdGguc3FydCgoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSkpO1xuICB9XG5cbiAgZG8ge1xuICAgIGFkdmFuY2UoKTtcbiAgfSB3aGlsZSAob2Zmc2V0IDwgZW5kIC0gc3RyaWRlICYmIHNlZ21lbnRNICsgc2VnbWVudExlbmd0aCA8IHN0YXJ0TSk7XG5cbiAgdmFyIGludGVycG9sYXRlID0gKHN0YXJ0TSAtIHNlZ21lbnRNKSAvIHNlZ21lbnRMZW5ndGg7XG4gIHZhciBiZWdpblggPSBsZXJwKHgxLCB4MiwgaW50ZXJwb2xhdGUpO1xuICB2YXIgYmVnaW5ZID0gbGVycCh5MSwgeTIsIGludGVycG9sYXRlKTtcbiAgdmFyIHN0YXJ0T2Zmc2V0ID0gb2Zmc2V0IC0gc3RyaWRlO1xuICB2YXIgc3RhcnRMZW5ndGggPSBzZWdtZW50TTtcbiAgdmFyIGVuZE0gPSBzdGFydE0gKyBzY2FsZSAqIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aChmb250LCB0ZXh0LCBjYWNoZSk7XG5cbiAgd2hpbGUgKG9mZnNldCA8IGVuZCAtIHN0cmlkZSAmJiBzZWdtZW50TSArIHNlZ21lbnRMZW5ndGggPCBlbmRNKSB7XG4gICAgYWR2YW5jZSgpO1xuICB9XG5cbiAgaW50ZXJwb2xhdGUgPSAoZW5kTSAtIHNlZ21lbnRNKSAvIHNlZ21lbnRMZW5ndGg7XG4gIHZhciBlbmRYID0gbGVycCh4MSwgeDIsIGludGVycG9sYXRlKTtcbiAgdmFyIGVuZFkgPSBsZXJwKHkxLCB5MiwgaW50ZXJwb2xhdGUpOyAvLyBLZWVwIHRleHQgdXByaWdodFxuXG4gIHZhciByZXZlcnNlO1xuXG4gIGlmIChyb3RhdGlvbikge1xuICAgIHZhciBmbGF0ID0gW2JlZ2luWCwgYmVnaW5ZLCBlbmRYLCBlbmRZXTtcbiAgICByb3RhdGUoZmxhdCwgMCwgNCwgMiwgcm90YXRpb24sIGZsYXQsIGZsYXQpO1xuICAgIHJldmVyc2UgPSBmbGF0WzBdID4gZmxhdFsyXTtcbiAgfSBlbHNlIHtcbiAgICByZXZlcnNlID0gYmVnaW5YID4gZW5kWDtcbiAgfVxuXG4gIHZhciBQSSA9IE1hdGguUEk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIHNpbmdsZVNlZ21lbnQgPSBzdGFydE9mZnNldCArIHN0cmlkZSA9PT0gb2Zmc2V0O1xuICBvZmZzZXQgPSBzdGFydE9mZnNldDtcbiAgc2VnbWVudExlbmd0aCA9IDA7XG4gIHNlZ21lbnRNID0gc3RhcnRMZW5ndGg7XG4gIHgyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gIHkyID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdOyAvLyBBbGwgb24gdGhlIHNhbWUgc2VnbWVudFxuXG4gIGlmIChzaW5nbGVTZWdtZW50KSB7XG4gICAgYWR2YW5jZSgpO1xuICAgIHZhciBwcmV2aW91c0FuZ2xlXzEgPSBNYXRoLmF0YW4yKHkyIC0geTEsIHgyIC0geDEpO1xuXG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIHByZXZpb3VzQW5nbGVfMSArPSBwcmV2aW91c0FuZ2xlXzEgPiAwID8gLVBJIDogUEk7XG4gICAgfVxuXG4gICAgdmFyIHggPSAoZW5kWCArIGJlZ2luWCkgLyAyO1xuICAgIHZhciB5ID0gKGVuZFkgKyBiZWdpblkpIC8gMjtcbiAgICByZXN1bHRbMF0gPSBbeCwgeSwgKGVuZE0gLSBzdGFydE0pIC8gMiwgcHJldmlvdXNBbmdsZV8xLCB0ZXh0XTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIHByZXZpb3VzQW5nbGU7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGV4dC5sZW5ndGg7IGkgPCBpaTspIHtcbiAgICBhZHZhbmNlKCk7XG4gICAgdmFyIGFuZ2xlID0gTWF0aC5hdGFuMih5MiAtIHkxLCB4MiAtIHgxKTtcblxuICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICBhbmdsZSArPSBhbmdsZSA+IDAgPyAtUEkgOiBQSTtcbiAgICB9XG5cbiAgICBpZiAocHJldmlvdXNBbmdsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgZGVsdGEgPSBhbmdsZSAtIHByZXZpb3VzQW5nbGU7XG4gICAgICBkZWx0YSArPSBkZWx0YSA+IFBJID8gLTIgKiBQSSA6IGRlbHRhIDwgLVBJID8gMiAqIFBJIDogMDtcblxuICAgICAgaWYgKE1hdGguYWJzKGRlbHRhKSA+IG1heEFuZ2xlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByZXZpb3VzQW5nbGUgPSBhbmdsZTtcbiAgICB2YXIgaVN0YXJ0ID0gaTtcbiAgICB2YXIgY2hhckxlbmd0aCA9IDA7XG5cbiAgICBmb3IgKDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBpbmRleCA9IHJldmVyc2UgPyBpaSAtIGkgLSAxIDogaTtcbiAgICAgIHZhciBsZW4gPSBzY2FsZSAqIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aChmb250LCB0ZXh0W2luZGV4XSwgY2FjaGUpO1xuXG4gICAgICBpZiAob2Zmc2V0ICsgc3RyaWRlIDwgZW5kICYmIHNlZ21lbnRNICsgc2VnbWVudExlbmd0aCA8IHN0YXJ0TSArIGNoYXJMZW5ndGggKyBsZW4gLyAyKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjaGFyTGVuZ3RoICs9IGxlbjtcbiAgICB9XG5cbiAgICBpZiAoaSA9PT0gaVN0YXJ0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB2YXIgY2hhcnMgPSByZXZlcnNlID8gdGV4dC5zdWJzdHJpbmcoaWkgLSBpU3RhcnQsIGlpIC0gaSkgOiB0ZXh0LnN1YnN0cmluZyhpU3RhcnQsIGkpO1xuICAgIGludGVycG9sYXRlID0gKHN0YXJ0TSArIGNoYXJMZW5ndGggLyAyIC0gc2VnbWVudE0pIC8gc2VnbWVudExlbmd0aDtcbiAgICB2YXIgeCA9IGxlcnAoeDEsIHgyLCBpbnRlcnBvbGF0ZSk7XG4gICAgdmFyIHkgPSBsZXJwKHkxLCB5MiwgaW50ZXJwb2xhdGUpO1xuICAgIHJlc3VsdC5wdXNoKFt4LCB5LCBjaGFyTGVuZ3RoIC8gMiwgYW5nbGUsIGNoYXJzXSk7XG4gICAgc3RhcnRNICs9IGNoYXJMZW5ndGg7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvbGVuZ3RoXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBMZW5ndGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaW5lU3RyaW5nTGVuZ3RoKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgdmFyIHkxID0gZmxhdENvb3JkaW5hdGVzW29mZnNldCArIDFdO1xuICB2YXIgbGVuZ3RoID0gMDtcblxuICBmb3IgKHZhciBpID0gb2Zmc2V0ICsgc3RyaWRlOyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgIHZhciB4MiA9IGZsYXRDb29yZGluYXRlc1tpXTtcbiAgICB2YXIgeTIgPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuICAgIGxlbmd0aCArPSBNYXRoLnNxcnQoKHgyIC0geDEpICogKHgyIC0geDEpICsgKHkyIC0geTEpICogKHkyIC0geTEpKTtcbiAgICB4MSA9IHgyO1xuICAgIHkxID0geTI7XG4gIH1cblxuICByZXR1cm4gbGVuZ3RoO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7bnVtYmVyfSBQZXJpbWV0ZXIuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVhclJpbmdMZW5ndGgoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIHZhciBwZXJpbWV0ZXIgPSBsaW5lU3RyaW5nTGVuZ3RoKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSk7XG4gIHZhciBkeCA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGVdIC0gZmxhdENvb3JkaW5hdGVzW29mZnNldF07XG4gIHZhciBkeSA9IGZsYXRDb29yZGluYXRlc1tlbmQgLSBzdHJpZGUgKyAxXSAtIGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyAxXTtcbiAgcGVyaW1ldGVyICs9IE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG4gIHJldHVybiBwZXJpbWV0ZXI7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvRXhlY3V0b3JcbiAqL1xuaW1wb3J0IENhbnZhc0luc3RydWN0aW9uIGZyb20gJy4vSW5zdHJ1Y3Rpb24uanMnO1xuaW1wb3J0IHsgVEVYVF9BTElHTiB9IGZyb20gJy4vVGV4dEJ1aWxkZXIuanMnO1xuaW1wb3J0IHsgV09SS0VSX09GRlNDUkVFTl9DQU5WQVMgfSBmcm9tICcuLi8uLi9oYXMuanMnO1xuaW1wb3J0IHsgYXBwbHkgYXMgYXBwbHlUcmFuc2Zvcm0sIGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSwgc2V0RnJvbUFycmF5IGFzIHRyYW5zZm9ybVNldEZyb21BcnJheSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbXB0eSwgY3JlYXRlT3JVcGRhdGUsIGludGVyc2VjdHMgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZGVmYXVsdFBhZGRpbmcsIGRlZmF1bHRUZXh0QmFzZWxpbmUsIGRyYXdJbWFnZU9yTGFiZWwgfSBmcm9tICcuLi9jYW52YXMuanMnO1xuaW1wb3J0IHsgZGVmYXVsdFRleHRBbGlnbiwgbWVhc3VyZUFuZENhY2hlVGV4dFdpZHRoLCBtZWFzdXJlVGV4dEhlaWdodCwgbWVhc3VyZVRleHRXaWR0aHMgfSBmcm9tICcuLi9jYW52YXMuanMnO1xuaW1wb3J0IHsgZHJhd1RleHRPblBhdGggfSBmcm9tICcuLi8uLi9nZW9tL2ZsYXQvdGV4dHBhdGguanMnO1xuaW1wb3J0IHsgZXF1YWxzIH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgbGluZVN0cmluZ0xlbmd0aCB9IGZyb20gJy4uLy4uL2dlb20vZmxhdC9sZW5ndGguanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtMkQgfSBmcm9tICcuLi8uLi9nZW9tL2ZsYXQvdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQkJveFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1pblhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5ZXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWF4WFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heFlcbiAqIEBwcm9wZXJ0eSB7Kn0gdmFsdWVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEltYWdlT3JMYWJlbERpbWVuc2lvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkcmF3SW1hZ2VYXG4gKiBAcHJvcGVydHkge251bWJlcn0gZHJhd0ltYWdlWVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRyYXdJbWFnZVdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBkcmF3SW1hZ2VIXG4gKiBAcHJvcGVydHkge251bWJlcn0gb3JpZ2luWFxuICogQHByb3BlcnR5IHtudW1iZXJ9IG9yaWdpbllcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gc2NhbGVcbiAqIEBwcm9wZXJ0eSB7QkJveH0gZGVjbHV0dGVyQm94XG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IGNhbnZhc1RyYW5zZm9ybVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge3swOiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQsIDE6IG51bWJlciwgMjogaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkxhYmVsfEhUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudCwgMzogSW1hZ2VPckxhYmVsRGltZW5zaW9ucywgNDogbnVtYmVyLCA1OiBBcnJheTwqPiwgNjogQXJyYXk8Kj59fSBSZXBsYXlJbWFnZU9yTGFiZWxBcmdzXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2UsIGltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdCk6IFR9IEZlYXR1cmVDYWxsYmFja1xuICovXG5cbi8qKlxuICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gKi9cblxudmFyIHRtcEV4dGVudCA9IGNyZWF0ZUVtcHR5KCk7XG4vKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cblxudmFyIHAxID0gW107XG4vKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cblxudmFyIHAyID0gW107XG4vKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cblxudmFyIHAzID0gW107XG4vKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gKi9cblxudmFyIHA0ID0gW107XG4vKipcbiAqIEBwYXJhbSB7UmVwbGF5SW1hZ2VPckxhYmVsQXJnc30gcmVwbGF5SW1hZ2VPckxhYmVsQXJncyBBcmd1bWVudHMgdG8gcmVwbGF5SW1hZ2VPckxhYmVsXG4gKiBAcmV0dXJuIHtCQm94fSBEZWNsdXR0ZXIgYmJveC5cbiAqL1xuXG5mdW5jdGlvbiBnZXREZWNsdXR0ZXJCb3gocmVwbGF5SW1hZ2VPckxhYmVsQXJncykge1xuICByZXR1cm4gcmVwbGF5SW1hZ2VPckxhYmVsQXJnc1szXS5kZWNsdXR0ZXJCb3g7XG59XG5cbnZhciBydGxSZWdFeCA9IG5ldyBSZWdFeHAoXG4vKiBlc2xpbnQtZGlzYWJsZSBwcmV0dGllci9wcmV0dGllciAqL1xuJ1snICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwNTkxKSArICctJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMDhmZikgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MGZiMWQpICsgJy0nICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDBmZGZmKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwZmU3MCkgKyAnLScgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MGZlZmMpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDEwODAwKSArICctJyArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgxMGZmZikgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MWU4MDApICsgJy0nICsgU3RyaW5nLmZyb21DaGFyQ29kZSgweDFlZmZmKSArICddJ1xuLyogZXNsaW50LWVuYWJsZSBwcmV0dGllci9wcmV0dGllciAqL1xuKTtcbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGV4dC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBhbGlnbiBBbGlnbm1lbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRleHQgYWxpZ25tZW50LlxuICovXG5cbmZ1bmN0aW9uIGhvcml6b250YWxUZXh0QWxpZ24odGV4dCwgYWxpZ24pIHtcbiAgaWYgKChhbGlnbiA9PT0gJ3N0YXJ0JyB8fCBhbGlnbiA9PT0gJ2VuZCcpICYmICFydGxSZWdFeC50ZXN0KHRleHQpKSB7XG4gICAgYWxpZ24gPSBhbGlnbiA9PT0gJ3N0YXJ0JyA/ICdsZWZ0JyA6ICdyaWdodCc7XG4gIH1cblxuICByZXR1cm4gVEVYVF9BTElHTlthbGlnbl07XG59XG5cbnZhciBFeGVjdXRvciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtib29sZWFufSBvdmVybGFwcyBUaGUgcmVwbGF5IGNhbiBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9uc30gaW5zdHJ1Y3Rpb25zIFRoZSBzZXJpYWxpemFibGUgaW5zdHJ1Y3Rpb25zXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc2l6ZS5qc1wiKS5TaXplfSByZW5kZXJCdWZmZXIgUmVuZGVyIGJ1ZmZlciAod2lkdGgvaGVpZ2h0KSBpbiBwaXhlbHMuXG4gICAqL1xuICBmdW5jdGlvbiBFeGVjdXRvcihyZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCBvdmVybGFwcywgaW5zdHJ1Y3Rpb25zLCByZW5kZXJCdWZmZXIpIHtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5vdmVybGFwcyA9IG92ZXJsYXBzO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5waXhlbFJhdGlvID0gcGl4ZWxSYXRpbztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQGNvbnN0XG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHRoaXMuYWxpZ25GaWxsXztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0FycmF5PCo+fVxuICAgICAqL1xuXG4gICAgdGhpcy5pbnN0cnVjdGlvbnMgPSBpbnN0cnVjdGlvbnMuaW5zdHJ1Y3Rpb25zO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMuY29vcmRpbmF0ZXMgPSBpbnN0cnVjdGlvbnMuY29vcmRpbmF0ZXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxudW1iZXIsaW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfEFycmF5PGltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj4+fVxuICAgICAqL1xuXG4gICAgdGhpcy5jb29yZGluYXRlQ2FjaGVfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZW5kZXJCdWZmZXJfID0gcmVuZGVyQnVmZmVyO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfVxuICAgICAqL1xuXG4gICAgdGhpcy5yZW5kZXJlZFRyYW5zZm9ybV8gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge0FycmF5PCo+fVxuICAgICAqL1xuXG4gICAgdGhpcy5oaXREZXRlY3Rpb25JbnN0cnVjdGlvbnMgPSBpbnN0cnVjdGlvbnMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLnZpZXdSb3RhdGlvbl8gPSAwO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkZpbGxTdGF0ZT59XG4gICAgICovXG5cbiAgICB0aGlzLmZpbGxTdGF0ZXMgPSBpbnN0cnVjdGlvbnMuZmlsbFN0YXRlcyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TdHJva2VTdGF0ZT59XG4gICAgICovXG5cbiAgICB0aGlzLnN0cm9rZVN0YXRlcyA9IGluc3RydWN0aW9ucy5zdHJva2VTdGF0ZXMgfHwge307XG4gICAgLyoqXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlPn1cbiAgICAgKi9cblxuICAgIHRoaXMudGV4dFN0YXRlcyA9IGluc3RydWN0aW9ucy50ZXh0U3RhdGVzIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIE9iamVjdDxzdHJpbmcsIG51bWJlcj4+fVxuICAgICAqL1xuXG4gICAgdGhpcy53aWR0aHNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkxhYmVsPn1cbiAgICAgKi9cblxuICAgIHRoaXMubGFiZWxzXyA9IHt9O1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCBUZXh0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGV4dEtleSBUZXh0IHN0eWxlIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGxLZXkgRmlsbCBzdHlsZSBrZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJva2VLZXkgU3Ryb2tlIHN0eWxlIGtleS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkxhYmVsfSBMYWJlbC5cbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuY3JlYXRlTGFiZWwgPSBmdW5jdGlvbiAodGV4dCwgdGV4dEtleSwgZmlsbEtleSwgc3Ryb2tlS2V5KSB7XG4gICAgdmFyIGtleSA9IHRleHQgKyB0ZXh0S2V5ICsgZmlsbEtleSArIHN0cm9rZUtleTtcblxuICAgIGlmICh0aGlzLmxhYmVsc19ba2V5XSkge1xuICAgICAgcmV0dXJuIHRoaXMubGFiZWxzX1trZXldO1xuICAgIH1cblxuICAgIHZhciBzdHJva2VTdGF0ZSA9IHN0cm9rZUtleSA/IHRoaXMuc3Ryb2tlU3RhdGVzW3N0cm9rZUtleV0gOiBudWxsO1xuICAgIHZhciBmaWxsU3RhdGUgPSBmaWxsS2V5ID8gdGhpcy5maWxsU3RhdGVzW2ZpbGxLZXldIDogbnVsbDtcbiAgICB2YXIgdGV4dFN0YXRlID0gdGhpcy50ZXh0U3RhdGVzW3RleHRLZXldO1xuICAgIHZhciBwaXhlbFJhdGlvID0gdGhpcy5waXhlbFJhdGlvO1xuICAgIHZhciBzY2FsZSA9IFt0ZXh0U3RhdGUuc2NhbGVbMF0gKiBwaXhlbFJhdGlvLCB0ZXh0U3RhdGUuc2NhbGVbMV0gKiBwaXhlbFJhdGlvXTtcbiAgICB2YXIgYWxpZ24gPSBob3Jpem9udGFsVGV4dEFsaWduKHRleHQsIHRleHRTdGF0ZS50ZXh0QWxpZ24gfHwgZGVmYXVsdFRleHRBbGlnbik7XG4gICAgdmFyIHN0cm9rZVdpZHRoID0gc3Ryb2tlS2V5ICYmIHN0cm9rZVN0YXRlLmxpbmVXaWR0aCA/IHN0cm9rZVN0YXRlLmxpbmVXaWR0aCA6IDA7XG4gICAgdmFyIGxpbmVzID0gdGV4dC5zcGxpdCgnXFxuJyk7XG4gICAgdmFyIG51bUxpbmVzID0gbGluZXMubGVuZ3RoO1xuICAgIHZhciB3aWR0aHMgPSBbXTtcbiAgICB2YXIgd2lkdGggPSBtZWFzdXJlVGV4dFdpZHRocyh0ZXh0U3RhdGUuZm9udCwgbGluZXMsIHdpZHRocyk7XG4gICAgdmFyIGxpbmVIZWlnaHQgPSBtZWFzdXJlVGV4dEhlaWdodCh0ZXh0U3RhdGUuZm9udCk7XG4gICAgdmFyIGhlaWdodCA9IGxpbmVIZWlnaHQgKiBudW1MaW5lcztcbiAgICB2YXIgcmVuZGVyV2lkdGggPSB3aWR0aCArIHN0cm9rZVdpZHRoO1xuICAgIHZhciBjb250ZXh0SW5zdHJ1Y3Rpb25zID0gW107IC8vIG1ha2UgY2FudmFzIDIgcGl4ZWxzIHdpZGVyIHRvIGFjY291bnQgZm9yIGl0YWxpYyB0ZXh0IHdpZHRoIG1lYXN1cmVtZW50IGVycm9yc1xuXG4gICAgdmFyIHcgPSAocmVuZGVyV2lkdGggKyAyKSAqIHNjYWxlWzBdO1xuICAgIHZhciBoID0gKGhlaWdodCArIHN0cm9rZVdpZHRoKSAqIHNjYWxlWzFdO1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkxhYmVsfSAqL1xuXG4gICAgdmFyIGxhYmVsID0ge1xuICAgICAgd2lkdGg6IHcgPCAwID8gTWF0aC5mbG9vcih3KSA6IE1hdGguY2VpbCh3KSxcbiAgICAgIGhlaWdodDogaCA8IDAgPyBNYXRoLmZsb29yKGgpIDogTWF0aC5jZWlsKGgpLFxuICAgICAgY29udGV4dEluc3RydWN0aW9uczogY29udGV4dEluc3RydWN0aW9uc1xuICAgIH07XG5cbiAgICBpZiAoc2NhbGVbMF0gIT0gMSB8fCBzY2FsZVsxXSAhPSAxKSB7XG4gICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ3NjYWxlJywgc2NhbGUpO1xuICAgIH1cblxuICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnZm9udCcsIHRleHRTdGF0ZS5mb250KTtcblxuICAgIGlmIChzdHJva2VLZXkpIHtcbiAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnc3Ryb2tlU3R5bGUnLCBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZSk7XG4gICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ2xpbmVXaWR0aCcsIHN0cm9rZVdpZHRoKTtcbiAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnbGluZUNhcCcsIHN0cm9rZVN0YXRlLmxpbmVDYXApO1xuICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdsaW5lSm9pbicsIHN0cm9rZVN0YXRlLmxpbmVKb2luKTtcbiAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnbWl0ZXJMaW1pdCcsIHN0cm9rZVN0YXRlLm1pdGVyTGltaXQpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblxuICAgICAgdmFyIENvbnRleHQgPSBXT1JLRVJfT0ZGU0NSRUVOX0NBTlZBUyA/IE9mZnNjcmVlbkNhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCA6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRDtcblxuICAgICAgaWYgKENvbnRleHQucHJvdG90eXBlLnNldExpbmVEYXNoKSB7XG4gICAgICAgIGNvbnRleHRJbnN0cnVjdGlvbnMucHVzaCgnc2V0TGluZURhc2gnLCBbc3Ryb2tlU3RhdGUubGluZURhc2hdKTtcbiAgICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdsaW5lRGFzaE9mZnNldCcsIHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmlsbEtleSkge1xuICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdmaWxsU3R5bGUnLCBmaWxsU3RhdGUuZmlsbFN0eWxlKTtcbiAgICB9XG5cbiAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ3RleHRCYXNlbGluZScsICdtaWRkbGUnKTtcbiAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ3RleHRBbGlnbicsICdjZW50ZXInKTtcbiAgICB2YXIgbGVmdFJpZ2h0ID0gMC41IC0gYWxpZ247XG4gICAgdmFyIHggPSBhbGlnbiAqIHJlbmRlcldpZHRoICsgbGVmdFJpZ2h0ICogc3Ryb2tlV2lkdGg7XG4gICAgdmFyIGk7XG5cbiAgICBpZiAoc3Ryb2tlS2V5KSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtTGluZXM7ICsraSkge1xuICAgICAgICBjb250ZXh0SW5zdHJ1Y3Rpb25zLnB1c2goJ3N0cm9rZVRleHQnLCBbbGluZXNbaV0sIHggKyBsZWZ0UmlnaHQgKiB3aWR0aHNbaV0sIDAuNSAqIChzdHJva2VXaWR0aCArIGxpbmVIZWlnaHQpICsgaSAqIGxpbmVIZWlnaHRdKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmlsbEtleSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IG51bUxpbmVzOyArK2kpIHtcbiAgICAgICAgY29udGV4dEluc3RydWN0aW9ucy5wdXNoKCdmaWxsVGV4dCcsIFtsaW5lc1tpXSwgeCArIGxlZnRSaWdodCAqIHdpZHRoc1tpXSwgMC41ICogKHN0cm9rZVdpZHRoICsgbGluZUhlaWdodCkgKyBpICogbGluZUhlaWdodF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubGFiZWxzX1trZXldID0gbGFiZWw7XG4gICAgcmV0dXJuIGxhYmVsO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHAxIDFzdCBwb2ludCBvZiB0aGUgYmFja2dyb3VuZCBib3guXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBwMiAybmQgcG9pbnQgb2YgdGhlIGJhY2tncm91bmQgYm94LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcDMgM3JkIHBvaW50IG9mIHRoZSBiYWNrZ3JvdW5kIGJveC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHA0IDR0aCBwb2ludCBvZiB0aGUgYmFja2dyb3VuZCBib3guXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGZpbGxJbnN0cnVjdGlvbiBGaWxsIGluc3RydWN0aW9uLlxuICAgKiBAcGFyYW0ge0FycmF5PCo+fSBzdHJva2VJbnN0cnVjdGlvbiBTdHJva2UgaW5zdHJ1Y3Rpb24uXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLnJlcGxheVRleHRCYWNrZ3JvdW5kXyA9IGZ1bmN0aW9uIChjb250ZXh0LCBwMSwgcDIsIHAzLCBwNCwgZmlsbEluc3RydWN0aW9uLCBzdHJva2VJbnN0cnVjdGlvbikge1xuICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgY29udGV4dC5tb3ZlVG8uYXBwbHkoY29udGV4dCwgcDEpO1xuICAgIGNvbnRleHQubGluZVRvLmFwcGx5KGNvbnRleHQsIHAyKTtcbiAgICBjb250ZXh0LmxpbmVUby5hcHBseShjb250ZXh0LCBwMyk7XG4gICAgY29udGV4dC5saW5lVG8uYXBwbHkoY29udGV4dCwgcDQpO1xuICAgIGNvbnRleHQubGluZVRvLmFwcGx5KGNvbnRleHQsIHAxKTtcblxuICAgIGlmIChmaWxsSW5zdHJ1Y3Rpb24pIHtcbiAgICAgIHRoaXMuYWxpZ25GaWxsXyA9XG4gICAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovXG4gICAgICBmaWxsSW5zdHJ1Y3Rpb25bMl07XG4gICAgICB0aGlzLmZpbGxfKGNvbnRleHQpO1xuICAgIH1cblxuICAgIGlmIChzdHJva2VJbnN0cnVjdGlvbikge1xuICAgICAgdGhpcy5zZXRTdHJva2VTdHlsZV8oY29udGV4dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8Kj59ICovXG4gICAgICBzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaGVldFdpZHRoIFdpZHRoIG9mIHRoZSBzcHJpdGUgc2hlZXQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaGVldEhlaWdodCBIZWlnaHQgb2YgdGhlIHNwcml0ZSBzaGVldC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNlbnRlclggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNlbnRlclkgWS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFdpZHRoLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IEhlaWdodC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFuY2hvclggQW5jaG9yIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhbmNob3JZIEFuY2hvciBZLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3JpZ2luWCBPcmlnaW4gWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9yaWdpblkgT3JpZ2luIFkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByb3RhdGlvbiBSb3RhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zaXplLmpzXCIpLlNpemV9IHNjYWxlIFNjYWxlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNuYXBUb1BpeGVsIFNuYXAgdG8gcGl4ZWwuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gcGFkZGluZyBQYWRkaW5nLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpbGxTdHJva2UgQmFja2dyb3VuZCBmaWxsIG9yIHN0cm9rZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEByZXR1cm4ge0ltYWdlT3JMYWJlbERpbWVuc2lvbnN9IERpbWVuc2lvbnMgZm9yIHBvc2l0aW9uaW5nIGFuZCBkZWNsdXR0ZXJpbmcgdGhlIGltYWdlIG9yIGxhYmVsLlxuICAgKi9cblxuXG4gIEV4ZWN1dG9yLnByb3RvdHlwZS5jYWxjdWxhdGVJbWFnZU9yTGFiZWxEaW1lbnNpb25zXyA9IGZ1bmN0aW9uIChzaGVldFdpZHRoLCBzaGVldEhlaWdodCwgY2VudGVyWCwgY2VudGVyWSwgd2lkdGgsIGhlaWdodCwgYW5jaG9yWCwgYW5jaG9yWSwgb3JpZ2luWCwgb3JpZ2luWSwgcm90YXRpb24sIHNjYWxlLCBzbmFwVG9QaXhlbCwgcGFkZGluZywgZmlsbFN0cm9rZSwgZmVhdHVyZSkge1xuICAgIGFuY2hvclggKj0gc2NhbGVbMF07XG4gICAgYW5jaG9yWSAqPSBzY2FsZVsxXTtcbiAgICB2YXIgeCA9IGNlbnRlclggLSBhbmNob3JYO1xuICAgIHZhciB5ID0gY2VudGVyWSAtIGFuY2hvclk7XG4gICAgdmFyIHcgPSB3aWR0aCArIG9yaWdpblggPiBzaGVldFdpZHRoID8gc2hlZXRXaWR0aCAtIG9yaWdpblggOiB3aWR0aDtcbiAgICB2YXIgaCA9IGhlaWdodCArIG9yaWdpblkgPiBzaGVldEhlaWdodCA/IHNoZWV0SGVpZ2h0IC0gb3JpZ2luWSA6IGhlaWdodDtcbiAgICB2YXIgYm94VyA9IHBhZGRpbmdbM10gKyB3ICogc2NhbGVbMF0gKyBwYWRkaW5nWzFdO1xuICAgIHZhciBib3hIID0gcGFkZGluZ1swXSArIGggKiBzY2FsZVsxXSArIHBhZGRpbmdbMl07XG4gICAgdmFyIGJveFggPSB4IC0gcGFkZGluZ1szXTtcbiAgICB2YXIgYm94WSA9IHkgLSBwYWRkaW5nWzBdO1xuXG4gICAgaWYgKGZpbGxTdHJva2UgfHwgcm90YXRpb24gIT09IDApIHtcbiAgICAgIHAxWzBdID0gYm94WDtcbiAgICAgIHA0WzBdID0gYm94WDtcbiAgICAgIHAxWzFdID0gYm94WTtcbiAgICAgIHAyWzFdID0gYm94WTtcbiAgICAgIHAyWzBdID0gYm94WCArIGJveFc7XG4gICAgICBwM1swXSA9IHAyWzBdO1xuICAgICAgcDNbMV0gPSBib3hZICsgYm94SDtcbiAgICAgIHA0WzFdID0gcDNbMV07XG4gICAgfVxuXG4gICAgdmFyIHRyYW5zZm9ybTtcblxuICAgIGlmIChyb3RhdGlvbiAhPT0gMCkge1xuICAgICAgdHJhbnNmb3JtID0gY29tcG9zZVRyYW5zZm9ybShjcmVhdGVUcmFuc2Zvcm0oKSwgY2VudGVyWCwgY2VudGVyWSwgMSwgMSwgcm90YXRpb24sIC1jZW50ZXJYLCAtY2VudGVyWSk7XG4gICAgICBhcHBseVRyYW5zZm9ybSh0cmFuc2Zvcm0sIHAxKTtcbiAgICAgIGFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybSwgcDIpO1xuICAgICAgYXBwbHlUcmFuc2Zvcm0odHJhbnNmb3JtLCBwMyk7XG4gICAgICBhcHBseVRyYW5zZm9ybSh0cmFuc2Zvcm0sIHA0KTtcbiAgICAgIGNyZWF0ZU9yVXBkYXRlKE1hdGgubWluKHAxWzBdLCBwMlswXSwgcDNbMF0sIHA0WzBdKSwgTWF0aC5taW4ocDFbMV0sIHAyWzFdLCBwM1sxXSwgcDRbMV0pLCBNYXRoLm1heChwMVswXSwgcDJbMF0sIHAzWzBdLCBwNFswXSksIE1hdGgubWF4KHAxWzFdLCBwMlsxXSwgcDNbMV0sIHA0WzFdKSwgdG1wRXh0ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3JlYXRlT3JVcGRhdGUoTWF0aC5taW4oYm94WCwgYm94WCArIGJveFcpLCBNYXRoLm1pbihib3hZLCBib3hZICsgYm94SCksIE1hdGgubWF4KGJveFgsIGJveFggKyBib3hXKSwgTWF0aC5tYXgoYm94WSwgYm94WSArIGJveEgpLCB0bXBFeHRlbnQpO1xuICAgIH1cblxuICAgIGlmIChzbmFwVG9QaXhlbCkge1xuICAgICAgeCA9IE1hdGgucm91bmQoeCk7XG4gICAgICB5ID0gTWF0aC5yb3VuZCh5KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZHJhd0ltYWdlWDogeCxcbiAgICAgIGRyYXdJbWFnZVk6IHksXG4gICAgICBkcmF3SW1hZ2VXOiB3LFxuICAgICAgZHJhd0ltYWdlSDogaCxcbiAgICAgIG9yaWdpblg6IG9yaWdpblgsXG4gICAgICBvcmlnaW5ZOiBvcmlnaW5ZLFxuICAgICAgZGVjbHV0dGVyQm94OiB7XG4gICAgICAgIG1pblg6IHRtcEV4dGVudFswXSxcbiAgICAgICAgbWluWTogdG1wRXh0ZW50WzFdLFxuICAgICAgICBtYXhYOiB0bXBFeHRlbnRbMl0sXG4gICAgICAgIG1heFk6IHRtcEV4dGVudFszXSxcbiAgICAgICAgdmFsdWU6IGZlYXR1cmVcbiAgICAgIH0sXG4gICAgICBjYW52YXNUcmFuc2Zvcm06IHRyYW5zZm9ybSxcbiAgICAgIHNjYWxlOiBzY2FsZVxuICAgIH07XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gY29udGV4dFNjYWxlIFNjYWxlIG9mIHRoZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5MYWJlbHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IGltYWdlT3JMYWJlbCBJbWFnZS5cbiAgICogQHBhcmFtIHtJbWFnZU9yTGFiZWxEaW1lbnNpb25zfSBkaW1lbnNpb25zIERpbWVuc2lvbnMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gICAqIEBwYXJhbSB7QXJyYXk8Kj59IGZpbGxJbnN0cnVjdGlvbiBGaWxsIGluc3RydWN0aW9uLlxuICAgKiBAcGFyYW0ge0FycmF5PCo+fSBzdHJva2VJbnN0cnVjdGlvbiBTdHJva2UgaW5zdHJ1Y3Rpb24uXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBpbWFnZSBvciBsYWJlbCB3YXMgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLnJlcGxheUltYWdlT3JMYWJlbF8gPSBmdW5jdGlvbiAoY29udGV4dCwgY29udGV4dFNjYWxlLCBpbWFnZU9yTGFiZWwsIGRpbWVuc2lvbnMsIG9wYWNpdHksIGZpbGxJbnN0cnVjdGlvbiwgc3Ryb2tlSW5zdHJ1Y3Rpb24pIHtcbiAgICB2YXIgZmlsbFN0cm9rZSA9ICEhKGZpbGxJbnN0cnVjdGlvbiB8fCBzdHJva2VJbnN0cnVjdGlvbik7XG4gICAgdmFyIGJveCA9IGRpbWVuc2lvbnMuZGVjbHV0dGVyQm94O1xuICAgIHZhciBjYW52YXMgPSBjb250ZXh0LmNhbnZhcztcbiAgICB2YXIgc3Ryb2tlUGFkZGluZyA9IHN0cm9rZUluc3RydWN0aW9uID8gc3Ryb2tlSW5zdHJ1Y3Rpb25bMl0gKiBkaW1lbnNpb25zLnNjYWxlWzBdIC8gMiA6IDA7XG4gICAgdmFyIGludGVyc2VjdHMgPSBib3gubWluWCAtIHN0cm9rZVBhZGRpbmcgPD0gY2FudmFzLndpZHRoIC8gY29udGV4dFNjYWxlICYmIGJveC5tYXhYICsgc3Ryb2tlUGFkZGluZyA+PSAwICYmIGJveC5taW5ZIC0gc3Ryb2tlUGFkZGluZyA8PSBjYW52YXMuaGVpZ2h0IC8gY29udGV4dFNjYWxlICYmIGJveC5tYXhZICsgc3Ryb2tlUGFkZGluZyA+PSAwO1xuXG4gICAgaWYgKGludGVyc2VjdHMpIHtcbiAgICAgIGlmIChmaWxsU3Ryb2tlKSB7XG4gICAgICAgIHRoaXMucmVwbGF5VGV4dEJhY2tncm91bmRfKGNvbnRleHQsIHAxLCBwMiwgcDMsIHA0LFxuICAgICAgICAvKiogQHR5cGUge0FycmF5PCo+fSAqL1xuICAgICAgICBmaWxsSW5zdHJ1Y3Rpb24sXG4gICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8Kj59ICovXG4gICAgICAgIHN0cm9rZUluc3RydWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgZHJhd0ltYWdlT3JMYWJlbChjb250ZXh0LCBkaW1lbnNpb25zLmNhbnZhc1RyYW5zZm9ybSwgb3BhY2l0eSwgaW1hZ2VPckxhYmVsLCBkaW1lbnNpb25zLm9yaWdpblgsIGRpbWVuc2lvbnMub3JpZ2luWSwgZGltZW5zaW9ucy5kcmF3SW1hZ2VXLCBkaW1lbnNpb25zLmRyYXdJbWFnZUgsIGRpbWVuc2lvbnMuZHJhd0ltYWdlWCwgZGltZW5zaW9ucy5kcmF3SW1hZ2VZLCBkaW1lbnNpb25zLnNjYWxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLmZpbGxfID0gZnVuY3Rpb24gKGNvbnRleHQpIHtcbiAgICBpZiAodGhpcy5hbGlnbkZpbGxfKSB7XG4gICAgICB2YXIgb3JpZ2luXzEgPSBhcHBseVRyYW5zZm9ybSh0aGlzLnJlbmRlcmVkVHJhbnNmb3JtXywgWzAsIDBdKTtcbiAgICAgIHZhciByZXBlYXRTaXplID0gNTEyICogdGhpcy5waXhlbFJhdGlvO1xuICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICBjb250ZXh0LnRyYW5zbGF0ZShvcmlnaW5fMVswXSAlIHJlcGVhdFNpemUsIG9yaWdpbl8xWzFdICUgcmVwZWF0U2l6ZSk7XG4gICAgICBjb250ZXh0LnJvdGF0ZSh0aGlzLnZpZXdSb3RhdGlvbl8pO1xuICAgIH1cblxuICAgIGNvbnRleHQuZmlsbCgpO1xuXG4gICAgaWYgKHRoaXMuYWxpZ25GaWxsXykge1xuICAgICAgY29udGV4dC5yZXN0b3JlKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtBcnJheTwqPn0gaW5zdHJ1Y3Rpb24gSW5zdHJ1Y3Rpb24uXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLnNldFN0cm9rZVN0eWxlXyA9IGZ1bmN0aW9uIChjb250ZXh0LCBpbnN0cnVjdGlvbikge1xuICAgIGNvbnRleHRbJ3N0cm9rZVN0eWxlJ10gPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29sb3JsaWtlLmpzXCIpLkNvbG9yTGlrZX0gKi9cbiAgICBpbnN0cnVjdGlvblsxXTtcbiAgICBjb250ZXh0LmxpbmVXaWR0aCA9XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgaW5zdHJ1Y3Rpb25bMl07XG4gICAgY29udGV4dC5saW5lQ2FwID1cbiAgICAvKiogQHR5cGUge0NhbnZhc0xpbmVDYXB9ICovXG4gICAgaW5zdHJ1Y3Rpb25bM107XG4gICAgY29udGV4dC5saW5lSm9pbiA9XG4gICAgLyoqIEB0eXBlIHtDYW52YXNMaW5lSm9pbn0gKi9cbiAgICBpbnN0cnVjdGlvbls0XTtcbiAgICBjb250ZXh0Lm1pdGVyTGltaXQgPVxuICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgIGluc3RydWN0aW9uWzVdO1xuXG4gICAgaWYgKGNvbnRleHQuc2V0TGluZURhc2gpIHtcbiAgICAgIGNvbnRleHQubGluZURhc2hPZmZzZXQgPVxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICBpbnN0cnVjdGlvbls3XTtcbiAgICAgIGNvbnRleHQuc2V0TGluZURhc2goXG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICBpbnN0cnVjdGlvbls2XSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gZHJhdy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRLZXkgVGhlIGtleSBvZiB0aGUgdGV4dCBzdGF0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cm9rZUtleSBUaGUga2V5IGZvciB0aGUgc3Ryb2tlIHN0YXRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsbEtleSBUaGUga2V5IGZvciB0aGUgZmlsbCBzdGF0ZS5cbiAgICogQHJldHVybiB7e2xhYmVsOiBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuTGFiZWwsIGFuY2hvclg6IG51bWJlciwgYW5jaG9yWTogbnVtYmVyfX0gVGhlIHRleHQgaW1hZ2UgYW5kIGl0cyBhbmNob3IuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLmRyYXdMYWJlbFdpdGhQb2ludFBsYWNlbWVudF8gPSBmdW5jdGlvbiAodGV4dCwgdGV4dEtleSwgc3Ryb2tlS2V5LCBmaWxsS2V5KSB7XG4gICAgdmFyIHRleHRTdGF0ZSA9IHRoaXMudGV4dFN0YXRlc1t0ZXh0S2V5XTtcbiAgICB2YXIgbGFiZWwgPSB0aGlzLmNyZWF0ZUxhYmVsKHRleHQsIHRleHRLZXksIGZpbGxLZXksIHN0cm9rZUtleSk7XG4gICAgdmFyIHN0cm9rZVN0YXRlID0gdGhpcy5zdHJva2VTdGF0ZXNbc3Ryb2tlS2V5XTtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IHRoaXMucGl4ZWxSYXRpbztcbiAgICB2YXIgYWxpZ24gPSBob3Jpem9udGFsVGV4dEFsaWduKHRleHQsIHRleHRTdGF0ZS50ZXh0QWxpZ24gfHwgZGVmYXVsdFRleHRBbGlnbik7XG4gICAgdmFyIGJhc2VsaW5lID0gVEVYVF9BTElHTlt0ZXh0U3RhdGUudGV4dEJhc2VsaW5lIHx8IGRlZmF1bHRUZXh0QmFzZWxpbmVdO1xuICAgIHZhciBzdHJva2VXaWR0aCA9IHN0cm9rZVN0YXRlICYmIHN0cm9rZVN0YXRlLmxpbmVXaWR0aCA/IHN0cm9rZVN0YXRlLmxpbmVXaWR0aCA6IDA7IC8vIFJlbW92ZSB0aGUgMiBwaXhlbHMgd2UgYWRkZWQgaW4gY3JlYXRlTGFiZWwoKSBmb3IgdGhlIGFuY2hvclxuXG4gICAgdmFyIHdpZHRoID0gbGFiZWwud2lkdGggLyBwaXhlbFJhdGlvIC0gMiAqIHRleHRTdGF0ZS5zY2FsZVswXTtcbiAgICB2YXIgYW5jaG9yWCA9IGFsaWduICogd2lkdGggKyAyICogKDAuNSAtIGFsaWduKSAqIHN0cm9rZVdpZHRoO1xuICAgIHZhciBhbmNob3JZID0gYmFzZWxpbmUgKiBsYWJlbC5oZWlnaHQgLyBwaXhlbFJhdGlvICsgMiAqICgwLjUgLSBiYXNlbGluZSkgKiBzdHJva2VXaWR0aDtcbiAgICByZXR1cm4ge1xuICAgICAgbGFiZWw6IGxhYmVsLFxuICAgICAgYW5jaG9yWDogYW5jaG9yWCxcbiAgICAgIGFuY2hvclk6IGFuY2hvcllcbiAgICB9O1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGNvbnRleHRTY2FsZSBTY2FsZSBvZiB0aGUgY29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge0FycmF5PCo+fSBpbnN0cnVjdGlvbnMgSW5zdHJ1Y3Rpb25zIGFycmF5LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNuYXBUb1BpeGVsIFNuYXAgcG9pbnQgc3ltYm9scyBhbmQgdGV4dCB0byBpbnRlZ2VyIHBpeGVscy5cbiAgICogQHBhcmFtIHtGZWF0dXJlQ2FsbGJhY2s8VD49fSBvcHRfZmVhdHVyZUNhbGxiYWNrIEZlYXR1cmUgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9oaXRFeHRlbnQgT25seSBjaGVja1xuICAgKiAgICAgZmVhdHVyZXMgdGhhdCBpbnRlcnNlY3QgdGhpcyBleHRlbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwicmJ1c2hcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJUcmVlIERlY2x1dHRlciB0cmVlLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIEV4ZWN1dG9yLnByb3RvdHlwZS5leGVjdXRlXyA9IGZ1bmN0aW9uIChjb250ZXh0LCBjb250ZXh0U2NhbGUsIHRyYW5zZm9ybSwgaW5zdHJ1Y3Rpb25zLCBzbmFwVG9QaXhlbCwgb3B0X2ZlYXR1cmVDYWxsYmFjaywgb3B0X2hpdEV4dGVudCwgb3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgdmFyIHBpeGVsQ29vcmRpbmF0ZXM7XG5cbiAgICBpZiAodGhpcy5waXhlbENvb3JkaW5hdGVzXyAmJiBlcXVhbHModHJhbnNmb3JtLCB0aGlzLnJlbmRlcmVkVHJhbnNmb3JtXykpIHtcbiAgICAgIHBpeGVsQ29vcmRpbmF0ZXMgPSB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMucGl4ZWxDb29yZGluYXRlc18pIHtcbiAgICAgICAgdGhpcy5waXhlbENvb3JkaW5hdGVzXyA9IFtdO1xuICAgICAgfVxuXG4gICAgICBwaXhlbENvb3JkaW5hdGVzID0gdHJhbnNmb3JtMkQodGhpcy5jb29yZGluYXRlcywgMCwgdGhpcy5jb29yZGluYXRlcy5sZW5ndGgsIDIsIHRyYW5zZm9ybSwgdGhpcy5waXhlbENvb3JkaW5hdGVzXyk7XG4gICAgICB0cmFuc2Zvcm1TZXRGcm9tQXJyYXkodGhpcy5yZW5kZXJlZFRyYW5zZm9ybV8sIHRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgdmFyIGkgPSAwOyAvLyBpbnN0cnVjdGlvbiBpbmRleFxuXG4gICAgdmFyIGlpID0gaW5zdHJ1Y3Rpb25zLmxlbmd0aDsgLy8gZW5kIG9mIGluc3RydWN0aW9uc1xuXG4gICAgdmFyIGQgPSAwOyAvLyBkYXRhIGluZGV4XG5cbiAgICB2YXIgZGQ7IC8vIGVuZCBvZiBwZXItaW5zdHJ1Y3Rpb24gZGF0YVxuXG4gICAgdmFyIGFuY2hvclgsIGFuY2hvclksIHByZXZYLCBwcmV2WSwgcm91bmRYLCByb3VuZFksIGltYWdlLCB0ZXh0LCB0ZXh0S2V5LCBzdHJva2VLZXksIGZpbGxLZXk7XG4gICAgdmFyIHBlbmRpbmdGaWxsID0gMDtcbiAgICB2YXIgcGVuZGluZ1N0cm9rZSA9IDA7XG4gICAgdmFyIGxhc3RGaWxsSW5zdHJ1Y3Rpb24gPSBudWxsO1xuICAgIHZhciBsYXN0U3Ryb2tlSW5zdHJ1Y3Rpb24gPSBudWxsO1xuICAgIHZhciBjb29yZGluYXRlQ2FjaGUgPSB0aGlzLmNvb3JkaW5hdGVDYWNoZV87XG4gICAgdmFyIHZpZXdSb3RhdGlvbiA9IHRoaXMudmlld1JvdGF0aW9uXztcbiAgICB2YXIgdmlld1JvdGF0aW9uRnJvbVRyYW5zZm9ybSA9IE1hdGgucm91bmQoTWF0aC5hdGFuMigtdHJhbnNmb3JtWzFdLCB0cmFuc2Zvcm1bMF0pICogMWUxMikgLyAxZTEyO1xuICAgIHZhciBzdGF0ZSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9yZW5kZXIuanNcIikuU3RhdGV9ICovXG4gICAge1xuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIHBpeGVsUmF0aW86IHRoaXMucGl4ZWxSYXRpbyxcbiAgICAgIHJlc29sdXRpb246IHRoaXMucmVzb2x1dGlvbixcbiAgICAgIHJvdGF0aW9uOiB2aWV3Um90YXRpb25cbiAgICB9OyAvLyBXaGVuIHRoZSBiYXRjaCBzaXplIGdldHMgdG9vIGJpZywgcGVyZm9ybWFuY2UgZGVjcmVhc2VzLiAyMDAgaXMgYSBnb29kXG4gICAgLy8gYmFsYW5jZSBiZXR3ZWVuIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBmaWxsL3N0cm9rZSBpbnN0cnVjdGlvbnMuXG5cbiAgICB2YXIgYmF0Y2hTaXplID0gdGhpcy5pbnN0cnVjdGlvbnMgIT0gaW5zdHJ1Y3Rpb25zIHx8IHRoaXMub3ZlcmxhcHMgPyAwIDogMjAwO1xuICAgIHZhclxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gKi9cbiAgICBmZWF0dXJlO1xuICAgIHZhciB4LCB5LCBjdXJyZW50R2VvbWV0cnk7XG5cbiAgICB3aGlsZSAoaSA8IGlpKSB7XG4gICAgICB2YXIgaW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbnNbaV07XG4gICAgICB2YXIgdHlwZSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vSW5zdHJ1Y3Rpb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGluc3RydWN0aW9uWzBdO1xuXG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5CRUdJTl9HRU9NRVRSWTpcbiAgICAgICAgICBmZWF0dXJlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgY3VycmVudEdlb21ldHJ5ID0gaW5zdHJ1Y3Rpb25bM107XG5cbiAgICAgICAgICBpZiAoIWZlYXR1cmUuZ2V0R2VvbWV0cnkoKSkge1xuICAgICAgICAgICAgaSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzJdO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3B0X2hpdEV4dGVudCAhPT0gdW5kZWZpbmVkICYmICFpbnRlcnNlY3RzKG9wdF9oaXRFeHRlbnQsIGN1cnJlbnRHZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgICAgICAgIGkgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsyXSArIDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICsraTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkJFR0lOX1BBVEg6XG4gICAgICAgICAgaWYgKHBlbmRpbmdGaWxsID4gYmF0Y2hTaXplKSB7XG4gICAgICAgICAgICB0aGlzLmZpbGxfKGNvbnRleHQpO1xuICAgICAgICAgICAgcGVuZGluZ0ZpbGwgPSAwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwZW5kaW5nU3Ryb2tlID4gYmF0Y2hTaXplKSB7XG4gICAgICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgICAgICAgICAgcGVuZGluZ1N0cm9rZSA9IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFwZW5kaW5nRmlsbCAmJiAhcGVuZGluZ1N0cm9rZSkge1xuICAgICAgICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICAgICAgICAgIHByZXZYID0gTmFOO1xuICAgICAgICAgICAgcHJldlkgPSBOYU47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uQ0lSQ0xFOlxuICAgICAgICAgIGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgIHZhciB4MSA9IHBpeGVsQ29vcmRpbmF0ZXNbZF07XG4gICAgICAgICAgdmFyIHkxID0gcGl4ZWxDb29yZGluYXRlc1tkICsgMV07XG4gICAgICAgICAgdmFyIHgyID0gcGl4ZWxDb29yZGluYXRlc1tkICsgMl07XG4gICAgICAgICAgdmFyIHkyID0gcGl4ZWxDb29yZGluYXRlc1tkICsgM107XG4gICAgICAgICAgdmFyIGR4ID0geDIgLSB4MTtcbiAgICAgICAgICB2YXIgZHkgPSB5MiAtIHkxO1xuICAgICAgICAgIHZhciByID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgICAgICAgICBjb250ZXh0Lm1vdmVUbyh4MSArIHIsIHkxKTtcbiAgICAgICAgICBjb250ZXh0LmFyYyh4MSwgeTEsIHIsIDAsIDIgKiBNYXRoLlBJLCB0cnVlKTtcbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5DTE9TRV9QQVRIOlxuICAgICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uQ1VTVE9NOlxuICAgICAgICAgIGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgIGRkID0gaW5zdHJ1Y3Rpb25bMl07XG4gICAgICAgICAgdmFyIGdlb21ldHJ5ID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblszXTtcbiAgICAgICAgICB2YXIgcmVuZGVyZXIgPSBpbnN0cnVjdGlvbls0XTtcbiAgICAgICAgICB2YXIgZm4gPSBpbnN0cnVjdGlvbi5sZW5ndGggPT0gNiA/IGluc3RydWN0aW9uWzVdIDogdW5kZWZpbmVkO1xuICAgICAgICAgIHN0YXRlLmdlb21ldHJ5ID0gZ2VvbWV0cnk7XG4gICAgICAgICAgc3RhdGUuZmVhdHVyZSA9IGZlYXR1cmU7XG5cbiAgICAgICAgICBpZiAoIShpIGluIGNvb3JkaW5hdGVDYWNoZSkpIHtcbiAgICAgICAgICAgIGNvb3JkaW5hdGVDYWNoZVtpXSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBjb29yZHMgPSBjb29yZGluYXRlQ2FjaGVbaV07XG5cbiAgICAgICAgICBpZiAoZm4pIHtcbiAgICAgICAgICAgIGZuKHBpeGVsQ29vcmRpbmF0ZXMsIGQsIGRkLCAyLCBjb29yZHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb29yZHNbMF0gPSBwaXhlbENvb3JkaW5hdGVzW2RdO1xuICAgICAgICAgICAgY29vcmRzWzFdID0gcGl4ZWxDb29yZGluYXRlc1tkICsgMV07XG4gICAgICAgICAgICBjb29yZHMubGVuZ3RoID0gMjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZW5kZXJlcihjb29yZHMsIHN0YXRlKTtcbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5EUkFXX0lNQUdFOlxuICAgICAgICAgIGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgIGRkID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsyXTtcbiAgICAgICAgICBpbWFnZSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bM107IC8vIFJlbWFpbmluZyBhcmd1bWVudHMgaW4gRFJBV19JTUFHRSBhcmUgaW4gYWxwaGFiZXRpY2FsIG9yZGVyXG5cbiAgICAgICAgICBhbmNob3JYID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls0XTtcbiAgICAgICAgICBhbmNob3JZID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls1XTtcbiAgICAgICAgICB2YXIgaGVpZ2h0ID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls2XTtcbiAgICAgICAgICB2YXIgb3BhY2l0eSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bN107XG4gICAgICAgICAgdmFyIG9yaWdpblggPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzhdO1xuICAgICAgICAgIHZhciBvcmlnaW5ZID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls5XTtcbiAgICAgICAgICB2YXIgcm90YXRlV2l0aFZpZXcgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxMF07XG4gICAgICAgICAgdmFyIHJvdGF0aW9uID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxMV07XG4gICAgICAgICAgdmFyIHNjYWxlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZX0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxMl07XG4gICAgICAgICAgdmFyIHdpZHRoID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxM107XG4gICAgICAgICAgdmFyIGRlY2x1dHRlckltYWdlV2l0aFRleHQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHR9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMTRdO1xuXG4gICAgICAgICAgaWYgKCFpbWFnZSAmJiBpbnN0cnVjdGlvbi5sZW5ndGggPj0gMTkpIHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBsYWJlbCBpbWFnZXNcbiAgICAgICAgICAgIHRleHQgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxOF07XG4gICAgICAgICAgICB0ZXh0S2V5ID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMTldO1xuICAgICAgICAgICAgc3Ryb2tlS2V5ID1cbiAgICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMjBdO1xuICAgICAgICAgICAgZmlsbEtleSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzIxXTtcbiAgICAgICAgICAgIHZhciBsYWJlbFdpdGhBbmNob3IgPSB0aGlzLmRyYXdMYWJlbFdpdGhQb2ludFBsYWNlbWVudF8odGV4dCwgdGV4dEtleSwgc3Ryb2tlS2V5LCBmaWxsS2V5KTtcbiAgICAgICAgICAgIGltYWdlID0gbGFiZWxXaXRoQW5jaG9yLmxhYmVsO1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bM10gPSBpbWFnZTtcbiAgICAgICAgICAgIHZhciB0ZXh0T2Zmc2V0WCA9XG4gICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzIyXTtcbiAgICAgICAgICAgIGFuY2hvclggPSAobGFiZWxXaXRoQW5jaG9yLmFuY2hvclggLSB0ZXh0T2Zmc2V0WCkgKiB0aGlzLnBpeGVsUmF0aW87XG4gICAgICAgICAgICBpbnN0cnVjdGlvbls0XSA9IGFuY2hvclg7XG4gICAgICAgICAgICB2YXIgdGV4dE9mZnNldFkgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsyM107XG4gICAgICAgICAgICBhbmNob3JZID0gKGxhYmVsV2l0aEFuY2hvci5hbmNob3JZIC0gdGV4dE9mZnNldFkpICogdGhpcy5waXhlbFJhdGlvO1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bNV0gPSBhbmNob3JZO1xuICAgICAgICAgICAgaGVpZ2h0ID0gaW1hZ2UuaGVpZ2h0O1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bNl0gPSBoZWlnaHQ7XG4gICAgICAgICAgICB3aWR0aCA9IGltYWdlLndpZHRoO1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMTNdID0gd2lkdGg7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIGdlb21ldHJ5V2lkdGhzID0gdm9pZCAwO1xuXG4gICAgICAgICAgaWYgKGluc3RydWN0aW9uLmxlbmd0aCA+IDI0KSB7XG4gICAgICAgICAgICBnZW9tZXRyeVdpZHRocyA9XG4gICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgIGluc3RydWN0aW9uWzI0XTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgcGFkZGluZyA9IHZvaWQgMCxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZEZpbGwgPSB2b2lkIDAsXG4gICAgICAgICAgICAgIGJhY2tncm91bmRTdHJva2UgPSB2b2lkIDA7XG5cbiAgICAgICAgICBpZiAoaW5zdHJ1Y3Rpb24ubGVuZ3RoID4gMTYpIHtcbiAgICAgICAgICAgIHBhZGRpbmcgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMTVdO1xuICAgICAgICAgICAgYmFja2dyb3VuZEZpbGwgPVxuICAgICAgICAgICAgLyoqIEB0eXBlIHtib29sZWFufSAqL1xuICAgICAgICAgICAgaW5zdHJ1Y3Rpb25bMTZdO1xuICAgICAgICAgICAgYmFja2dyb3VuZFN0cm9rZSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge2Jvb2xlYW59ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxN107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhZGRpbmcgPSBkZWZhdWx0UGFkZGluZztcbiAgICAgICAgICAgIGJhY2tncm91bmRGaWxsID0gZmFsc2U7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kU3Ryb2tlID0gZmFsc2U7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJvdGF0ZVdpdGhWaWV3ICYmIHZpZXdSb3RhdGlvbkZyb21UcmFuc2Zvcm0pIHtcbiAgICAgICAgICAgIC8vIENhbnZhcyBpcyBleHBlY3RlZCB0byBiZSByb3RhdGVkIHRvIHJldmVyc2UgdmlldyByb3RhdGlvbi5cbiAgICAgICAgICAgIHJvdGF0aW9uICs9IHZpZXdSb3RhdGlvbjtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFyb3RhdGVXaXRoVmlldyAmJiAhdmlld1JvdGF0aW9uRnJvbVRyYW5zZm9ybSkge1xuICAgICAgICAgICAgLy8gQ2FudmFzIGlzIG5vdCByb3RhdGVkLCBpbWFnZXMgbmVlZCB0byBiZSByb3RhdGVkIGJhY2sgdG8gYmUgbm9ydGgtdXAuXG4gICAgICAgICAgICByb3RhdGlvbiAtPSB2aWV3Um90YXRpb247XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIHdpZHRoSW5kZXggPSAwO1xuXG4gICAgICAgICAgZm9yICg7IGQgPCBkZDsgZCArPSAyKSB7XG4gICAgICAgICAgICBpZiAoZ2VvbWV0cnlXaWR0aHMgJiYgZ2VvbWV0cnlXaWR0aHNbd2lkdGhJbmRleCsrXSA8IHdpZHRoIC8gdGhpcy5waXhlbFJhdGlvKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlSW1hZ2VPckxhYmVsRGltZW5zaW9uc18oaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCwgcGl4ZWxDb29yZGluYXRlc1tkXSwgcGl4ZWxDb29yZGluYXRlc1tkICsgMV0sIHdpZHRoLCBoZWlnaHQsIGFuY2hvclgsIGFuY2hvclksIG9yaWdpblgsIG9yaWdpblksIHJvdGF0aW9uLCBzY2FsZSwgc25hcFRvUGl4ZWwsIHBhZGRpbmcsIGJhY2tncm91bmRGaWxsIHx8IGJhY2tncm91bmRTdHJva2UsIGZlYXR1cmUpO1xuICAgICAgICAgICAgLyoqIEB0eXBlIHtSZXBsYXlJbWFnZU9yTGFiZWxBcmdzfSAqL1xuXG4gICAgICAgICAgICB2YXIgYXJncyA9IFtjb250ZXh0LCBjb250ZXh0U2NhbGUsIGltYWdlLCBkaW1lbnNpb25zLCBvcGFjaXR5LCBiYWNrZ3JvdW5kRmlsbCA/XG4gICAgICAgICAgICAvKiogQHR5cGUge0FycmF5PCo+fSAqL1xuICAgICAgICAgICAgbGFzdEZpbGxJbnN0cnVjdGlvbiA6IG51bGwsIGJhY2tncm91bmRTdHJva2UgP1xuICAgICAgICAgICAgLyoqIEB0eXBlIHtBcnJheTwqPn0gKi9cbiAgICAgICAgICAgIGxhc3RTdHJva2VJbnN0cnVjdGlvbiA6IG51bGxdO1xuICAgICAgICAgICAgdmFyIGltYWdlQXJncyA9IHZvaWQgMDtcbiAgICAgICAgICAgIHZhciBpbWFnZURlY2x1dHRlckJveCA9IHZvaWQgMDtcblxuICAgICAgICAgICAgaWYgKG9wdF9kZWNsdXR0ZXJUcmVlICYmIGRlY2x1dHRlckltYWdlV2l0aFRleHQpIHtcbiAgICAgICAgICAgICAgaWYgKCFkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0W2RdKSB7XG4gICAgICAgICAgICAgICAgLy8gV2Ugbm93IGhhdmUgdGhlIGltYWdlIGZvciBhbiBpbWFnZSt0ZXh0IGNvbWJpbmF0aW9uLlxuICAgICAgICAgICAgICAgIGRlY2x1dHRlckltYWdlV2l0aFRleHRbZF0gPSBhcmdzOyAvLyBEb24ndCByZW5kZXIgYW55dGhpbmcgZm9yIG5vdywgd2FpdCBmb3IgdGhlIHRleHQuXG5cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGltYWdlQXJncyA9IGRlY2x1dHRlckltYWdlV2l0aFRleHRbZF07XG4gICAgICAgICAgICAgIGRlbGV0ZSBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0W2RdO1xuICAgICAgICAgICAgICBpbWFnZURlY2x1dHRlckJveCA9IGdldERlY2x1dHRlckJveChpbWFnZUFyZ3MpO1xuXG4gICAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZS5jb2xsaWRlcyhpbWFnZURlY2x1dHRlckJveCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUgJiYgb3B0X2RlY2x1dHRlclRyZWUuY29sbGlkZXMoZGltZW5zaW9ucy5kZWNsdXR0ZXJCb3gpKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaW1hZ2VBcmdzKSB7XG4gICAgICAgICAgICAgIC8vIFdlIG5vdyBoYXZlIGltYWdlIGFuZCB0ZXh0IGZvciBhbiBpbWFnZSt0ZXh0IGNvbWJpbmF0aW9uLlxuICAgICAgICAgICAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICAgICAgICAgICAgICBvcHRfZGVjbHV0dGVyVHJlZS5pbnNlcnQoaW1hZ2VEZWNsdXR0ZXJCb3gpO1xuICAgICAgICAgICAgICB9IC8vIFJlbmRlciB0aGUgaW1hZ2UgYmVmb3JlIHdlIHJlbmRlciB0aGUgdGV4dC5cblxuXG4gICAgICAgICAgICAgIHRoaXMucmVwbGF5SW1hZ2VPckxhYmVsXy5hcHBseSh0aGlzLCBpbWFnZUFyZ3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICAgICAgICAgICAgb3B0X2RlY2x1dHRlclRyZWUuaW5zZXJ0KGRpbWVuc2lvbnMuZGVjbHV0dGVyQm94KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yZXBsYXlJbWFnZU9yTGFiZWxfLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIENhbnZhc0luc3RydWN0aW9uLkRSQVdfQ0hBUlM6XG4gICAgICAgICAgdmFyIGJlZ2luID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxXTtcbiAgICAgICAgICB2YXIgZW5kID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsyXTtcbiAgICAgICAgICB2YXIgYmFzZWxpbmUgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzNdO1xuICAgICAgICAgIHZhciBvdmVyZmxvdyA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bNF07XG4gICAgICAgICAgZmlsbEtleSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bNV07XG4gICAgICAgICAgdmFyIG1heEFuZ2xlID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls2XTtcbiAgICAgICAgICB2YXIgbWVhc3VyZVBpeGVsUmF0aW8gPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzddO1xuICAgICAgICAgIHZhciBvZmZzZXRZID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvbls4XTtcbiAgICAgICAgICBzdHJva2VLZXkgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzldO1xuICAgICAgICAgIHZhciBzdHJva2VXaWR0aCA9XG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMTBdO1xuICAgICAgICAgIHRleHQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzExXTtcbiAgICAgICAgICB0ZXh0S2V5ID1cbiAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxMl07XG4gICAgICAgICAgdmFyIHBpeGVsUmF0aW9TY2FsZSA9IFtcbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsxM10sXG4gICAgICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMTNdXTtcbiAgICAgICAgICB2YXIgdGV4dFN0YXRlID0gdGhpcy50ZXh0U3RhdGVzW3RleHRLZXldO1xuICAgICAgICAgIHZhciBmb250ID0gdGV4dFN0YXRlLmZvbnQ7XG4gICAgICAgICAgdmFyIHRleHRTY2FsZSA9IFt0ZXh0U3RhdGUuc2NhbGVbMF0gKiBtZWFzdXJlUGl4ZWxSYXRpbywgdGV4dFN0YXRlLnNjYWxlWzFdICogbWVhc3VyZVBpeGVsUmF0aW9dO1xuICAgICAgICAgIHZhciBjYWNoZWRXaWR0aHMgPSB2b2lkIDA7XG5cbiAgICAgICAgICBpZiAoZm9udCBpbiB0aGlzLndpZHRoc18pIHtcbiAgICAgICAgICAgIGNhY2hlZFdpZHRocyA9IHRoaXMud2lkdGhzX1tmb250XTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkV2lkdGhzID0ge307XG4gICAgICAgICAgICB0aGlzLndpZHRoc19bZm9udF0gPSBjYWNoZWRXaWR0aHM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIHBhdGhMZW5ndGggPSBsaW5lU3RyaW5nTGVuZ3RoKHBpeGVsQ29vcmRpbmF0ZXMsIGJlZ2luLCBlbmQsIDIpO1xuICAgICAgICAgIHZhciB0ZXh0TGVuZ3RoID0gTWF0aC5hYnModGV4dFNjYWxlWzBdKSAqIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aChmb250LCB0ZXh0LCBjYWNoZWRXaWR0aHMpO1xuXG4gICAgICAgICAgaWYgKG92ZXJmbG93IHx8IHRleHRMZW5ndGggPD0gcGF0aExlbmd0aCkge1xuICAgICAgICAgICAgdmFyIHRleHRBbGlnbiA9IHRoaXMudGV4dFN0YXRlc1t0ZXh0S2V5XS50ZXh0QWxpZ247XG4gICAgICAgICAgICB2YXIgc3RhcnRNID0gKHBhdGhMZW5ndGggLSB0ZXh0TGVuZ3RoKSAqIFRFWFRfQUxJR05bdGV4dEFsaWduXTtcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IGRyYXdUZXh0T25QYXRoKHBpeGVsQ29vcmRpbmF0ZXMsIGJlZ2luLCBlbmQsIDIsIHRleHQsIHN0YXJ0TSwgbWF4QW5nbGUsIE1hdGguYWJzKHRleHRTY2FsZVswXSksIG1lYXN1cmVBbmRDYWNoZVRleHRXaWR0aCwgZm9udCwgY2FjaGVkV2lkdGhzLCB2aWV3Um90YXRpb25Gcm9tVHJhbnNmb3JtID8gMCA6IHRoaXMudmlld1JvdGF0aW9uXyk7XG5cbiAgICAgICAgICAgIGRyYXdDaGFyczogaWYgKHBhcnRzKSB7XG4gICAgICAgICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVwbGF5SW1hZ2VPckxhYmVsQXJncz59ICovXG4gICAgICAgICAgICAgIHZhciByZXBsYXlJbWFnZU9yTGFiZWxBcmdzID0gW107XG4gICAgICAgICAgICAgIHZhciBjID0gdm9pZCAwLFxuICAgICAgICAgICAgICAgICAgY2MgPSB2b2lkIDAsXG4gICAgICAgICAgICAgICAgICBjaGFycyA9IHZvaWQgMCxcbiAgICAgICAgICAgICAgICAgIGxhYmVsID0gdm9pZCAwLFxuICAgICAgICAgICAgICAgICAgcGFydCA9IHZvaWQgMDtcblxuICAgICAgICAgICAgICBpZiAoc3Ryb2tlS2V5KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjID0gMCwgY2MgPSBwYXJ0cy5sZW5ndGg7IGMgPCBjYzsgKytjKSB7XG4gICAgICAgICAgICAgICAgICBwYXJ0ID0gcGFydHNbY107IC8vIHgsIHksIGFuY2hvclgsIHJvdGF0aW9uLCBjaHVua1xuXG4gICAgICAgICAgICAgICAgICBjaGFycyA9XG4gICAgICAgICAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi9cbiAgICAgICAgICAgICAgICAgIHBhcnRbNF07XG4gICAgICAgICAgICAgICAgICBsYWJlbCA9IHRoaXMuY3JlYXRlTGFiZWwoY2hhcnMsIHRleHRLZXksICcnLCBzdHJva2VLZXkpO1xuICAgICAgICAgICAgICAgICAgYW5jaG9yWCA9XG4gICAgICAgICAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICAgICAgICAgIHBhcnRbMl0gKyAodGV4dFNjYWxlWzBdIDwgMCA/IC1zdHJva2VXaWR0aCA6IHN0cm9rZVdpZHRoKTtcbiAgICAgICAgICAgICAgICAgIGFuY2hvclkgPSBiYXNlbGluZSAqIGxhYmVsLmhlaWdodCArICgwLjUgLSBiYXNlbGluZSkgKiAyICogc3Ryb2tlV2lkdGggKiB0ZXh0U2NhbGVbMV0gLyB0ZXh0U2NhbGVbMF0gLSBvZmZzZXRZO1xuICAgICAgICAgICAgICAgICAgdmFyIGRpbWVuc2lvbnMgPSB0aGlzLmNhbGN1bGF0ZUltYWdlT3JMYWJlbERpbWVuc2lvbnNfKGxhYmVsLndpZHRoLCBsYWJlbC5oZWlnaHQsIHBhcnRbMF0sIHBhcnRbMV0sIGxhYmVsLndpZHRoLCBsYWJlbC5oZWlnaHQsIGFuY2hvclgsIGFuY2hvclksIDAsIDAsIHBhcnRbM10sIHBpeGVsUmF0aW9TY2FsZSwgZmFsc2UsIGRlZmF1bHRQYWRkaW5nLCBmYWxzZSwgZmVhdHVyZSk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSAmJiBvcHRfZGVjbHV0dGVyVHJlZS5jb2xsaWRlcyhkaW1lbnNpb25zLmRlY2x1dHRlckJveCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWsgZHJhd0NoYXJzO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICByZXBsYXlJbWFnZU9yTGFiZWxBcmdzLnB1c2goW2NvbnRleHQsIGNvbnRleHRTY2FsZSwgbGFiZWwsIGRpbWVuc2lvbnMsIDEsIG51bGwsIG51bGxdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoZmlsbEtleSkge1xuICAgICAgICAgICAgICAgIGZvciAoYyA9IDAsIGNjID0gcGFydHMubGVuZ3RoOyBjIDwgY2M7ICsrYykge1xuICAgICAgICAgICAgICAgICAgcGFydCA9IHBhcnRzW2NdOyAvLyB4LCB5LCBhbmNob3JYLCByb3RhdGlvbiwgY2h1bmtcblxuICAgICAgICAgICAgICAgICAgY2hhcnMgPVxuICAgICAgICAgICAgICAgICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgICAgICAgICAgICAgICBwYXJ0WzRdO1xuICAgICAgICAgICAgICAgICAgbGFiZWwgPSB0aGlzLmNyZWF0ZUxhYmVsKGNoYXJzLCB0ZXh0S2V5LCBmaWxsS2V5LCAnJyk7XG4gICAgICAgICAgICAgICAgICBhbmNob3JYID1cbiAgICAgICAgICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgICAgICAgICAgcGFydFsyXTtcbiAgICAgICAgICAgICAgICAgIGFuY2hvclkgPSBiYXNlbGluZSAqIGxhYmVsLmhlaWdodCAtIG9mZnNldFk7XG4gICAgICAgICAgICAgICAgICB2YXIgZGltZW5zaW9ucyA9IHRoaXMuY2FsY3VsYXRlSW1hZ2VPckxhYmVsRGltZW5zaW9uc18obGFiZWwud2lkdGgsIGxhYmVsLmhlaWdodCwgcGFydFswXSwgcGFydFsxXSwgbGFiZWwud2lkdGgsIGxhYmVsLmhlaWdodCwgYW5jaG9yWCwgYW5jaG9yWSwgMCwgMCwgcGFydFszXSwgcGl4ZWxSYXRpb1NjYWxlLCBmYWxzZSwgZGVmYXVsdFBhZGRpbmcsIGZhbHNlLCBmZWF0dXJlKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKG9wdF9kZWNsdXR0ZXJUcmVlICYmIG9wdF9kZWNsdXR0ZXJUcmVlLmNvbGxpZGVzKGRpbWVuc2lvbnMuZGVjbHV0dGVyQm94KSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhayBkcmF3Q2hhcnM7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIHJlcGxheUltYWdlT3JMYWJlbEFyZ3MucHVzaChbY29udGV4dCwgY29udGV4dFNjYWxlLCBsYWJlbCwgZGltZW5zaW9ucywgMSwgbnVsbCwgbnVsbF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChvcHRfZGVjbHV0dGVyVHJlZSkge1xuICAgICAgICAgICAgICAgIG9wdF9kZWNsdXR0ZXJUcmVlLmxvYWQocmVwbGF5SW1hZ2VPckxhYmVsQXJncy5tYXAoZ2V0RGVjbHV0dGVyQm94KSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBmb3IgKHZhciBpXzEgPSAwLCBpaV8xID0gcmVwbGF5SW1hZ2VPckxhYmVsQXJncy5sZW5ndGg7IGlfMSA8IGlpXzE7ICsraV8xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXBsYXlJbWFnZU9yTGFiZWxfLmFwcGx5KHRoaXMsIHJlcGxheUltYWdlT3JMYWJlbEFyZ3NbaV8xXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5FTkRfR0VPTUVUUlk6XG4gICAgICAgICAgaWYgKG9wdF9mZWF0dXJlQ2FsbGJhY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZmVhdHVyZSA9XG4gICAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9ICovXG4gICAgICAgICAgICBpbnN0cnVjdGlvblsxXTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBvcHRfZmVhdHVyZUNhbGxiYWNrKGZlYXR1cmUsIGN1cnJlbnRHZW9tZXRyeSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5GSUxMOlxuICAgICAgICAgIGlmIChiYXRjaFNpemUpIHtcbiAgICAgICAgICAgIHBlbmRpbmdGaWxsKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZmlsbF8oY29udGV4dCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uTU9WRV9UT19MSU5FX1RPOlxuICAgICAgICAgIGQgPVxuICAgICAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uWzFdO1xuICAgICAgICAgIGRkID1cbiAgICAgICAgICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgICAgICAgICBpbnN0cnVjdGlvblsyXTtcbiAgICAgICAgICB4ID0gcGl4ZWxDb29yZGluYXRlc1tkXTtcbiAgICAgICAgICB5ID0gcGl4ZWxDb29yZGluYXRlc1tkICsgMV07XG4gICAgICAgICAgcm91bmRYID0geCArIDAuNSB8IDA7XG4gICAgICAgICAgcm91bmRZID0geSArIDAuNSB8IDA7XG5cbiAgICAgICAgICBpZiAocm91bmRYICE9PSBwcmV2WCB8fCByb3VuZFkgIT09IHByZXZZKSB7XG4gICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyh4LCB5KTtcbiAgICAgICAgICAgIHByZXZYID0gcm91bmRYO1xuICAgICAgICAgICAgcHJldlkgPSByb3VuZFk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChkICs9IDI7IGQgPCBkZDsgZCArPSAyKSB7XG4gICAgICAgICAgICB4ID0gcGl4ZWxDb29yZGluYXRlc1tkXTtcbiAgICAgICAgICAgIHkgPSBwaXhlbENvb3JkaW5hdGVzW2QgKyAxXTtcbiAgICAgICAgICAgIHJvdW5kWCA9IHggKyAwLjUgfCAwO1xuICAgICAgICAgICAgcm91bmRZID0geSArIDAuNSB8IDA7XG5cbiAgICAgICAgICAgIGlmIChkID09IGRkIC0gMiB8fCByb3VuZFggIT09IHByZXZYIHx8IHJvdW5kWSAhPT0gcHJldlkpIHtcbiAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8oeCwgeSk7XG4gICAgICAgICAgICAgIHByZXZYID0gcm91bmRYO1xuICAgICAgICAgICAgICBwcmV2WSA9IHJvdW5kWTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5TRVRfRklMTF9TVFlMRTpcbiAgICAgICAgICBsYXN0RmlsbEluc3RydWN0aW9uID0gaW5zdHJ1Y3Rpb247XG4gICAgICAgICAgdGhpcy5hbGlnbkZpbGxfID0gaW5zdHJ1Y3Rpb25bMl07XG5cbiAgICAgICAgICBpZiAocGVuZGluZ0ZpbGwpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsbF8oY29udGV4dCk7XG4gICAgICAgICAgICBwZW5kaW5nRmlsbCA9IDA7XG5cbiAgICAgICAgICAgIGlmIChwZW5kaW5nU3Ryb2tlKSB7XG4gICAgICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICAgICAgICAgIHBlbmRpbmdTdHJva2UgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRleHQuZmlsbFN0eWxlID1cbiAgICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2NvbG9ybGlrZS5qc1wiKS5Db2xvckxpa2V9ICovXG4gICAgICAgICAgaW5zdHJ1Y3Rpb25bMV07XG4gICAgICAgICAgKytpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgQ2FudmFzSW5zdHJ1Y3Rpb24uU0VUX1NUUk9LRV9TVFlMRTpcbiAgICAgICAgICBsYXN0U3Ryb2tlSW5zdHJ1Y3Rpb24gPSBpbnN0cnVjdGlvbjtcblxuICAgICAgICAgIGlmIChwZW5kaW5nU3Ryb2tlKSB7XG4gICAgICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgICAgICAgICAgcGVuZGluZ1N0cm9rZSA9IDA7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5zZXRTdHJva2VTdHlsZV8oY29udGV4dCxcbiAgICAgICAgICAvKiogQHR5cGUge0FycmF5PCo+fSAqL1xuICAgICAgICAgIGluc3RydWN0aW9uKTtcbiAgICAgICAgICArK2k7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBDYW52YXNJbnN0cnVjdGlvbi5TVFJPS0U6XG4gICAgICAgICAgaWYgKGJhdGNoU2l6ZSkge1xuICAgICAgICAgICAgcGVuZGluZ1N0cm9rZSsrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgICsraTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICsraTsgLy8gY29uc3VtZSB0aGUgaW5zdHJ1Y3Rpb24gYW55d2F5LCB0byBhdm9pZCBhbiBpbmZpbml0ZSBsb29wXG5cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGVuZGluZ0ZpbGwpIHtcbiAgICAgIHRoaXMuZmlsbF8oY29udGV4dCk7XG4gICAgfVxuXG4gICAgaWYgKHBlbmRpbmdTdHJva2UpIHtcbiAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjb250ZXh0U2NhbGUgU2NhbGUgb2YgdGhlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZpZXdSb3RhdGlvbiBWaWV3IHJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHNuYXBUb1BpeGVsIFNuYXAgcG9pbnQgc3ltYm9scyBhbmQgdGV4dCB0byBpbnRlZ2VyIHBpeGVscy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJyYnVzaFwiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlclRyZWUgRGVjbHV0dGVyIHRyZWUuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3IucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbiAoY29udGV4dCwgY29udGV4dFNjYWxlLCB0cmFuc2Zvcm0sIHZpZXdSb3RhdGlvbiwgc25hcFRvUGl4ZWwsIG9wdF9kZWNsdXR0ZXJUcmVlKSB7XG4gICAgdGhpcy52aWV3Um90YXRpb25fID0gdmlld1JvdGF0aW9uO1xuICAgIHRoaXMuZXhlY3V0ZV8oY29udGV4dCwgY29udGV4dFNjYWxlLCB0cmFuc2Zvcm0sIHRoaXMuaW5zdHJ1Y3Rpb25zLCBzbmFwVG9QaXhlbCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIG9wdF9kZWNsdXR0ZXJUcmVlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSBjb250ZXh0IENvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdHJhbnNmb3JtLmpzXCIpLlRyYW5zZm9ybX0gdHJhbnNmb3JtIFRyYW5zZm9ybS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHZpZXdSb3RhdGlvbiBWaWV3IHJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge0ZlYXR1cmVDYWxsYmFjazxUPj19IG9wdF9mZWF0dXJlQ2FsbGJhY2sgRmVhdHVyZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2hpdEV4dGVudCBPbmx5IGNoZWNrXG4gICAqICAgICBmZWF0dXJlcyB0aGF0IGludGVyc2VjdCB0aGlzIGV4dGVudC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICovXG5cblxuICBFeGVjdXRvci5wcm90b3R5cGUuZXhlY3V0ZUhpdERldGVjdGlvbiA9IGZ1bmN0aW9uIChjb250ZXh0LCB0cmFuc2Zvcm0sIHZpZXdSb3RhdGlvbiwgb3B0X2ZlYXR1cmVDYWxsYmFjaywgb3B0X2hpdEV4dGVudCkge1xuICAgIHRoaXMudmlld1JvdGF0aW9uXyA9IHZpZXdSb3RhdGlvbjtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlXyhjb250ZXh0LCAxLCB0cmFuc2Zvcm0sIHRoaXMuaGl0RGV0ZWN0aW9uSW5zdHJ1Y3Rpb25zLCB0cnVlLCBvcHRfZmVhdHVyZUNhbGxiYWNrLCBvcHRfaGl0RXh0ZW50KTtcbiAgfTtcblxuICByZXR1cm4gRXhlY3V0b3I7XG59KCk7XG5cbmV4cG9ydCBkZWZhdWx0IEV4ZWN1dG9yOyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXBcbiAqL1xuaW1wb3J0IEJ1aWxkZXJUeXBlIGZyb20gJy4vQnVpbGRlclR5cGUuanMnO1xuaW1wb3J0IEV4ZWN1dG9yIGZyb20gJy4vRXhlY3V0b3IuanMnO1xuaW1wb3J0IHsgYnVmZmVyLCBjcmVhdGVFbXB0eSwgZXh0ZW5kQ29vcmRpbmF0ZSB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjb21wb3NlIGFzIGNvbXBvc2VUcmFuc2Zvcm0sIGNyZWF0ZSBhcyBjcmVhdGVUcmFuc2Zvcm0gfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi4vLi4vZG9tLmpzJztcbmltcG9ydCB7IGlzRW1wdHkgfSBmcm9tICcuLi8uLi9vYmouanMnO1xuaW1wb3J0IHsgbnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbiB9IGZyb20gJy4uLy4uL2FycmF5LmpzJztcbmltcG9ydCB7IHRyYW5zZm9ybTJEIH0gZnJvbSAnLi4vLi4vZ2VvbS9mbGF0L3RyYW5zZm9ybS5qcyc7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge0FycmF5PGltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdD59XG4gKi9cblxudmFyIE9SREVSID0gW0J1aWxkZXJUeXBlLlBPTFlHT04sIEJ1aWxkZXJUeXBlLkNJUkNMRSwgQnVpbGRlclR5cGUuTElORV9TVFJJTkcsIEJ1aWxkZXJUeXBlLklNQUdFLCBCdWlsZGVyVHlwZS5URVhULCBCdWlsZGVyVHlwZS5ERUZBVUxUXTtcblxudmFyIEV4ZWN1dG9yR3JvdXAgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBtYXhFeHRlbnQgTWF4IGV4dGVudCBmb3IgY2xpcHBpbmcuIFdoZW4gYVxuICAgKiBgbWF4RXh0ZW50YCB3YXMgc2V0IG9uIHRoZSBCdWlsbGRlciBmb3IgdGhpcyBleGVjdXRvciBncm91cCwgdGhlIHNhbWUgYG1heEV4dGVudGBcbiAgICogc2hvdWxkIGJlIHNldCBoZXJlLCB1bmxlc3MgdGhlIHRhcmdldCBjb250ZXh0IGRvZXMgbm90IGV4Y2VldCB0aGF0IGV4dGVudCAod2hpY2hcbiAgICogY2FuIGJlIHRoZSBjYXNlIHdoZW4gcmVuZGVyaW5nIHRvIHRpbGVzKS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gb3ZlcmxhcHMgVGhlIGV4ZWN1dG9yIGdyb3VwIGNhbiBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuXG4gICAqIEBwYXJhbSB7IU9iamVjdDxzdHJpbmcsICFPYmplY3Q8aW1wb3J0KFwiLi9CdWlsZGVyVHlwZS5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU2VyaWFsaXphYmxlSW5zdHJ1Y3Rpb25zPj59IGFsbEluc3RydWN0aW9uc1xuICAgKiBUaGUgc2VyaWFsaXphYmxlIGluc3RydWN0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfcmVuZGVyQnVmZmVyIE9wdGlvbmFsIHJlbmRlcmluZyBidWZmZXIuXG4gICAqL1xuICBmdW5jdGlvbiBFeGVjdXRvckdyb3VwKG1heEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgb3ZlcmxhcHMsIGFsbEluc3RydWN0aW9ucywgb3B0X3JlbmRlckJ1ZmZlcikge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG4gICAgdGhpcy5tYXhFeHRlbnRfID0gbWF4RXh0ZW50O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICB0aGlzLm92ZXJsYXBzXyA9IG92ZXJsYXBzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucGl4ZWxSYXRpb18gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIHRoaXMucmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLnJlbmRlckJ1ZmZlcl8gPSBvcHRfcmVuZGVyQnVmZmVyO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCAhT2JqZWN0PGltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi9FeGVjdXRvclwiKS5kZWZhdWx0Pj59XG4gICAgICovXG5cbiAgICB0aGlzLmV4ZWN1dG9yc0J5WkluZGV4XyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH1cbiAgICAgKi9cblxuICAgIHRoaXMuaGl0RGV0ZWN0aW9uQ29udGV4dF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICB0aGlzLmhpdERldGVjdGlvblRyYW5zZm9ybV8gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICB0aGlzLmNyZWF0ZUV4ZWN1dG9yc18oYWxsSW5zdHJ1Y3Rpb25zKTtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKi9cblxuXG4gIEV4ZWN1dG9yR3JvdXAucHJvdG90eXBlLmNsaXAgPSBmdW5jdGlvbiAoY29udGV4dCwgdHJhbnNmb3JtKSB7XG4gICAgdmFyIGZsYXRDbGlwQ29vcmRzID0gdGhpcy5nZXRDbGlwQ29vcmRzKHRyYW5zZm9ybSk7XG4gICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICBjb250ZXh0Lm1vdmVUbyhmbGF0Q2xpcENvb3Jkc1swXSwgZmxhdENsaXBDb29yZHNbMV0pO1xuICAgIGNvbnRleHQubGluZVRvKGZsYXRDbGlwQ29vcmRzWzJdLCBmbGF0Q2xpcENvb3Jkc1szXSk7XG4gICAgY29udGV4dC5saW5lVG8oZmxhdENsaXBDb29yZHNbNF0sIGZsYXRDbGlwQ29vcmRzWzVdKTtcbiAgICBjb250ZXh0LmxpbmVUbyhmbGF0Q2xpcENvb3Jkc1s2XSwgZmxhdENsaXBDb29yZHNbN10pO1xuICAgIGNvbnRleHQuY2xpcCgpO1xuICB9O1xuICAvKipcbiAgICogQ3JlYXRlIGV4ZWN1dG9ycyBhbmQgcG9wdWxhdGUgdGhlbSB1c2luZyB0aGUgcHJvdmlkZWQgaW5zdHJ1Y3Rpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyFPYmplY3Q8c3RyaW5nLCAhT2JqZWN0PGltcG9ydChcIi4vQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlNlcmlhbGl6YWJsZUluc3RydWN0aW9ucz4+fSBhbGxJbnN0cnVjdGlvbnMgVGhlIHNlcmlhbGl6YWJsZSBpbnN0cnVjdGlvbnNcbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5jcmVhdGVFeGVjdXRvcnNfID0gZnVuY3Rpb24gKGFsbEluc3RydWN0aW9ucykge1xuICAgIGZvciAodmFyIHpJbmRleCBpbiBhbGxJbnN0cnVjdGlvbnMpIHtcbiAgICAgIHZhciBleGVjdXRvcnMgPSB0aGlzLmV4ZWN1dG9yc0J5WkluZGV4X1t6SW5kZXhdO1xuXG4gICAgICBpZiAoZXhlY3V0b3JzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZXhlY3V0b3JzID0ge307XG4gICAgICAgIHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfW3pJbmRleF0gPSBleGVjdXRvcnM7XG4gICAgICB9XG5cbiAgICAgIHZhciBpbnN0cnVjdGlvbkJ5WmluZGV4ID0gYWxsSW5zdHJ1Y3Rpb25zW3pJbmRleF07XG4gICAgICB2YXIgcmVuZGVyQnVmZmVyID0gW3RoaXMucmVuZGVyQnVmZmVyXyB8fCAwLCB0aGlzLnJlbmRlckJ1ZmZlcl8gfHwgMF07XG5cbiAgICAgIGZvciAodmFyIGJ1aWxkZXJUeXBlIGluIGluc3RydWN0aW9uQnlaaW5kZXgpIHtcbiAgICAgICAgdmFyIGluc3RydWN0aW9ucyA9IGluc3RydWN0aW9uQnlaaW5kZXhbYnVpbGRlclR5cGVdO1xuICAgICAgICBleGVjdXRvcnNbYnVpbGRlclR5cGVdID0gbmV3IEV4ZWN1dG9yKHRoaXMucmVzb2x1dGlvbl8sIHRoaXMucGl4ZWxSYXRpb18sIHRoaXMub3ZlcmxhcHNfLCBpbnN0cnVjdGlvbnMsIHJlbmRlckJ1ZmZlcik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0J1aWxkZXJUeXBlLmpzXCIpLmRlZmF1bHQ+fSBleGVjdXRvcnMgRXhlY3V0b3JzLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBIYXMgZXhlY3V0b3JzIG9mIHRoZSBwcm92aWRlZCB0eXBlcy5cbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5oYXNFeGVjdXRvcnMgPSBmdW5jdGlvbiAoZXhlY3V0b3JzKSB7XG4gICAgZm9yICh2YXIgekluZGV4IGluIHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfKSB7XG4gICAgICB2YXIgY2FuZGlkYXRlcyA9IHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfW3pJbmRleF07XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGV4ZWN1dG9ycy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGlmIChleGVjdXRvcnNbaV0gaW4gY2FuZGlkYXRlcykge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2UsIGltcG9ydChcIi4uLy4uL2dlb20vU2ltcGxlR2VvbWV0cnkuanNcIikuZGVmYXVsdCwgbnVtYmVyKTogVH0gY2FsbGJhY2sgRmVhdHVyZSBjYWxsYmFjay5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gZGVjbHV0dGVyZWRGZWF0dXJlcyBEZWNsdXR0ZXJlZCBmZWF0dXJlcy5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICogQHRlbXBsYXRlIFRcbiAgICovXG5cblxuICBFeGVjdXRvckdyb3VwLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgaGl0VG9sZXJhbmNlLCBjYWxsYmFjaywgZGVjbHV0dGVyZWRGZWF0dXJlcykge1xuICAgIGhpdFRvbGVyYW5jZSA9IE1hdGgucm91bmQoaGl0VG9sZXJhbmNlKTtcbiAgICB2YXIgY29udGV4dFNpemUgPSBoaXRUb2xlcmFuY2UgKiAyICsgMTtcbiAgICB2YXIgdHJhbnNmb3JtID0gY29tcG9zZVRyYW5zZm9ybSh0aGlzLmhpdERldGVjdGlvblRyYW5zZm9ybV8sIGhpdFRvbGVyYW5jZSArIDAuNSwgaGl0VG9sZXJhbmNlICsgMC41LCAxIC8gcmVzb2x1dGlvbiwgLTEgLyByZXNvbHV0aW9uLCAtcm90YXRpb24sIC1jb29yZGluYXRlWzBdLCAtY29vcmRpbmF0ZVsxXSk7XG4gICAgdmFyIG5ld0NvbnRleHQgPSAhdGhpcy5oaXREZXRlY3Rpb25Db250ZXh0XztcblxuICAgIGlmIChuZXdDb250ZXh0KSB7XG4gICAgICB0aGlzLmhpdERldGVjdGlvbkNvbnRleHRfID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKGNvbnRleHRTaXplLCBjb250ZXh0U2l6ZSk7XG4gICAgfVxuXG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmhpdERldGVjdGlvbkNvbnRleHRfO1xuXG4gICAgaWYgKGNvbnRleHQuY2FudmFzLndpZHRoICE9PSBjb250ZXh0U2l6ZSB8fCBjb250ZXh0LmNhbnZhcy5oZWlnaHQgIT09IGNvbnRleHRTaXplKSB7XG4gICAgICBjb250ZXh0LmNhbnZhcy53aWR0aCA9IGNvbnRleHRTaXplO1xuICAgICAgY29udGV4dC5jYW52YXMuaGVpZ2h0ID0gY29udGV4dFNpemU7XG4gICAgfSBlbHNlIGlmICghbmV3Q29udGV4dCkge1xuICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgY29udGV4dFNpemUsIGNvbnRleHRTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gICAgICovXG5cblxuICAgIHZhciBoaXRFeHRlbnQ7XG5cbiAgICBpZiAodGhpcy5yZW5kZXJCdWZmZXJfICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhpdEV4dGVudCA9IGNyZWF0ZUVtcHR5KCk7XG4gICAgICBleHRlbmRDb29yZGluYXRlKGhpdEV4dGVudCwgY29vcmRpbmF0ZSk7XG4gICAgICBidWZmZXIoaGl0RXh0ZW50LCByZXNvbHV0aW9uICogKHRoaXMucmVuZGVyQnVmZmVyXyArIGhpdFRvbGVyYW5jZSksIGhpdEV4dGVudCk7XG4gICAgfVxuXG4gICAgdmFyIGluZGV4ZXMgPSBnZXRQaXhlbEluZGV4QXJyYXkoaGl0VG9sZXJhbmNlKTtcbiAgICB2YXIgYnVpbGRlclR5cGU7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAgICovXG5cbiAgICBmdW5jdGlvbiBmZWF0dXJlQ2FsbGJhY2soZmVhdHVyZSwgZ2VvbWV0cnkpIHtcbiAgICAgIHZhciBpbWFnZURhdGEgPSBjb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCBjb250ZXh0U2l6ZSwgY29udGV4dFNpemUpLmRhdGE7XG5cbiAgICAgIGZvciAodmFyIGlfMSA9IDAsIGlpID0gaW5kZXhlcy5sZW5ndGg7IGlfMSA8IGlpOyBpXzErKykge1xuICAgICAgICBpZiAoaW1hZ2VEYXRhW2luZGV4ZXNbaV8xXV0gPiAwKSB7XG4gICAgICAgICAgaWYgKCFkZWNsdXR0ZXJlZEZlYXR1cmVzIHx8IGJ1aWxkZXJUeXBlICE9PSBCdWlsZGVyVHlwZS5JTUFHRSAmJiBidWlsZGVyVHlwZSAhPT0gQnVpbGRlclR5cGUuVEVYVCB8fCBkZWNsdXR0ZXJlZEZlYXR1cmVzLmluZGV4T2YoZmVhdHVyZSkgIT09IC0xKSB7XG4gICAgICAgICAgICB2YXIgaWR4ID0gKGluZGV4ZXNbaV8xXSAtIDMpIC8gNDtcbiAgICAgICAgICAgIHZhciB4ID0gaGl0VG9sZXJhbmNlIC0gaWR4ICUgY29udGV4dFNpemU7XG4gICAgICAgICAgICB2YXIgeSA9IGhpdFRvbGVyYW5jZSAtIChpZHggLyBjb250ZXh0U2l6ZSB8IDApO1xuICAgICAgICAgICAgdmFyIHJlc3VsdF8xID0gY2FsbGJhY2soZmVhdHVyZSwgZ2VvbWV0cnksIHggKiB4ICsgeSAqIHkpO1xuXG4gICAgICAgICAgICBpZiAocmVzdWx0XzEpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdF8xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnRleHQuY2xlYXJSZWN0KDAsIDAsIGNvbnRleHRTaXplLCBjb250ZXh0U2l6ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuXG5cbiAgICB2YXIgenMgPSBPYmplY3Qua2V5cyh0aGlzLmV4ZWN1dG9yc0J5WkluZGV4XykubWFwKE51bWJlcik7XG4gICAgenMuc29ydChudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uKTtcbiAgICB2YXIgaSwgaiwgZXhlY3V0b3JzLCBleGVjdXRvciwgcmVzdWx0O1xuXG4gICAgZm9yIChpID0genMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHZhciB6SW5kZXhLZXkgPSB6c1tpXS50b1N0cmluZygpO1xuICAgICAgZXhlY3V0b3JzID0gdGhpcy5leGVjdXRvcnNCeVpJbmRleF9bekluZGV4S2V5XTtcblxuICAgICAgZm9yIChqID0gT1JERVIubGVuZ3RoIC0gMTsgaiA+PSAwOyAtLWopIHtcbiAgICAgICAgYnVpbGRlclR5cGUgPSBPUkRFUltqXTtcbiAgICAgICAgZXhlY3V0b3IgPSBleGVjdXRvcnNbYnVpbGRlclR5cGVdO1xuXG4gICAgICAgIGlmIChleGVjdXRvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVzdWx0ID0gZXhlY3V0b3IuZXhlY3V0ZUhpdERldGVjdGlvbihjb250ZXh0LCB0cmFuc2Zvcm0sIHJvdGF0aW9uLCBmZWF0dXJlQ2FsbGJhY2ssIGhpdEV4dGVudCk7XG5cbiAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IENsaXAgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3JHcm91cC5wcm90b3R5cGUuZ2V0Q2xpcENvb3JkcyA9IGZ1bmN0aW9uICh0cmFuc2Zvcm0pIHtcbiAgICB2YXIgbWF4RXh0ZW50ID0gdGhpcy5tYXhFeHRlbnRfO1xuXG4gICAgaWYgKCFtYXhFeHRlbnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBtaW5YID0gbWF4RXh0ZW50WzBdO1xuICAgIHZhciBtaW5ZID0gbWF4RXh0ZW50WzFdO1xuICAgIHZhciBtYXhYID0gbWF4RXh0ZW50WzJdO1xuICAgIHZhciBtYXhZID0gbWF4RXh0ZW50WzNdO1xuICAgIHZhciBmbGF0Q2xpcENvb3JkcyA9IFttaW5YLCBtaW5ZLCBtaW5YLCBtYXhZLCBtYXhYLCBtYXhZLCBtYXhYLCBtaW5ZXTtcbiAgICB0cmFuc2Zvcm0yRChmbGF0Q2xpcENvb3JkcywgMCwgOCwgMiwgdHJhbnNmb3JtLCBmbGF0Q2xpcENvb3Jkcyk7XG4gICAgcmV0dXJuIGZsYXRDbGlwQ29vcmRzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgZW1wdHkuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3JHcm91cC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaXNFbXB0eSh0aGlzLmV4ZWN1dG9yc0J5WkluZGV4Xyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCBDb250ZXh0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gY29udGV4dFNjYWxlIFNjYWxlIG9mIHRoZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19IHRyYW5zZm9ybSBUcmFuc2Zvcm0uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2aWV3Um90YXRpb24gVmlldyByb3RhdGlvbi5cbiAgICogQHBhcmFtIHtib29sZWFufSBzbmFwVG9QaXhlbCBTbmFwIHBvaW50IHN5bWJvbHMgYW5kIHRlc3QgdG8gaW50ZWdlciBwaXhlbC5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0J1aWxkZXJUeXBlLmpzXCIpLmRlZmF1bHQ+PX0gb3B0X2J1aWxkZXJUeXBlcyBPcmRlcmVkIHJlcGxheSB0eXBlcyB0byByZXBsYXkuXG4gICAqICAgICBEZWZhdWx0IGlzIHtAbGluayBtb2R1bGU6b2wvcmVuZGVyL3JlcGxheX5PUkRFUn1cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJyYnVzaFwiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlclRyZWUgRGVjbHV0dGVyIHRyZWUuXG4gICAqL1xuXG5cbiAgRXhlY3V0b3JHcm91cC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChjb250ZXh0LCBjb250ZXh0U2NhbGUsIHRyYW5zZm9ybSwgdmlld1JvdGF0aW9uLCBzbmFwVG9QaXhlbCwgb3B0X2J1aWxkZXJUeXBlcywgb3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgdmFyIHpzID0gT2JqZWN0LmtleXModGhpcy5leGVjdXRvcnNCeVpJbmRleF8pLm1hcChOdW1iZXIpO1xuICAgIHpzLnNvcnQobnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbik7IC8vIHNldHVwIGNsaXBwaW5nIHNvIHRoYXQgdGhlIHBhcnRzIG9mIG92ZXItc2ltcGxpZmllZCBnZW9tZXRyaWVzIGFyZSBub3RcbiAgICAvLyB2aXNpYmxlIG91dHNpZGUgdGhlIGN1cnJlbnQgZXh0ZW50IHdoZW4gcGFubmluZ1xuXG4gICAgaWYgKHRoaXMubWF4RXh0ZW50Xykge1xuICAgICAgY29udGV4dC5zYXZlKCk7XG4gICAgICB0aGlzLmNsaXAoY29udGV4dCwgdHJhbnNmb3JtKTtcbiAgICB9XG5cbiAgICB2YXIgYnVpbGRlclR5cGVzID0gb3B0X2J1aWxkZXJUeXBlcyA/IG9wdF9idWlsZGVyVHlwZXMgOiBPUkRFUjtcbiAgICB2YXIgaSwgaWksIGosIGpqLCByZXBsYXlzLCByZXBsYXk7XG5cbiAgICBpZiAob3B0X2RlY2x1dHRlclRyZWUpIHtcbiAgICAgIHpzLnJldmVyc2UoKTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBpaSA9IHpzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciB6SW5kZXhLZXkgPSB6c1tpXS50b1N0cmluZygpO1xuICAgICAgcmVwbGF5cyA9IHRoaXMuZXhlY3V0b3JzQnlaSW5kZXhfW3pJbmRleEtleV07XG5cbiAgICAgIGZvciAoaiA9IDAsIGpqID0gYnVpbGRlclR5cGVzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICAgICAgdmFyIGJ1aWxkZXJUeXBlID0gYnVpbGRlclR5cGVzW2pdO1xuICAgICAgICByZXBsYXkgPSByZXBsYXlzW2J1aWxkZXJUeXBlXTtcblxuICAgICAgICBpZiAocmVwbGF5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXBsYXkuZXhlY3V0ZShjb250ZXh0LCBjb250ZXh0U2NhbGUsIHRyYW5zZm9ybSwgdmlld1JvdGF0aW9uLCBzbmFwVG9QaXhlbCwgb3B0X2RlY2x1dHRlclRyZWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RXh0ZW50Xykge1xuICAgICAgY29udGV4dC5yZXN0b3JlKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBFeGVjdXRvckdyb3VwO1xufSgpO1xuLyoqXG4gKiBUaGlzIGNhY2hlIGlzIHVzZWQgdG8gc3RvcmUgYXJyYXlzIG9mIGluZGV4ZXMgZm9yIGNhbGN1bGF0ZWQgcGl4ZWwgY2lyY2xlc1xuICogdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2UuXG4gKiBJdCBpcyBhIHN0YXRpYyBwcm9wZXJ0eSB0byBhbGxvdyBlYWNoIFJlcGxheWdyb3VwIHRvIGFjY2VzcyBpdC5cbiAqIEB0eXBlIHtPYmplY3Q8bnVtYmVyLCBBcnJheTxudW1iZXI+Pn1cbiAqL1xuXG5cbnZhciBjaXJjbGVQaXhlbEluZGV4QXJyYXlDYWNoZSA9IHt9O1xuLyoqXG4gKiBUaGlzIG1ldGhvZHMgY3JlYXRlcyBhbiBhcnJheSB3aXRoIGluZGV4ZXMgb2YgYWxsIHBpeGVscyB3aXRoaW4gYSBjaXJjbGUsXG4gKiBvcmRlcmVkIGJ5IGhvdyBjbG9zZSB0aGV5IGFyZSB0byB0aGUgY2VudGVyLlxuICogQSBjYWNoZSBpcyB1c2VkIHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IHJhZGl1cyBSYWRpdXMuXG4gKiBAcmV0dXJucyB7QXJyYXk8bnVtYmVyPn0gQW4gYXJyYXkgd2l0aCBpbmRleGVzIHdpdGhpbiBhIGNpcmNsZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGl4ZWxJbmRleEFycmF5KHJhZGl1cykge1xuICBpZiAoY2lyY2xlUGl4ZWxJbmRleEFycmF5Q2FjaGVbcmFkaXVzXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGNpcmNsZVBpeGVsSW5kZXhBcnJheUNhY2hlW3JhZGl1c107XG4gIH1cblxuICB2YXIgc2l6ZSA9IHJhZGl1cyAqIDIgKyAxO1xuICB2YXIgbWF4RGlzdGFuY2VTcSA9IHJhZGl1cyAqIHJhZGl1cztcbiAgdmFyIGRpc3RhbmNlcyA9IG5ldyBBcnJheShtYXhEaXN0YW5jZVNxICsgMSk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPD0gcmFkaXVzOyArK2kpIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8PSByYWRpdXM7ICsraikge1xuICAgICAgdmFyIGRpc3RhbmNlU3EgPSBpICogaSArIGogKiBqO1xuXG4gICAgICBpZiAoZGlzdGFuY2VTcSA+IG1heERpc3RhbmNlU3EpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHZhciBkaXN0YW5jZSA9IGRpc3RhbmNlc1tkaXN0YW5jZVNxXTtcblxuICAgICAgaWYgKCFkaXN0YW5jZSkge1xuICAgICAgICBkaXN0YW5jZSA9IFtdO1xuICAgICAgICBkaXN0YW5jZXNbZGlzdGFuY2VTcV0gPSBkaXN0YW5jZTtcbiAgICAgIH1cblxuICAgICAgZGlzdGFuY2UucHVzaCgoKHJhZGl1cyArIGkpICogc2l6ZSArIChyYWRpdXMgKyBqKSkgKiA0ICsgMyk7XG5cbiAgICAgIGlmIChpID4gMCkge1xuICAgICAgICBkaXN0YW5jZS5wdXNoKCgocmFkaXVzIC0gaSkgKiBzaXplICsgKHJhZGl1cyArIGopKSAqIDQgKyAzKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGogPiAwKSB7XG4gICAgICAgIGRpc3RhbmNlLnB1c2goKChyYWRpdXMgKyBpKSAqIHNpemUgKyAocmFkaXVzIC0gaikpICogNCArIDMpO1xuXG4gICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgIGRpc3RhbmNlLnB1c2goKChyYWRpdXMgLSBpKSAqIHNpemUgKyAocmFkaXVzIC0gaikpICogNCArIDMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBpeGVsSW5kZXggPSBbXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBkaXN0YW5jZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGlmIChkaXN0YW5jZXNbaV0pIHtcbiAgICAgIHBpeGVsSW5kZXgucHVzaC5hcHBseShwaXhlbEluZGV4LCBkaXN0YW5jZXNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIGNpcmNsZVBpeGVsSW5kZXhBcnJheUNhY2hlW3JhZGl1c10gPSBwaXhlbEluZGV4O1xuICByZXR1cm4gcGl4ZWxJbmRleDtcbn1cbmV4cG9ydCBkZWZhdWx0IEV4ZWN1dG9yR3JvdXA7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvSW1tZWRpYXRlXG4gKi9cbi8vIEZJWE1FIHRlc3QsIGVzcGVjaWFsbHkgcG9seWdvbnMgd2l0aCBob2xlcyBhbmQgbXVsdGlwb2x5Z29uc1xuLy8gRklYTUUgbmVlZCB0byBoYW5kbGUgbGFyZ2UgdGhpY2sgZmVhdHVyZXMgKHdoZXJlIHBpeGVsIHNpemUgbWF0dGVycylcbi8vIEZJWE1FIGFkZCBvZmZzZXQgYW5kIGVuZCB0byBvbC9nZW9tL2ZsYXQvdHJhbnNmb3JtfnRyYW5zZm9ybTJEP1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuLi8uLi9nZW9tL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgVmVjdG9yQ29udGV4dCBmcm9tICcuLi9WZWN0b3JDb250ZXh0LmpzJztcbmltcG9ydCB7IGFzQ29sb3JMaWtlIH0gZnJvbSAnLi4vLi4vY29sb3JsaWtlLmpzJztcbmltcG9ydCB7IGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSB9IGZyb20gJy4uLy4uL3RyYW5zZm9ybS5qcyc7XG5pbXBvcnQgeyBkZWZhdWx0RmlsbFN0eWxlLCBkZWZhdWx0Rm9udCwgZGVmYXVsdExpbmVDYXAsIGRlZmF1bHRMaW5lRGFzaCwgZGVmYXVsdExpbmVEYXNoT2Zmc2V0LCBkZWZhdWx0TGluZUpvaW4sIGRlZmF1bHRMaW5lV2lkdGgsIGRlZmF1bHRNaXRlckxpbWl0LCBkZWZhdWx0U3Ryb2tlU3R5bGUsIGRlZmF1bHRUZXh0QWxpZ24sIGRlZmF1bHRUZXh0QmFzZWxpbmUgfSBmcm9tICcuLi9jYW52YXMuanMnO1xuaW1wb3J0IHsgZXF1YWxzIH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0cyB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0yRCB9IGZyb20gJy4uLy4uL2dlb20vZmxhdC90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtR2VvbTJEIH0gZnJvbSAnLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEEgY29uY3JldGUgc3ViY2xhc3Mgb2Yge0BsaW5rIG1vZHVsZTpvbC9yZW5kZXIvVmVjdG9yQ29udGV4dH0gdGhhdCBpbXBsZW1lbnRzXG4gKiBkaXJlY3QgcmVuZGVyaW5nIG9mIGZlYXR1cmVzIGFuZCBnZW9tZXRyaWVzIHRvIGFuIEhUTUw1IENhbnZhcyBjb250ZXh0LlxuICogSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgYXJlIGNyZWF0ZWQgaW50ZXJuYWxseSBieSB0aGUgbGlicmFyeSBhbmRcbiAqIHByb3ZpZGVkIHRvIGFwcGxpY2F0aW9uIGNvZGUgYXMgdmVjdG9yQ29udGV4dCBtZW1iZXIgb2YgdGhlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9FdmVudH5SZW5kZXJFdmVudH0gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCBwb3N0Y29tcG9zZSwgcHJlY29tcG9zZSBhbmRcbiAqIHJlbmRlciBldmVudHMgZW1pdHRlZCBieSBsYXllcnMgYW5kIG1hcHMuXG4gKi9cblxudmFyIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGNvbnRleHQgQ29udGV4dC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmlld1JvdGF0aW9uIFZpZXcgcm90YXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3NxdWFyZWRUb2xlcmFuY2UgT3B0aW9uYWwgc3F1YXJlZCB0b2xlcmFuY2UgZm9yIHNpbXBsaWZpY2F0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb249fSBvcHRfdXNlclRyYW5zZm9ybSBUcmFuc2Zvcm0gZnJvbSB1c2VyIHRvIHZpZXcgcHJvamVjdGlvbi5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNJbW1lZGlhdGVSZW5kZXJlcihjb250ZXh0LCBwaXhlbFJhdGlvLCBleHRlbnQsIHRyYW5zZm9ybSwgdmlld1JvdGF0aW9uLCBvcHRfc3F1YXJlZFRvbGVyYW5jZSwgb3B0X3VzZXJUcmFuc2Zvcm0pIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29udGV4dF8gPSBjb250ZXh0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnBpeGVsUmF0aW9fID0gcGl4ZWxSYXRpbztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZXh0ZW50XyA9IGV4dGVudDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhbnNmb3JtXyA9IHRyYW5zZm9ybTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy52aWV3Um90YXRpb25fID0gdmlld1JvdGF0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNxdWFyZWRUb2xlcmFuY2VfID0gb3B0X3NxdWFyZWRUb2xlcmFuY2U7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnVzZXJUcmFuc2Zvcm1fID0gb3B0X3VzZXJUcmFuc2Zvcm07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0RmlsbFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TdHJva2VTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRleHRTdHJva2VTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuVGV4dFN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29udGV4dFRleHRTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmlsbFN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5TdHJva2VTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnN0cm9rZVN0YXRlXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTFZpZGVvRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZUFuY2hvclhfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZUFuY2hvcllfID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZUhlaWdodF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlT3BhY2l0eV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlT3JpZ2luWF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlT3JpZ2luWV8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZVJvdGF0ZVdpdGhWaWV3XyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlUm90YXRpb25fID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZVNjYWxlXyA9IFswLCAwXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZVdpZHRoXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dF8gPSAnJztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0T2Zmc2V0WF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRPZmZzZXRZXyA9IDA7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRSb3RhdGVXaXRoVmlld18gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0Um90YXRpb25fID0gMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0U2NhbGVfID0gWzAsIDBdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuRmlsbFN0YXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGV4dEZpbGxTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9pbXBvcnQoXCIuLi9jYW52YXMuanNcIikuU3Ryb2tlU3RhdGV9XG4gICAgICovXG5cbiAgICBfdGhpcy50ZXh0U3Ryb2tlU3RhdGVfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlRleHRTdGF0ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRleHRTdGF0ZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5waXhlbENvb3JkaW5hdGVzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy50bXBMb2NhbFRyYW5zZm9ybV8gPSBjcmVhdGVUcmFuc2Zvcm0oKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdJbWFnZXNfID0gZnVuY3Rpb24gKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSkge1xuICAgIGlmICghdGhpcy5pbWFnZV8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcGl4ZWxDb29yZGluYXRlcyA9IHRyYW5zZm9ybTJEKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIDIsIHRoaXMudHJhbnNmb3JtXywgdGhpcy5waXhlbENvb3JkaW5hdGVzXyk7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgIHZhciBsb2NhbFRyYW5zZm9ybSA9IHRoaXMudG1wTG9jYWxUcmFuc2Zvcm1fO1xuICAgIHZhciBhbHBoYSA9IGNvbnRleHQuZ2xvYmFsQWxwaGE7XG5cbiAgICBpZiAodGhpcy5pbWFnZU9wYWNpdHlfICE9IDEpIHtcbiAgICAgIGNvbnRleHQuZ2xvYmFsQWxwaGEgPSBhbHBoYSAqIHRoaXMuaW1hZ2VPcGFjaXR5XztcbiAgICB9XG5cbiAgICB2YXIgcm90YXRpb24gPSB0aGlzLmltYWdlUm90YXRpb25fO1xuXG4gICAgaWYgKHRoaXMuaW1hZ2VSb3RhdGVXaXRoVmlld18pIHtcbiAgICAgIHJvdGF0aW9uICs9IHRoaXMudmlld1JvdGF0aW9uXztcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBwaXhlbENvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyBpICs9IDIpIHtcbiAgICAgIHZhciB4ID0gcGl4ZWxDb29yZGluYXRlc1tpXSAtIHRoaXMuaW1hZ2VBbmNob3JYXztcbiAgICAgIHZhciB5ID0gcGl4ZWxDb29yZGluYXRlc1tpICsgMV0gLSB0aGlzLmltYWdlQW5jaG9yWV87XG5cbiAgICAgIGlmIChyb3RhdGlvbiAhPT0gMCB8fCB0aGlzLmltYWdlU2NhbGVfWzBdICE9IDEgfHwgdGhpcy5pbWFnZVNjYWxlX1sxXSAhPSAxKSB7XG4gICAgICAgIHZhciBjZW50ZXJYID0geCArIHRoaXMuaW1hZ2VBbmNob3JYXztcbiAgICAgICAgdmFyIGNlbnRlclkgPSB5ICsgdGhpcy5pbWFnZUFuY2hvcllfO1xuICAgICAgICBjb21wb3NlVHJhbnNmb3JtKGxvY2FsVHJhbnNmb3JtLCBjZW50ZXJYLCBjZW50ZXJZLCAxLCAxLCByb3RhdGlvbiwgLWNlbnRlclgsIC1jZW50ZXJZKTtcbiAgICAgICAgY29udGV4dC5zZXRUcmFuc2Zvcm0uYXBwbHkoY29udGV4dCwgbG9jYWxUcmFuc2Zvcm0pO1xuICAgICAgICBjb250ZXh0LnRyYW5zbGF0ZShjZW50ZXJYLCBjZW50ZXJZKTtcbiAgICAgICAgY29udGV4dC5zY2FsZSh0aGlzLmltYWdlU2NhbGVfWzBdLCB0aGlzLmltYWdlU2NhbGVfWzFdKTtcbiAgICAgICAgY29udGV4dC5kcmF3SW1hZ2UodGhpcy5pbWFnZV8sIHRoaXMuaW1hZ2VPcmlnaW5YXywgdGhpcy5pbWFnZU9yaWdpbllfLCB0aGlzLmltYWdlV2lkdGhfLCB0aGlzLmltYWdlSGVpZ2h0XywgLXRoaXMuaW1hZ2VBbmNob3JYXywgLXRoaXMuaW1hZ2VBbmNob3JZXywgdGhpcy5pbWFnZVdpZHRoXywgdGhpcy5pbWFnZUhlaWdodF8pO1xuICAgICAgICBjb250ZXh0LnNldFRyYW5zZm9ybSgxLCAwLCAwLCAxLCAwLCAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQuZHJhd0ltYWdlKHRoaXMuaW1hZ2VfLCB0aGlzLmltYWdlT3JpZ2luWF8sIHRoaXMuaW1hZ2VPcmlnaW5ZXywgdGhpcy5pbWFnZVdpZHRoXywgdGhpcy5pbWFnZUhlaWdodF8sIHgsIHksIHRoaXMuaW1hZ2VXaWR0aF8sIHRoaXMuaW1hZ2VIZWlnaHRfKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5pbWFnZU9wYWNpdHlfICE9IDEpIHtcbiAgICAgIGNvbnRleHQuZ2xvYmFsQWxwaGEgPSBhbHBoYTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3VGV4dF8gPSBmdW5jdGlvbiAoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gICAgaWYgKCF0aGlzLnRleHRTdGF0ZV8gfHwgdGhpcy50ZXh0XyA9PT0gJycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0RmlsbFN0YXRlXykge1xuICAgICAgdGhpcy5zZXRDb250ZXh0RmlsbFN0YXRlXyh0aGlzLnRleHRGaWxsU3RhdGVfKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0U3Ryb2tlU3RhdGVfKSB7XG4gICAgICB0aGlzLnNldENvbnRleHRTdHJva2VTdGF0ZV8odGhpcy50ZXh0U3Ryb2tlU3RhdGVfKTtcbiAgICB9XG5cbiAgICB0aGlzLnNldENvbnRleHRUZXh0U3RhdGVfKHRoaXMudGV4dFN0YXRlXyk7XG4gICAgdmFyIHBpeGVsQ29vcmRpbmF0ZXMgPSB0cmFuc2Zvcm0yRChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIHRoaXMudHJhbnNmb3JtXywgdGhpcy5waXhlbENvb3JkaW5hdGVzXyk7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgIHZhciByb3RhdGlvbiA9IHRoaXMudGV4dFJvdGF0aW9uXztcblxuICAgIGlmICh0aGlzLnRleHRSb3RhdGVXaXRoVmlld18pIHtcbiAgICAgIHJvdGF0aW9uICs9IHRoaXMudmlld1JvdGF0aW9uXztcbiAgICB9XG5cbiAgICBmb3IgKDsgb2Zmc2V0IDwgZW5kOyBvZmZzZXQgKz0gc3RyaWRlKSB7XG4gICAgICB2YXIgeCA9IHBpeGVsQ29vcmRpbmF0ZXNbb2Zmc2V0XSArIHRoaXMudGV4dE9mZnNldFhfO1xuICAgICAgdmFyIHkgPSBwaXhlbENvb3JkaW5hdGVzW29mZnNldCArIDFdICsgdGhpcy50ZXh0T2Zmc2V0WV87XG5cbiAgICAgIGlmIChyb3RhdGlvbiAhPT0gMCB8fCB0aGlzLnRleHRTY2FsZV9bMF0gIT0gMSB8fCB0aGlzLnRleHRTY2FsZV9bMV0gIT0gMSkge1xuICAgICAgICB2YXIgbG9jYWxUcmFuc2Zvcm0gPSBjb21wb3NlVHJhbnNmb3JtKHRoaXMudG1wTG9jYWxUcmFuc2Zvcm1fLCB4LCB5LCAxLCAxLCByb3RhdGlvbiwgLXgsIC15KTtcbiAgICAgICAgY29udGV4dC5zZXRUcmFuc2Zvcm0uYXBwbHkoY29udGV4dCwgbG9jYWxUcmFuc2Zvcm0pO1xuICAgICAgICBjb250ZXh0LnRyYW5zbGF0ZSh4LCB5KTtcbiAgICAgICAgY29udGV4dC5zY2FsZSh0aGlzLnRleHRTY2FsZV9bMF0sIHRoaXMudGV4dFNjYWxlX1sxXSk7XG5cbiAgICAgICAgaWYgKHRoaXMudGV4dFN0cm9rZVN0YXRlXykge1xuICAgICAgICAgIGNvbnRleHQuc3Ryb2tlVGV4dCh0aGlzLnRleHRfLCAwLCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRleHRGaWxsU3RhdGVfKSB7XG4gICAgICAgICAgY29udGV4dC5maWxsVGV4dCh0aGlzLnRleHRfLCAwLCAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQuc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMudGV4dFN0cm9rZVN0YXRlXykge1xuICAgICAgICAgIGNvbnRleHQuc3Ryb2tlVGV4dCh0aGlzLnRleHRfLCB4LCB5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnRleHRGaWxsU3RhdGVfKSB7XG4gICAgICAgICAgY29udGV4dC5maWxsVGV4dCh0aGlzLnRleHRfLCB4LCB5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY2xvc2UgQ2xvc2UuXG4gICAqIEBwcml2YXRlXG4gICAqIEByZXR1cm4ge251bWJlcn0gZW5kIEVuZC5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUubW92ZVRvTGluZVRvXyA9IGZ1bmN0aW9uIChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGNsb3NlKSB7XG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgIHZhciBwaXhlbENvb3JkaW5hdGVzID0gdHJhbnNmb3JtMkQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCB0aGlzLnRyYW5zZm9ybV8sIHRoaXMucGl4ZWxDb29yZGluYXRlc18pO1xuICAgIGNvbnRleHQubW92ZVRvKHBpeGVsQ29vcmRpbmF0ZXNbMF0sIHBpeGVsQ29vcmRpbmF0ZXNbMV0pO1xuICAgIHZhciBsZW5ndGggPSBwaXhlbENvb3JkaW5hdGVzLmxlbmd0aDtcblxuICAgIGlmIChjbG9zZSkge1xuICAgICAgbGVuZ3RoIC09IDI7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDI7IGkgPCBsZW5ndGg7IGkgKz0gMikge1xuICAgICAgY29udGV4dC5saW5lVG8ocGl4ZWxDb29yZGluYXRlc1tpXSwgcGl4ZWxDb29yZGluYXRlc1tpICsgMV0pO1xuICAgIH1cblxuICAgIGlmIChjbG9zZSkge1xuICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZW5kO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZW5kcyBFbmRzLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7bnVtYmVyfSBFbmQuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdSaW5nc18gPSBmdW5jdGlvbiAoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgb2Zmc2V0ID0gdGhpcy5tb3ZlVG9MaW5lVG9fKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmRzW2ldLCBzdHJpZGUsIHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBjaXJjbGUgZ2VvbWV0cnkgaW50byB0aGUgY2FudmFzLiAgUmVuZGVyaW5nIGlzIGltbWVkaWF0ZSBhbmQgdXNlc1xuICAgKiB0aGUgY3VycmVudCBmaWxsIGFuZCBzdHJva2Ugc3R5bGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vQ2lyY2xlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IENpcmNsZSBnZW9tZXRyeS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3Q2lyY2xlID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgaWYgKCFpbnRlcnNlY3RzKHRoaXMuZXh0ZW50XywgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZmlsbFN0YXRlXyB8fCB0aGlzLnN0cm9rZVN0YXRlXykge1xuICAgICAgaWYgKHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgICB0aGlzLnNldENvbnRleHRGaWxsU3RhdGVfKHRoaXMuZmlsbFN0YXRlXyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0cm9rZVN0YXRlXykge1xuICAgICAgICB0aGlzLnNldENvbnRleHRTdHJva2VTdGF0ZV8odGhpcy5zdHJva2VTdGF0ZV8pO1xuICAgICAgfVxuXG4gICAgICB2YXIgcGl4ZWxDb29yZGluYXRlcyA9IHRyYW5zZm9ybUdlb20yRChnZW9tZXRyeSwgdGhpcy50cmFuc2Zvcm1fLCB0aGlzLnBpeGVsQ29vcmRpbmF0ZXNfKTtcbiAgICAgIHZhciBkeCA9IHBpeGVsQ29vcmRpbmF0ZXNbMl0gLSBwaXhlbENvb3JkaW5hdGVzWzBdO1xuICAgICAgdmFyIGR5ID0gcGl4ZWxDb29yZGluYXRlc1szXSAtIHBpeGVsQ29vcmRpbmF0ZXNbMV07XG4gICAgICB2YXIgcmFkaXVzID0gTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KTtcbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICBjb250ZXh0LmFyYyhwaXhlbENvb3JkaW5hdGVzWzBdLCBwaXhlbENvb3JkaW5hdGVzWzFdLCByYWRpdXMsIDAsIDIgKiBNYXRoLlBJKTtcblxuICAgICAgaWYgKHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgICBjb250ZXh0LmZpbGwoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhnZW9tZXRyeS5nZXRDZW50ZXIoKSwgMCwgMiwgMik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSByZW5kZXJpbmcgc3R5bGUuICBOb3RlIHRoYXQgc2luY2UgdGhpcyBpcyBhbiBpbW1lZGlhdGUgcmVuZGVyaW5nIEFQSSxcbiAgICogYW55IGB6SW5kZXhgIG9uIHRoZSBwcm92aWRlZCBzdHlsZSB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgVGhlIHJlbmRlcmluZyBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRTdHlsZSA9IGZ1bmN0aW9uIChzdHlsZSkge1xuICAgIHRoaXMuc2V0RmlsbFN0cm9rZVN0eWxlKHN0eWxlLmdldEZpbGwoKSwgc3R5bGUuZ2V0U3Ryb2tlKCkpO1xuICAgIHRoaXMuc2V0SW1hZ2VTdHlsZShzdHlsZS5nZXRJbWFnZSgpKTtcbiAgICB0aGlzLnNldFRleHRTdHlsZShzdHlsZS5nZXRUZXh0KCkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtfSB0cmFuc2Zvcm0gVHJhbnNmb3JtLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRUcmFuc2Zvcm0gPSBmdW5jdGlvbiAodHJhbnNmb3JtKSB7XG4gICAgdGhpcy50cmFuc2Zvcm1fID0gdHJhbnNmb3JtO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgZ2VvbWV0cnkgaW50byB0aGUgY2FudmFzLiAgQ2FsbFxuICAgKiB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9jYW52YXMvSW1tZWRpYXRlI3NldFN0eWxlfSBmaXJzdCB0byBzZXQgdGhlIHJlbmRlcmluZyBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBUaGUgZ2VvbWV0cnkgdG8gcmVuZGVyLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdHZW9tZXRyeSA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIHZhciB0eXBlID0gZ2VvbWV0cnkuZ2V0VHlwZSgpO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0lOVDpcbiAgICAgICAgdGhpcy5kcmF3UG9pbnQoXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2ludC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORzpcbiAgICAgICAgdGhpcy5kcmF3TGluZVN0cmluZyhcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9MWUdPTjpcbiAgICAgICAgdGhpcy5kcmF3UG9seWdvbihcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ6XG4gICAgICAgIHRoaXMuZHJhd011bHRpUG9pbnQoXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aVBvaW50LmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HOlxuICAgICAgICB0aGlzLmRyYXdNdWx0aUxpbmVTdHJpbmcoXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgICAgZ2VvbWV0cnkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTjpcbiAgICAgICAgdGhpcy5kcmF3TXVsdGlQb2x5Z29uKFxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICAgIGdlb21ldHJ5KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT046XG4gICAgICAgIHRoaXMuZHJhd0dlb21ldHJ5Q29sbGVjdGlvbihcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0dlb21ldHJ5Q29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIEdlb21ldHJ5VHlwZS5DSVJDTEU6XG4gICAgICAgIHRoaXMuZHJhd0NpcmNsZShcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0NpcmNsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICBnZW9tZXRyeSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBhIGZlYXR1cmUgaW50byB0aGUgY2FudmFzLiAgTm90ZSB0aGF0IGFueSBgekluZGV4YCBvbiB0aGUgcHJvdmlkZWRcbiAgICogc3R5bGUgd2lsbCBiZSBpZ25vcmVkIC0gZmVhdHVyZXMgYXJlIHJlbmRlcmVkIGltbWVkaWF0ZWx5IGluIHRoZSBvcmRlciB0aGF0XG4gICAqIHRoaXMgbWV0aG9kIGlzIGNhbGxlZC4gIElmIHlvdSBuZWVkIGB6SW5kZXhgIHN1cHBvcnQsIHlvdSBzaG91bGQgYmUgdXNpbmcgYW5cbiAgICoge0BsaW5rIG1vZHVsZTpvbC9sYXllci9WZWN0b3J+VmVjdG9yTGF5ZXJ9IGluc3RlYWQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd0ZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSwgc3R5bGUpIHtcbiAgICB2YXIgZ2VvbWV0cnkgPSBzdHlsZS5nZXRHZW9tZXRyeUZ1bmN0aW9uKCkoZmVhdHVyZSk7XG5cbiAgICBpZiAoIWdlb21ldHJ5IHx8ICFpbnRlcnNlY3RzKHRoaXMuZXh0ZW50XywgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTdHlsZShzdHlsZSk7XG4gICAgdGhpcy5kcmF3R2VvbWV0cnkoZ2VvbWV0cnkpO1xuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgR2VvbWV0cnlDb2xsZWN0aW9uIHRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZFxuICAgKiB1c2VzIHRoZSBjdXJyZW50IHN0eWxlcyBhcHByb3ByaWF0ZSBmb3IgZWFjaCBnZW9tZXRyeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0dlb21ldHJ5Q29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeSBjb2xsZWN0aW9uLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3R2VvbWV0cnlDb2xsZWN0aW9uID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSBnZW9tZXRyeS5nZXRHZW9tZXRyaWVzQXJyYXkoKTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdGhpcy5kcmF3R2VvbWV0cnkoZ2VvbWV0cmllc1tpXSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgUG9pbnQgZ2VvbWV0cnkgaW50byB0aGUgY2FudmFzLiAgUmVuZGVyaW5nIGlzIGltbWVkaWF0ZSBhbmQgdXNlc1xuICAgKiB0aGUgY3VycmVudCBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvaW50LmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBQb2ludCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd1BvaW50ID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgaWYgKHRoaXMuc3F1YXJlZFRvbGVyYW5jZV8pIHtcbiAgICAgIGdlb21ldHJ5ID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9Qb2ludC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuXG4gICAgaWYgKHRoaXMuaW1hZ2VfKSB7XG4gICAgICB0aGlzLmRyYXdJbWFnZXNfKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXh0XyAhPT0gJycpIHtcbiAgICAgIHRoaXMuZHJhd1RleHRfKGZsYXRDb29yZGluYXRlcywgMCwgZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgc3RyaWRlKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBNdWx0aVBvaW50IGdlb21ldHJ5ICBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZFxuICAgKiB1c2VzIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTXVsdGlQb2ludC5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgTXVsdGlQb2ludCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd011bHRpUG9pbnQgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9pbnQuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LnNpbXBsaWZ5VHJhbnNmb3JtZWQodGhpcy5zcXVhcmVkVG9sZXJhbmNlXywgdGhpcy51c2VyVHJhbnNmb3JtXyk7XG4gICAgfVxuXG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgIHZhciBzdHJpZGUgPSBnZW9tZXRyeS5nZXRTdHJpZGUoKTtcblxuICAgIGlmICh0aGlzLmltYWdlXykge1xuICAgICAgdGhpcy5kcmF3SW1hZ2VzXyhmbGF0Q29vcmRpbmF0ZXMsIDAsIGZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHN0cmlkZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhmbGF0Q29vcmRpbmF0ZXMsIDAsIGZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHN0cmlkZSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgTGluZVN0cmluZyBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZCB1c2VzXG4gICAqIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgTGluZVN0cmluZyBnZW9tZXRyeS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd0xpbmVTdHJpbmcgPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LnNpbXBsaWZ5VHJhbnNmb3JtZWQodGhpcy5zcXVhcmVkVG9sZXJhbmNlXywgdGhpcy51c2VyVHJhbnNmb3JtXyk7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzKHRoaXMuZXh0ZW50XywgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICB0aGlzLnNldENvbnRleHRTdHJva2VTdGF0ZV8odGhpcy5zdHJva2VTdGF0ZV8pO1xuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHRfO1xuICAgICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IGdlb21ldHJ5LmdldEZsYXRDb29yZGluYXRlcygpO1xuICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcbiAgICAgIHRoaXMubW92ZVRvTGluZVRvXyhmbGF0Q29vcmRpbmF0ZXMsIDAsIGZsYXRDb29yZGluYXRlcy5sZW5ndGgsIGdlb21ldHJ5LmdldFN0cmlkZSgpLCBmYWxzZSk7XG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRfICE9PSAnJykge1xuICAgICAgdmFyIGZsYXRNaWRwb2ludCA9IGdlb21ldHJ5LmdldEZsYXRNaWRwb2ludCgpO1xuICAgICAgdGhpcy5kcmF3VGV4dF8oZmxhdE1pZHBvaW50LCAwLCAyLCAyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgYSBNdWx0aUxpbmVTdHJpbmcgZ2VvbWV0cnkgaW50byB0aGUgY2FudmFzLiAgUmVuZGVyaW5nIGlzIGltbWVkaWF0ZVxuICAgKiBhbmQgdXNlcyB0aGUgY3VycmVudCBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpTGluZVN0cmluZy5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgTXVsdGlMaW5lU3RyaW5nIGdlb21ldHJ5LlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3TXVsdGlMaW5lU3RyaW5nID0gZnVuY3Rpb24gKGdlb21ldHJ5KSB7XG4gICAgaWYgKHRoaXMuc3F1YXJlZFRvbGVyYW5jZV8pIHtcbiAgICAgIGdlb21ldHJ5ID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LnNpbXBsaWZ5VHJhbnNmb3JtZWQodGhpcy5zcXVhcmVkVG9sZXJhbmNlXywgdGhpcy51c2VyVHJhbnNmb3JtXyk7XG4gICAgfVxuXG4gICAgdmFyIGdlb21ldHJ5RXh0ZW50ID0gZ2VvbWV0cnkuZ2V0RXh0ZW50KCk7XG5cbiAgICBpZiAoIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeUV4dGVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8pIHtcbiAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnN0cm9rZVN0YXRlXyk7XG4gICAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gZ2VvbWV0cnkuZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG4gICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgIHZhciBlbmRzID1cbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGdlb21ldHJ5LmdldEVuZHMoKTtcbiAgICAgIHZhciBzdHJpZGUgPSBnZW9tZXRyeS5nZXRTdHJpZGUoKTtcbiAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBvZmZzZXQgPSB0aGlzLm1vdmVUb0xpbmVUb18oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNbaV0sIHN0cmlkZSwgZmFsc2UpO1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRfICE9PSAnJykge1xuICAgICAgdmFyIGZsYXRNaWRwb2ludHMgPSBnZW9tZXRyeS5nZXRGbGF0TWlkcG9pbnRzKCk7XG4gICAgICB0aGlzLmRyYXdUZXh0XyhmbGF0TWlkcG9pbnRzLCAwLCBmbGF0TWlkcG9pbnRzLmxlbmd0aCwgMik7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmVuZGVyIGEgUG9seWdvbiBnZW9tZXRyeSBpbnRvIHRoZSBjYW52YXMuICBSZW5kZXJpbmcgaXMgaW1tZWRpYXRlIGFuZCB1c2VzXG4gICAqIHRoZSBjdXJyZW50IHN0eWxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgUG9seWdvbiBnZW9tZXRyeS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuZHJhd1BvbHlnb24gPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1BvbHlnb24uanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIGdlb21ldHJ5LnNpbXBsaWZ5VHJhbnNmb3JtZWQodGhpcy5zcXVhcmVkVG9sZXJhbmNlXywgdGhpcy51c2VyVHJhbnNmb3JtXyk7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzKHRoaXMuZXh0ZW50XywgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfIHx8IHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgaWYgKHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgICB0aGlzLnNldENvbnRleHRGaWxsU3RhdGVfKHRoaXMuZmlsbFN0YXRlXyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0cm9rZVN0YXRlXykge1xuICAgICAgICB0aGlzLnNldENvbnRleHRTdHJva2VTdGF0ZV8odGhpcy5zdHJva2VTdGF0ZV8pO1xuICAgICAgfVxuXG4gICAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgICAgdGhpcy5kcmF3UmluZ3NfKGdlb21ldHJ5LmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCksIDAsXG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICBnZW9tZXRyeS5nZXRFbmRzKCksIGdlb21ldHJ5LmdldFN0cmlkZSgpKTtcblxuICAgICAgaWYgKHRoaXMuZmlsbFN0YXRlXykge1xuICAgICAgICBjb250ZXh0LmZpbGwoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGV4dF8gIT09ICcnKSB7XG4gICAgICB2YXIgZmxhdEludGVyaW9yUG9pbnQgPSBnZW9tZXRyeS5nZXRGbGF0SW50ZXJpb3JQb2ludCgpO1xuICAgICAgdGhpcy5kcmF3VGV4dF8oZmxhdEludGVyaW9yUG9pbnQsIDAsIDIsIDIpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBNdWx0aVBvbHlnb24gZ2VvbWV0cnkgaW50byB0aGUgY2FudmFzLiAgUmVuZGVyaW5nIGlzIGltbWVkaWF0ZSBhbmRcbiAgICogdXNlcyB0aGUgY3VycmVudCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBNdWx0aVBvbHlnb24gZ2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdNdWx0aVBvbHlnb24gPSBmdW5jdGlvbiAoZ2VvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5zcXVhcmVkVG9sZXJhbmNlXykge1xuICAgICAgZ2VvbWV0cnkgPVxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9nZW9tL011bHRpUG9seWdvbi5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZCh0aGlzLnNxdWFyZWRUb2xlcmFuY2VfLCB0aGlzLnVzZXJUcmFuc2Zvcm1fKTtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHModGhpcy5leHRlbnRfLCBnZW9tZXRyeS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdHJva2VTdGF0ZV8gfHwgdGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICBpZiAodGhpcy5maWxsU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dEZpbGxTdGF0ZV8odGhpcy5maWxsU3RhdGVfKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Ryb2tlU3RhdGVfKSB7XG4gICAgICAgIHRoaXMuc2V0Q29udGV4dFN0cm9rZVN0YXRlXyh0aGlzLnN0cm9rZVN0YXRlXyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBnZW9tZXRyeS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpO1xuICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICB2YXIgZW5kc3MgPSBnZW9tZXRyeS5nZXRFbmRzcygpO1xuICAgICAgdmFyIHN0cmlkZSA9IGdlb21ldHJ5LmdldFN0cmlkZSgpO1xuICAgICAgY29udGV4dC5iZWdpblBhdGgoKTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgICAgICBvZmZzZXQgPSB0aGlzLmRyYXdSaW5nc18oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmZpbGxTdGF0ZV8pIHtcbiAgICAgICAgY29udGV4dC5maWxsKCk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnN0cm9rZVN0YXRlXykge1xuICAgICAgICBjb250ZXh0LnN0cm9rZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnRleHRfICE9PSAnJykge1xuICAgICAgdmFyIGZsYXRJbnRlcmlvclBvaW50cyA9IGdlb21ldHJ5LmdldEZsYXRJbnRlcmlvclBvaW50cygpO1xuICAgICAgdGhpcy5kcmF3VGV4dF8oZmxhdEludGVyaW9yUG9pbnRzLCAwLCBmbGF0SW50ZXJpb3JQb2ludHMubGVuZ3RoLCAyKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NhbnZhcy5qc1wiKS5GaWxsU3RhdGV9IGZpbGxTdGF0ZSBGaWxsIHN0YXRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRDb250ZXh0RmlsbFN0YXRlXyA9IGZ1bmN0aW9uIChmaWxsU3RhdGUpIHtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgdmFyIGNvbnRleHRGaWxsU3RhdGUgPSB0aGlzLmNvbnRleHRGaWxsU3RhdGVfO1xuXG4gICAgaWYgKCFjb250ZXh0RmlsbFN0YXRlKSB7XG4gICAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGZpbGxTdGF0ZS5maWxsU3R5bGU7XG4gICAgICB0aGlzLmNvbnRleHRGaWxsU3RhdGVfID0ge1xuICAgICAgICBmaWxsU3R5bGU6IGZpbGxTdGF0ZS5maWxsU3R5bGVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjb250ZXh0RmlsbFN0YXRlLmZpbGxTdHlsZSAhPSBmaWxsU3RhdGUuZmlsbFN0eWxlKSB7XG4gICAgICAgIGNvbnRleHRGaWxsU3RhdGUuZmlsbFN0eWxlID0gZmlsbFN0YXRlLmZpbGxTdHlsZTtcbiAgICAgICAgY29udGV4dC5maWxsU3R5bGUgPSBmaWxsU3RhdGUuZmlsbFN0eWxlO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlN0cm9rZVN0YXRlfSBzdHJva2VTdGF0ZSBTdHJva2Ugc3RhdGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldENvbnRleHRTdHJva2VTdGF0ZV8gPSBmdW5jdGlvbiAoc3Ryb2tlU3RhdGUpIHtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dF87XG4gICAgdmFyIGNvbnRleHRTdHJva2VTdGF0ZSA9IHRoaXMuY29udGV4dFN0cm9rZVN0YXRlXztcblxuICAgIGlmICghY29udGV4dFN0cm9rZVN0YXRlKSB7XG4gICAgICBjb250ZXh0LmxpbmVDYXAgPSBzdHJva2VTdGF0ZS5saW5lQ2FwO1xuXG4gICAgICBpZiAoY29udGV4dC5zZXRMaW5lRGFzaCkge1xuICAgICAgICBjb250ZXh0LnNldExpbmVEYXNoKHN0cm9rZVN0YXRlLmxpbmVEYXNoKTtcbiAgICAgICAgY29udGV4dC5saW5lRGFzaE9mZnNldCA9IHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0O1xuICAgICAgfVxuXG4gICAgICBjb250ZXh0LmxpbmVKb2luID0gc3Ryb2tlU3RhdGUubGluZUpvaW47XG4gICAgICBjb250ZXh0LmxpbmVXaWR0aCA9IHN0cm9rZVN0YXRlLmxpbmVXaWR0aDtcbiAgICAgIGNvbnRleHQubWl0ZXJMaW1pdCA9IHN0cm9rZVN0YXRlLm1pdGVyTGltaXQ7XG4gICAgICBjb250ZXh0LnN0cm9rZVN0eWxlID0gc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGU7XG4gICAgICB0aGlzLmNvbnRleHRTdHJva2VTdGF0ZV8gPSB7XG4gICAgICAgIGxpbmVDYXA6IHN0cm9rZVN0YXRlLmxpbmVDYXAsXG4gICAgICAgIGxpbmVEYXNoOiBzdHJva2VTdGF0ZS5saW5lRGFzaCxcbiAgICAgICAgbGluZURhc2hPZmZzZXQ6IHN0cm9rZVN0YXRlLmxpbmVEYXNoT2Zmc2V0LFxuICAgICAgICBsaW5lSm9pbjogc3Ryb2tlU3RhdGUubGluZUpvaW4sXG4gICAgICAgIGxpbmVXaWR0aDogc3Ryb2tlU3RhdGUubGluZVdpZHRoLFxuICAgICAgICBtaXRlckxpbWl0OiBzdHJva2VTdGF0ZS5taXRlckxpbWl0LFxuICAgICAgICBzdHJva2VTdHlsZTogc3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjb250ZXh0U3Ryb2tlU3RhdGUubGluZUNhcCAhPSBzdHJva2VTdGF0ZS5saW5lQ2FwKSB7XG4gICAgICAgIGNvbnRleHRTdHJva2VTdGF0ZS5saW5lQ2FwID0gc3Ryb2tlU3RhdGUubGluZUNhcDtcbiAgICAgICAgY29udGV4dC5saW5lQ2FwID0gc3Ryb2tlU3RhdGUubGluZUNhcDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHQuc2V0TGluZURhc2gpIHtcbiAgICAgICAgaWYgKCFlcXVhbHMoY29udGV4dFN0cm9rZVN0YXRlLmxpbmVEYXNoLCBzdHJva2VTdGF0ZS5saW5lRGFzaCkpIHtcbiAgICAgICAgICBjb250ZXh0LnNldExpbmVEYXNoKGNvbnRleHRTdHJva2VTdGF0ZS5saW5lRGFzaCA9IHN0cm9rZVN0YXRlLmxpbmVEYXNoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0U3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQgIT0gc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQpIHtcbiAgICAgICAgICBjb250ZXh0U3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQgPSBzdHJva2VTdGF0ZS5saW5lRGFzaE9mZnNldDtcbiAgICAgICAgICBjb250ZXh0LmxpbmVEYXNoT2Zmc2V0ID0gc3Ryb2tlU3RhdGUubGluZURhc2hPZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRTdHJva2VTdGF0ZS5saW5lSm9pbiAhPSBzdHJva2VTdGF0ZS5saW5lSm9pbikge1xuICAgICAgICBjb250ZXh0U3Ryb2tlU3RhdGUubGluZUpvaW4gPSBzdHJva2VTdGF0ZS5saW5lSm9pbjtcbiAgICAgICAgY29udGV4dC5saW5lSm9pbiA9IHN0cm9rZVN0YXRlLmxpbmVKb2luO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29udGV4dFN0cm9rZVN0YXRlLmxpbmVXaWR0aCAhPSBzdHJva2VTdGF0ZS5saW5lV2lkdGgpIHtcbiAgICAgICAgY29udGV4dFN0cm9rZVN0YXRlLmxpbmVXaWR0aCA9IHN0cm9rZVN0YXRlLmxpbmVXaWR0aDtcbiAgICAgICAgY29udGV4dC5saW5lV2lkdGggPSBzdHJva2VTdGF0ZS5saW5lV2lkdGg7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb250ZXh0U3Ryb2tlU3RhdGUubWl0ZXJMaW1pdCAhPSBzdHJva2VTdGF0ZS5taXRlckxpbWl0KSB7XG4gICAgICAgIGNvbnRleHRTdHJva2VTdGF0ZS5taXRlckxpbWl0ID0gc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdDtcbiAgICAgICAgY29udGV4dC5taXRlckxpbWl0ID0gc3Ryb2tlU3RhdGUubWl0ZXJMaW1pdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRTdHJva2VTdGF0ZS5zdHJva2VTdHlsZSAhPSBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZSkge1xuICAgICAgICBjb250ZXh0U3Ryb2tlU3RhdGUuc3Ryb2tlU3R5bGUgPSBzdHJva2VTdGF0ZS5zdHJva2VTdHlsZTtcbiAgICAgICAgY29udGV4dC5zdHJva2VTdHlsZSA9IHN0cm9rZVN0YXRlLnN0cm9rZVN0eWxlO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY2FudmFzLmpzXCIpLlRleHRTdGF0ZX0gdGV4dFN0YXRlIFRleHQgc3RhdGUuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIucHJvdG90eXBlLnNldENvbnRleHRUZXh0U3RhdGVfID0gZnVuY3Rpb24gKHRleHRTdGF0ZSkge1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0XztcbiAgICB2YXIgY29udGV4dFRleHRTdGF0ZSA9IHRoaXMuY29udGV4dFRleHRTdGF0ZV87XG4gICAgdmFyIHRleHRBbGlnbiA9IHRleHRTdGF0ZS50ZXh0QWxpZ24gPyB0ZXh0U3RhdGUudGV4dEFsaWduIDogZGVmYXVsdFRleHRBbGlnbjtcblxuICAgIGlmICghY29udGV4dFRleHRTdGF0ZSkge1xuICAgICAgY29udGV4dC5mb250ID0gdGV4dFN0YXRlLmZvbnQ7XG4gICAgICBjb250ZXh0LnRleHRBbGlnbiA9XG4gICAgICAvKiogQHR5cGUge0NhbnZhc1RleHRBbGlnbn0gKi9cbiAgICAgIHRleHRBbGlnbjtcbiAgICAgIGNvbnRleHQudGV4dEJhc2VsaW5lID1cbiAgICAgIC8qKiBAdHlwZSB7Q2FudmFzVGV4dEJhc2VsaW5lfSAqL1xuICAgICAgdGV4dFN0YXRlLnRleHRCYXNlbGluZTtcbiAgICAgIHRoaXMuY29udGV4dFRleHRTdGF0ZV8gPSB7XG4gICAgICAgIGZvbnQ6IHRleHRTdGF0ZS5mb250LFxuICAgICAgICB0ZXh0QWxpZ246IHRleHRBbGlnbixcbiAgICAgICAgdGV4dEJhc2VsaW5lOiB0ZXh0U3RhdGUudGV4dEJhc2VsaW5lXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY29udGV4dFRleHRTdGF0ZS5mb250ICE9IHRleHRTdGF0ZS5mb250KSB7XG4gICAgICAgIGNvbnRleHRUZXh0U3RhdGUuZm9udCA9IHRleHRTdGF0ZS5mb250O1xuICAgICAgICBjb250ZXh0LmZvbnQgPSB0ZXh0U3RhdGUuZm9udDtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRUZXh0U3RhdGUudGV4dEFsaWduICE9IHRleHRBbGlnbikge1xuICAgICAgICBjb250ZXh0VGV4dFN0YXRlLnRleHRBbGlnbiA9XG4gICAgICAgIC8qKiBAdHlwZSB7Q2FudmFzVGV4dEFsaWdufSAqL1xuICAgICAgICB0ZXh0QWxpZ247XG4gICAgICAgIGNvbnRleHQudGV4dEFsaWduID1cbiAgICAgICAgLyoqIEB0eXBlIHtDYW52YXNUZXh0QWxpZ259ICovXG4gICAgICAgIHRleHRBbGlnbjtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHRUZXh0U3RhdGUudGV4dEJhc2VsaW5lICE9IHRleHRTdGF0ZS50ZXh0QmFzZWxpbmUpIHtcbiAgICAgICAgY29udGV4dFRleHRTdGF0ZS50ZXh0QmFzZWxpbmUgPVxuICAgICAgICAvKiogQHR5cGUge0NhbnZhc1RleHRCYXNlbGluZX0gKi9cbiAgICAgICAgdGV4dFN0YXRlLnRleHRCYXNlbGluZTtcbiAgICAgICAgY29udGV4dC50ZXh0QmFzZWxpbmUgPVxuICAgICAgICAvKiogQHR5cGUge0NhbnZhc1RleHRCYXNlbGluZX0gKi9cbiAgICAgICAgdGV4dFN0YXRlLnRleHRCYXNlbGluZTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGZpbGwgYW5kIHN0cm9rZSBzdHlsZSBmb3Igc3Vic2VxdWVudCBkcmF3IG9wZXJhdGlvbnMuICBUbyBjbGVhclxuICAgKiBlaXRoZXIgZmlsbCBvciBzdHJva2Ugc3R5bGVzLCBwYXNzIG51bGwgZm9yIHRoZSBhcHByb3ByaWF0ZSBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvRmlsbC5qc1wiKS5kZWZhdWx0fSBmaWxsU3R5bGUgRmlsbCBzdHlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHJva2UuanNcIikuZGVmYXVsdH0gc3Ryb2tlU3R5bGUgU3Ryb2tlIHN0eWxlLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRGaWxsU3Ryb2tlU3R5bGUgPSBmdW5jdGlvbiAoZmlsbFN0eWxlLCBzdHJva2VTdHlsZSkge1xuICAgIGlmICghZmlsbFN0eWxlKSB7XG4gICAgICB0aGlzLmZpbGxTdGF0ZV8gPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZmlsbFN0eWxlQ29sb3IgPSBmaWxsU3R5bGUuZ2V0Q29sb3IoKTtcbiAgICAgIHRoaXMuZmlsbFN0YXRlXyA9IHtcbiAgICAgICAgZmlsbFN0eWxlOiBhc0NvbG9yTGlrZShmaWxsU3R5bGVDb2xvciA/IGZpbGxTdHlsZUNvbG9yIDogZGVmYXVsdEZpbGxTdHlsZSlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKCFzdHJva2VTdHlsZSkge1xuICAgICAgdGhpcy5zdHJva2VTdGF0ZV8gPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVDb2xvciA9IHN0cm9rZVN0eWxlLmdldENvbG9yKCk7XG4gICAgICB2YXIgc3Ryb2tlU3R5bGVMaW5lQ2FwID0gc3Ryb2tlU3R5bGUuZ2V0TGluZUNhcCgpO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlTGluZURhc2ggPSBzdHJva2VTdHlsZS5nZXRMaW5lRGFzaCgpO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlTGluZURhc2hPZmZzZXQgPSBzdHJva2VTdHlsZS5nZXRMaW5lRGFzaE9mZnNldCgpO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlTGluZUpvaW4gPSBzdHJva2VTdHlsZS5nZXRMaW5lSm9pbigpO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlV2lkdGggPSBzdHJva2VTdHlsZS5nZXRXaWR0aCgpO1xuICAgICAgdmFyIHN0cm9rZVN0eWxlTWl0ZXJMaW1pdCA9IHN0cm9rZVN0eWxlLmdldE1pdGVyTGltaXQoKTtcbiAgICAgIHRoaXMuc3Ryb2tlU3RhdGVfID0ge1xuICAgICAgICBsaW5lQ2FwOiBzdHJva2VTdHlsZUxpbmVDYXAgIT09IHVuZGVmaW5lZCA/IHN0cm9rZVN0eWxlTGluZUNhcCA6IGRlZmF1bHRMaW5lQ2FwLFxuICAgICAgICBsaW5lRGFzaDogc3Ryb2tlU3R5bGVMaW5lRGFzaCA/IHN0cm9rZVN0eWxlTGluZURhc2ggOiBkZWZhdWx0TGluZURhc2gsXG4gICAgICAgIGxpbmVEYXNoT2Zmc2V0OiBzdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0ID8gc3Ryb2tlU3R5bGVMaW5lRGFzaE9mZnNldCA6IGRlZmF1bHRMaW5lRGFzaE9mZnNldCxcbiAgICAgICAgbGluZUpvaW46IHN0cm9rZVN0eWxlTGluZUpvaW4gIT09IHVuZGVmaW5lZCA/IHN0cm9rZVN0eWxlTGluZUpvaW4gOiBkZWZhdWx0TGluZUpvaW4sXG4gICAgICAgIGxpbmVXaWR0aDogdGhpcy5waXhlbFJhdGlvXyAqIChzdHJva2VTdHlsZVdpZHRoICE9PSB1bmRlZmluZWQgPyBzdHJva2VTdHlsZVdpZHRoIDogZGVmYXVsdExpbmVXaWR0aCksXG4gICAgICAgIG1pdGVyTGltaXQ6IHN0cm9rZVN0eWxlTWl0ZXJMaW1pdCAhPT0gdW5kZWZpbmVkID8gc3Ryb2tlU3R5bGVNaXRlckxpbWl0IDogZGVmYXVsdE1pdGVyTGltaXQsXG4gICAgICAgIHN0cm9rZVN0eWxlOiBhc0NvbG9yTGlrZShzdHJva2VTdHlsZUNvbG9yID8gc3Ryb2tlU3R5bGVDb2xvciA6IGRlZmF1bHRTdHJva2VTdHlsZSlcbiAgICAgIH07XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBpbWFnZSBzdHlsZSBmb3Igc3Vic2VxdWVudCBkcmF3IG9wZXJhdGlvbnMuICBQYXNzIG51bGwgdG8gcmVtb3ZlXG4gICAqIHRoZSBpbWFnZSBzdHlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9JbWFnZS5qc1wiKS5kZWZhdWx0fSBpbWFnZVN0eWxlIEltYWdlIHN0eWxlLlxuICAgKi9cblxuXG4gIENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyLnByb3RvdHlwZS5zZXRJbWFnZVN0eWxlID0gZnVuY3Rpb24gKGltYWdlU3R5bGUpIHtcbiAgICBpZiAoIWltYWdlU3R5bGUpIHtcbiAgICAgIHRoaXMuaW1hZ2VfID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGltYWdlU2l6ZSA9IGltYWdlU3R5bGUuZ2V0U2l6ZSgpO1xuXG4gICAgICBpZiAoIWltYWdlU2l6ZSkge1xuICAgICAgICB0aGlzLmltYWdlXyA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaW1hZ2VBbmNob3IgPSBpbWFnZVN0eWxlLmdldEFuY2hvcigpOyAvLyBGSVhNRSBwaXhlbCByYXRpb1xuXG4gICAgICAgIHZhciBpbWFnZUltYWdlID0gaW1hZ2VTdHlsZS5nZXRJbWFnZSgxKTtcbiAgICAgICAgdmFyIGltYWdlT3JpZ2luID0gaW1hZ2VTdHlsZS5nZXRPcmlnaW4oKTtcbiAgICAgICAgdmFyIGltYWdlU2NhbGUgPSBpbWFnZVN0eWxlLmdldFNjYWxlQXJyYXkoKTtcbiAgICAgICAgdGhpcy5pbWFnZUFuY2hvclhfID0gaW1hZ2VBbmNob3JbMF07XG4gICAgICAgIHRoaXMuaW1hZ2VBbmNob3JZXyA9IGltYWdlQW5jaG9yWzFdO1xuICAgICAgICB0aGlzLmltYWdlSGVpZ2h0XyA9IGltYWdlU2l6ZVsxXTtcbiAgICAgICAgdGhpcy5pbWFnZV8gPSBpbWFnZUltYWdlO1xuICAgICAgICB0aGlzLmltYWdlT3BhY2l0eV8gPSBpbWFnZVN0eWxlLmdldE9wYWNpdHkoKTtcbiAgICAgICAgdGhpcy5pbWFnZU9yaWdpblhfID0gaW1hZ2VPcmlnaW5bMF07XG4gICAgICAgIHRoaXMuaW1hZ2VPcmlnaW5ZXyA9IGltYWdlT3JpZ2luWzFdO1xuICAgICAgICB0aGlzLmltYWdlUm90YXRlV2l0aFZpZXdfID0gaW1hZ2VTdHlsZS5nZXRSb3RhdGVXaXRoVmlldygpO1xuICAgICAgICB0aGlzLmltYWdlUm90YXRpb25fID0gaW1hZ2VTdHlsZS5nZXRSb3RhdGlvbigpO1xuICAgICAgICB0aGlzLmltYWdlU2NhbGVfID0gW3RoaXMucGl4ZWxSYXRpb18gKiBpbWFnZVNjYWxlWzBdLCB0aGlzLnBpeGVsUmF0aW9fICogaW1hZ2VTY2FsZVsxXV07XG4gICAgICAgIHRoaXMuaW1hZ2VXaWR0aF8gPSBpbWFnZVNpemVbMF07XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB0ZXh0IHN0eWxlIGZvciBzdWJzZXF1ZW50IGRyYXcgb3BlcmF0aW9ucy4gIFBhc3MgbnVsbCB0b1xuICAgKiByZW1vdmUgdGhlIHRleHQgc3R5bGUuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc3R5bGUvVGV4dC5qc1wiKS5kZWZhdWx0fSB0ZXh0U3R5bGUgVGV4dCBzdHlsZS5cbiAgICovXG5cblxuICBDYW52YXNJbW1lZGlhdGVSZW5kZXJlci5wcm90b3R5cGUuc2V0VGV4dFN0eWxlID0gZnVuY3Rpb24gKHRleHRTdHlsZSkge1xuICAgIGlmICghdGV4dFN0eWxlKSB7XG4gICAgICB0aGlzLnRleHRfID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB0ZXh0RmlsbFN0eWxlID0gdGV4dFN0eWxlLmdldEZpbGwoKTtcblxuICAgICAgaWYgKCF0ZXh0RmlsbFN0eWxlKSB7XG4gICAgICAgIHRoaXMudGV4dEZpbGxTdGF0ZV8gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHRleHRGaWxsU3R5bGVDb2xvciA9IHRleHRGaWxsU3R5bGUuZ2V0Q29sb3IoKTtcbiAgICAgICAgdGhpcy50ZXh0RmlsbFN0YXRlXyA9IHtcbiAgICAgICAgICBmaWxsU3R5bGU6IGFzQ29sb3JMaWtlKHRleHRGaWxsU3R5bGVDb2xvciA/IHRleHRGaWxsU3R5bGVDb2xvciA6IGRlZmF1bHRGaWxsU3R5bGUpXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGUgPSB0ZXh0U3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgICAgIGlmICghdGV4dFN0cm9rZVN0eWxlKSB7XG4gICAgICAgIHRoaXMudGV4dFN0cm9rZVN0YXRlXyA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlQ29sb3IgPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0Q29sb3IoKTtcbiAgICAgICAgdmFyIHRleHRTdHJva2VTdHlsZUxpbmVDYXAgPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TGluZUNhcCgpO1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlTGluZURhc2ggPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TGluZURhc2goKTtcbiAgICAgICAgdmFyIHRleHRTdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0ID0gdGV4dFN0cm9rZVN0eWxlLmdldExpbmVEYXNoT2Zmc2V0KCk7XG4gICAgICAgIHZhciB0ZXh0U3Ryb2tlU3R5bGVMaW5lSm9pbiA9IHRleHRTdHJva2VTdHlsZS5nZXRMaW5lSm9pbigpO1xuICAgICAgICB2YXIgdGV4dFN0cm9rZVN0eWxlV2lkdGggPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0V2lkdGgoKTtcbiAgICAgICAgdmFyIHRleHRTdHJva2VTdHlsZU1pdGVyTGltaXQgPSB0ZXh0U3Ryb2tlU3R5bGUuZ2V0TWl0ZXJMaW1pdCgpO1xuICAgICAgICB0aGlzLnRleHRTdHJva2VTdGF0ZV8gPSB7XG4gICAgICAgICAgbGluZUNhcDogdGV4dFN0cm9rZVN0eWxlTGluZUNhcCAhPT0gdW5kZWZpbmVkID8gdGV4dFN0cm9rZVN0eWxlTGluZUNhcCA6IGRlZmF1bHRMaW5lQ2FwLFxuICAgICAgICAgIGxpbmVEYXNoOiB0ZXh0U3Ryb2tlU3R5bGVMaW5lRGFzaCA/IHRleHRTdHJva2VTdHlsZUxpbmVEYXNoIDogZGVmYXVsdExpbmVEYXNoLFxuICAgICAgICAgIGxpbmVEYXNoT2Zmc2V0OiB0ZXh0U3Ryb2tlU3R5bGVMaW5lRGFzaE9mZnNldCA/IHRleHRTdHJva2VTdHlsZUxpbmVEYXNoT2Zmc2V0IDogZGVmYXVsdExpbmVEYXNoT2Zmc2V0LFxuICAgICAgICAgIGxpbmVKb2luOiB0ZXh0U3Ryb2tlU3R5bGVMaW5lSm9pbiAhPT0gdW5kZWZpbmVkID8gdGV4dFN0cm9rZVN0eWxlTGluZUpvaW4gOiBkZWZhdWx0TGluZUpvaW4sXG4gICAgICAgICAgbGluZVdpZHRoOiB0ZXh0U3Ryb2tlU3R5bGVXaWR0aCAhPT0gdW5kZWZpbmVkID8gdGV4dFN0cm9rZVN0eWxlV2lkdGggOiBkZWZhdWx0TGluZVdpZHRoLFxuICAgICAgICAgIG1pdGVyTGltaXQ6IHRleHRTdHJva2VTdHlsZU1pdGVyTGltaXQgIT09IHVuZGVmaW5lZCA/IHRleHRTdHJva2VTdHlsZU1pdGVyTGltaXQgOiBkZWZhdWx0TWl0ZXJMaW1pdCxcbiAgICAgICAgICBzdHJva2VTdHlsZTogYXNDb2xvckxpa2UodGV4dFN0cm9rZVN0eWxlQ29sb3IgPyB0ZXh0U3Ryb2tlU3R5bGVDb2xvciA6IGRlZmF1bHRTdHJva2VTdHlsZSlcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdmFyIHRleHRGb250ID0gdGV4dFN0eWxlLmdldEZvbnQoKTtcbiAgICAgIHZhciB0ZXh0T2Zmc2V0WCA9IHRleHRTdHlsZS5nZXRPZmZzZXRYKCk7XG4gICAgICB2YXIgdGV4dE9mZnNldFkgPSB0ZXh0U3R5bGUuZ2V0T2Zmc2V0WSgpO1xuICAgICAgdmFyIHRleHRSb3RhdGVXaXRoVmlldyA9IHRleHRTdHlsZS5nZXRSb3RhdGVXaXRoVmlldygpO1xuICAgICAgdmFyIHRleHRSb3RhdGlvbiA9IHRleHRTdHlsZS5nZXRSb3RhdGlvbigpO1xuICAgICAgdmFyIHRleHRTY2FsZSA9IHRleHRTdHlsZS5nZXRTY2FsZUFycmF5KCk7XG4gICAgICB2YXIgdGV4dFRleHQgPSB0ZXh0U3R5bGUuZ2V0VGV4dCgpO1xuICAgICAgdmFyIHRleHRUZXh0QWxpZ24gPSB0ZXh0U3R5bGUuZ2V0VGV4dEFsaWduKCk7XG4gICAgICB2YXIgdGV4dFRleHRCYXNlbGluZSA9IHRleHRTdHlsZS5nZXRUZXh0QmFzZWxpbmUoKTtcbiAgICAgIHRoaXMudGV4dFN0YXRlXyA9IHtcbiAgICAgICAgZm9udDogdGV4dEZvbnQgIT09IHVuZGVmaW5lZCA/IHRleHRGb250IDogZGVmYXVsdEZvbnQsXG4gICAgICAgIHRleHRBbGlnbjogdGV4dFRleHRBbGlnbiAhPT0gdW5kZWZpbmVkID8gdGV4dFRleHRBbGlnbiA6IGRlZmF1bHRUZXh0QWxpZ24sXG4gICAgICAgIHRleHRCYXNlbGluZTogdGV4dFRleHRCYXNlbGluZSAhPT0gdW5kZWZpbmVkID8gdGV4dFRleHRCYXNlbGluZSA6IGRlZmF1bHRUZXh0QmFzZWxpbmVcbiAgICAgIH07XG4gICAgICB0aGlzLnRleHRfID0gdGV4dFRleHQgIT09IHVuZGVmaW5lZCA/IHRleHRUZXh0IDogJyc7XG4gICAgICB0aGlzLnRleHRPZmZzZXRYXyA9IHRleHRPZmZzZXRYICE9PSB1bmRlZmluZWQgPyB0aGlzLnBpeGVsUmF0aW9fICogdGV4dE9mZnNldFggOiAwO1xuICAgICAgdGhpcy50ZXh0T2Zmc2V0WV8gPSB0ZXh0T2Zmc2V0WSAhPT0gdW5kZWZpbmVkID8gdGhpcy5waXhlbFJhdGlvXyAqIHRleHRPZmZzZXRZIDogMDtcbiAgICAgIHRoaXMudGV4dFJvdGF0ZVdpdGhWaWV3XyA9IHRleHRSb3RhdGVXaXRoVmlldyAhPT0gdW5kZWZpbmVkID8gdGV4dFJvdGF0ZVdpdGhWaWV3IDogZmFsc2U7XG4gICAgICB0aGlzLnRleHRSb3RhdGlvbl8gPSB0ZXh0Um90YXRpb24gIT09IHVuZGVmaW5lZCA/IHRleHRSb3RhdGlvbiA6IDA7XG4gICAgICB0aGlzLnRleHRTY2FsZV8gPSBbdGhpcy5waXhlbFJhdGlvXyAqIHRleHRTY2FsZVswXSwgdGhpcy5waXhlbFJhdGlvXyAqIHRleHRTY2FsZVsxXV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBDYW52YXNJbW1lZGlhdGVSZW5kZXJlcjtcbn0oVmVjdG9yQ29udGV4dCk7XG5cbmV4cG9ydCBkZWZhdWx0IENhbnZhc0ltbWVkaWF0ZVJlbmRlcmVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9JY29uQW5jaG9yVW5pdHNcbiAqL1xuXG4vKipcbiAqIEljb24gYW5jaG9yIHVuaXRzLiBPbmUgb2YgJ2ZyYWN0aW9uJywgJ3BpeGVscycuXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBBbmNob3IgaXMgYSBmcmFjdGlvblxuICAgKiBAYXBpXG4gICAqL1xuICBGUkFDVElPTjogJ2ZyYWN0aW9uJyxcblxuICAvKipcbiAgICogQW5jaG9yIGlzIGluIHBpeGVsc1xuICAgKiBAYXBpXG4gICAqL1xuICBQSVhFTFM6ICdwaXhlbHMnXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHlsZS9JY29uT3JpZ2luXG4gKi9cblxuLyoqXG4gKiBJY29uIG9yaWdpbi4gT25lIG9mICdib3R0b20tbGVmdCcsICdib3R0b20tcmlnaHQnLCAndG9wLWxlZnQnLCAndG9wLXJpZ2h0Jy5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIE9yaWdpbiBpcyBhdCBib3R0b20gbGVmdFxuICAgKiBAYXBpXG4gICAqL1xuICBCT1RUT01fTEVGVDogJ2JvdHRvbS1sZWZ0JyxcblxuICAvKipcbiAgICogT3JpZ2luIGlzIGF0IGJvdHRvbSByaWdodFxuICAgKiBAYXBpXG4gICAqL1xuICBCT1RUT01fUklHSFQ6ICdib3R0b20tcmlnaHQnLFxuXG4gIC8qKlxuICAgKiBPcmlnaW4gaXMgYXQgdG9wIGxlZnRcbiAgICogQGFwaVxuICAgKi9cbiAgVE9QX0xFRlQ6ICd0b3AtbGVmdCcsXG5cbiAgLyoqXG4gICAqIE9yaWdpbiBpcyBhdCB0b3AgcmlnaHRcbiAgICogQGFwaVxuICAgKi9cbiAgVE9QX1JJR0hUOiAndG9wLXJpZ2h0J1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL0ltYWdlQmFzZVxuICovXG5cblxuaW1wb3J0IEV2ZW50VGFyZ2V0IGZyb20gJy4vZXZlbnRzL1RhcmdldC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4vdXRpbC5qcyc7XG4vKipcbiAqIEBhYnN0cmFjdFxuICovXG5cbnZhciBJbWFnZUJhc2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSW1hZ2VCYXNlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfHVuZGVmaW5lZH0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH0gc3RhdGUgU3RhdGUuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gSW1hZ2VCYXNlKGV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgc3RhdGUpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5leHRlbnQgPSBleHRlbnQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxSYXRpb18gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuY2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoRXZlbnRUeXBlLkNIQU5HRSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICovXG5cblxuICBJbWFnZUJhc2UucHJvdG90eXBlLmdldEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnQ7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSBJbWFnZS5cbiAgICovXG5cblxuICBJbWFnZUJhc2UucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBQaXhlbFJhdGlvLlxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUuZ2V0UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5waXhlbFJhdGlvXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gUmVzb2x1dGlvbi5cbiAgICovXG5cblxuICBJbWFnZUJhc2UucHJvdG90eXBlLmdldFJlc29sdXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5yZXNvbHV0aW9uXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBTdGF0ZS5cbiAgICovXG5cblxuICBJbWFnZUJhc2UucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cblxuXG4gIEltYWdlQmFzZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuXG4gIHJldHVybiBJbWFnZUJhc2U7XG59KEV2ZW50VGFyZ2V0KTtcblxuZXhwb3J0IGRlZmF1bHQgSW1hZ2VCYXNlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvSW1hZ2VcbiAqL1xuXG5cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbWFnZUJhc2UgZnJvbSAnLi9JbWFnZUJhc2UuanMnO1xuaW1wb3J0IEltYWdlU3RhdGUgZnJvbSAnLi9JbWFnZVN0YXRlLmpzJztcbmltcG9ydCB7IElNQUdFX0RFQ09ERSB9IGZyb20gJy4vaGFzLmpzJztcbmltcG9ydCB7IGdldEhlaWdodCB9IGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGxpc3Rlbk9uY2UsIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuL2V2ZW50cy5qcyc7XG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhbiB7QGxpbmsgbW9kdWxlOm9sL0ltYWdlfkltYWdlfSBmb3IgdGhlIGltYWdlIGFuZCBhXG4gKiBge3N0cmluZ31gIGZvciB0aGUgc3JjIGFzIGFyZ3VtZW50cy4gSXQgaXMgc3VwcG9zZWQgdG8gbWFrZSBpdCBzbyB0aGVcbiAqIHVuZGVybHlpbmcgaW1hZ2Uge0BsaW5rIG1vZHVsZTpvbC9JbWFnZX5JbWFnZSNnZXRJbWFnZX0gaXMgYXNzaWduZWQgdGhlXG4gKiBjb250ZW50IHNwZWNpZmllZCBieSB0aGUgc3JjLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgZGVmYXVsdCBpc1xuICpcbiAqICAgICBmdW5jdGlvbihpbWFnZSwgc3JjKSB7XG4gKiAgICAgICBpbWFnZS5nZXRJbWFnZSgpLnNyYyA9IHNyYztcbiAqICAgICB9XG4gKlxuICogUHJvdmlkaW5nIGEgY3VzdG9tIGBpbWFnZUxvYWRGdW5jdGlvbmAgY2FuIGJlIHVzZWZ1bCB0byBsb2FkIGltYWdlcyB3aXRoXG4gKiBwb3N0IHJlcXVlc3RzIG9yIC0gaW4gZ2VuZXJhbCAtIHRocm91Z2ggWEhSIHJlcXVlc3RzLCB3aGVyZSB0aGUgc3JjIG9mIHRoZVxuICogaW1hZ2UgZWxlbWVudCB3b3VsZCBiZSBzZXQgdG8gYSBkYXRhIFVSSSB3aGVuIHRoZSBjb250ZW50IGlzIGxvYWRlZC5cbiAqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oSW1hZ2VXcmFwcGVyLCBzdHJpbmcpOiB2b2lkfSBMb2FkRnVuY3Rpb25cbiAqIEBhcGlcbiAqL1xuXG52YXIgSW1hZ2VXcmFwcGVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEltYWdlV3JhcHBlciwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgSW1hZ2Ugc291cmNlIFVSSS5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gICAqIEBwYXJhbSB7TG9hZEZ1bmN0aW9ufSBpbWFnZUxvYWRGdW5jdGlvbiBJbWFnZSBsb2FkIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEltYWdlV3JhcHBlcihleHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8sIHNyYywgY3Jvc3NPcmlnaW4sIGltYWdlTG9hZEZ1bmN0aW9uKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgZXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvLCBJbWFnZVN0YXRlLklETEUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5zcmNfID0gc3JjO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxDYW52YXNFbGVtZW50fEhUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLmltYWdlXyA9IG5ldyBJbWFnZSgpO1xuXG4gICAgaWYgKGNyb3NzT3JpZ2luICE9PSBudWxsKSB7XG4gICAgICBfdGhpcy5pbWFnZV8uY3Jvc3NPcmlnaW4gPSBjcm9zc09yaWdpbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P2Z1bmN0aW9uKCk6dm9pZH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMudW5saXN0ZW5fID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RhdGUgPSBJbWFnZVN0YXRlLklETEU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7TG9hZEZ1bmN0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW1hZ2VMb2FkRnVuY3Rpb25fID0gaW1hZ2VMb2FkRnVuY3Rpb247XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IEltYWdlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbWFnZV87XG4gIH07XG4gIC8qKlxuICAgKiBUcmFja3MgbG9hZGluZyBvciByZWFkIGVycm9ycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLmhhbmRsZUltYWdlRXJyb3JfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc3RhdGUgPSBJbWFnZVN0YXRlLkVSUk9SO1xuICAgIHRoaXMudW5saXN0ZW5JbWFnZV8oKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFRyYWNrcyBzdWNjZXNzZnVsIGltYWdlIGxvYWQuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSW1hZ2VXcmFwcGVyLnByb3RvdHlwZS5oYW5kbGVJbWFnZUxvYWRfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnJlc29sdXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5yZXNvbHV0aW9uID0gZ2V0SGVpZ2h0KHRoaXMuZXh0ZW50KSAvIHRoaXMuaW1hZ2VfLmhlaWdodDtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0gSW1hZ2VTdGF0ZS5MT0FERUQ7XG4gICAgdGhpcy51bmxpc3RlbkltYWdlXygpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCB0aGUgaW1hZ2Ugb3IgcmV0cnkgaWYgbG9hZGluZyBwcmV2aW91c2x5IGZhaWxlZC5cbiAgICogTG9hZGluZyBpcyB0YWtlbiBjYXJlIG9mIGJ5IHRoZSB0aWxlIHF1ZXVlLCBhbmQgY2FsbGluZyB0aGlzIG1ldGhvZCBpc1xuICAgKiBvbmx5IG5lZWRlZCBmb3IgcHJlbG9hZGluZyBvciBmb3IgcmVsb2FkaW5nIGluIGNhc2Ugb2YgYW4gZXJyb3IuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUgPT0gSW1hZ2VTdGF0ZS5JRExFIHx8IHRoaXMuc3RhdGUgPT0gSW1hZ2VTdGF0ZS5FUlJPUikge1xuICAgICAgdGhpcy5zdGF0ZSA9IEltYWdlU3RhdGUuTE9BRElORztcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgdGhpcy5pbWFnZUxvYWRGdW5jdGlvbl8odGhpcywgdGhpcy5zcmNfKTtcbiAgICAgIHRoaXMudW5saXN0ZW5fID0gbGlzdGVuSW1hZ2UodGhpcy5pbWFnZV8sIHRoaXMuaGFuZGxlSW1hZ2VMb2FkXy5iaW5kKHRoaXMpLCB0aGlzLmhhbmRsZUltYWdlRXJyb3JfLmJpbmQodGhpcykpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSBpbWFnZSBJbWFnZS5cbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLnNldEltYWdlID0gZnVuY3Rpb24gKGltYWdlKSB7XG4gICAgdGhpcy5pbWFnZV8gPSBpbWFnZTtcbiAgfTtcbiAgLyoqXG4gICAqIERpc2NhcmRzIGV2ZW50IGhhbmRsZXJzIHdoaWNoIGxpc3RlbiBmb3IgbG9hZCBjb21wbGV0aW9uIG9yIGVycm9ycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJbWFnZVdyYXBwZXIucHJvdG90eXBlLnVubGlzdGVuSW1hZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnVubGlzdGVuXykge1xuICAgICAgdGhpcy51bmxpc3Rlbl8oKTtcbiAgICAgIHRoaXMudW5saXN0ZW5fID0gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIEltYWdlV3JhcHBlcjtcbn0oSW1hZ2VCYXNlKTtcbi8qKlxuICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IGltYWdlIEltYWdlIGVsZW1lbnQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6YW55fSBsb2FkSGFuZGxlciBMb2FkIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbigpOmFueX0gZXJyb3JIYW5kbGVyIEVycm9yIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHJldHVybiB7ZnVuY3Rpb24oKTp2b2lkfSBDYWxsYmFjayB0byBzdG9wIGxpc3RlbmluZy5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0ZW5JbWFnZShpbWFnZSwgbG9hZEhhbmRsZXIsIGVycm9ySGFuZGxlcikge1xuICB2YXIgaW1nID1cbiAgLyoqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fSAqL1xuICBpbWFnZTtcblxuICBpZiAoaW1nLnNyYyAmJiBJTUFHRV9ERUNPREUpIHtcbiAgICB2YXIgcHJvbWlzZSA9IGltZy5kZWNvZGUoKTtcbiAgICB2YXIgbGlzdGVuaW5nXzEgPSB0cnVlO1xuXG4gICAgdmFyIHVubGlzdGVuID0gZnVuY3Rpb24gdW5saXN0ZW4oKSB7XG4gICAgICBsaXN0ZW5pbmdfMSA9IGZhbHNlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGxpc3RlbmluZ18xKSB7XG4gICAgICAgIGxvYWRIYW5kbGVyKCk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBpZiAobGlzdGVuaW5nXzEpIHtcbiAgICAgICAgLy8gRklYTUU6IFVuY29uZGl0aW9uYWxseSBjYWxsIGVycm9ySGFuZGxlcigpIHdoZW4gdGhpcyBidWcgaXMgZml4ZWQgdXBzdHJlYW06XG4gICAgICAgIC8vICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTk4NTI3XG4gICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRW5jb2RpbmdFcnJvcicgJiYgZXJyb3IubWVzc2FnZSA9PT0gJ0ludmFsaWQgaW1hZ2UgdHlwZS4nKSB7XG4gICAgICAgICAgbG9hZEhhbmRsZXIoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlcnJvckhhbmRsZXIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB1bmxpc3RlbjtcbiAgfVxuXG4gIHZhciBsaXN0ZW5lcktleXMgPSBbbGlzdGVuT25jZShpbWcsIEV2ZW50VHlwZS5MT0FELCBsb2FkSGFuZGxlciksIGxpc3Rlbk9uY2UoaW1nLCBFdmVudFR5cGUuRVJST1IsIGVycm9ySGFuZGxlcildO1xuICByZXR1cm4gZnVuY3Rpb24gdW5saXN0ZW4oKSB7XG4gICAgbGlzdGVuZXJLZXlzLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gIH07XG59XG5leHBvcnQgZGVmYXVsdCBJbWFnZVdyYXBwZXI7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ljb25JbWFnZVxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi4vZXZlbnRzL1RhcmdldC5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IEltYWdlU3RhdGUgZnJvbSAnLi4vSW1hZ2VTdGF0ZS5qcyc7XG5pbXBvcnQgeyBhc1N0cmluZyB9IGZyb20gJy4uL2NvbG9yLmpzJztcbmltcG9ydCB7IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCB9IGZyb20gJy4uL2RvbS5qcyc7XG5pbXBvcnQgeyBzaGFyZWQgYXMgaWNvbkltYWdlQ2FjaGUgfSBmcm9tICcuL0ljb25JbWFnZUNhY2hlLmpzJztcbmltcG9ydCB7IGxpc3RlbkltYWdlIH0gZnJvbSAnLi4vSW1hZ2UuanMnO1xuLyoqXG4gKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfVxuICovXG5cbnZhciB0YWludGVkVGVzdENvbnRleHQgPSBudWxsO1xuXG52YXIgSWNvbkltYWdlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEljb25JbWFnZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gaW1hZ2UgSW1hZ2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gc3JjIFNyYy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IHNpemUgU2l6ZS5cbiAgICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBpbWFnZVN0YXRlIEltYWdlIHN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfSBjb2xvciBDb2xvci5cbiAgICovXG5cblxuICBmdW5jdGlvbiBJY29uSW1hZ2UoaW1hZ2UsIHNyYywgc2l6ZSwgY3Jvc3NPcmlnaW4sIGltYWdlU3RhdGUsIGNvbG9yKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZV8gPSAhaW1hZ2UgPyBuZXcgSW1hZ2UoKSA6IGltYWdlO1xuXG4gICAgaWYgKGNyb3NzT3JpZ2luICE9PSBudWxsKSB7XG4gICAgICAvKiogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR9ICovXG4gICAgICBfdGhpcy5pbWFnZV8uY3Jvc3NPcmlnaW4gPSBjcm9zc09yaWdpbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PG51bWJlciwgSFRNTENhbnZhc0VsZW1lbnQ+fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5jYW52YXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb2xvcl8gPSBjb2xvcjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/ZnVuY3Rpb24oKTp2b2lkfVxuICAgICAqL1xuXG4gICAgX3RoaXMudW5saXN0ZW5fID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9JbWFnZVN0YXRlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZVN0YXRlXyA9IGltYWdlU3RhdGU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc2l6ZV8gPSBzaXplO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zcmNfID0gc3JjO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBfdGhpcy50YWludGVkXztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBpbWFnZSBjYW52YXMgaXMgdGFpbnRlZC5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmlzVGFpbnRlZF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMudGFpbnRlZF8gPT09IHVuZGVmaW5lZCAmJiB0aGlzLmltYWdlU3RhdGVfID09PSBJbWFnZVN0YXRlLkxPQURFRCkge1xuICAgICAgaWYgKCF0YWludGVkVGVzdENvbnRleHQpIHtcbiAgICAgICAgdGFpbnRlZFRlc3RDb250ZXh0ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEpO1xuICAgICAgfVxuXG4gICAgICB0YWludGVkVGVzdENvbnRleHQuZHJhd0ltYWdlKHRoaXMuaW1hZ2VfLCAwLCAwKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdGFpbnRlZFRlc3RDb250ZXh0LmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKTtcbiAgICAgICAgdGhpcy50YWludGVkXyA9IGZhbHNlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0YWludGVkVGVzdENvbnRleHQgPSBudWxsO1xuICAgICAgICB0aGlzLnRhaW50ZWRfID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy50YWludGVkXyA9PT0gdHJ1ZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5kaXNwYXRjaENoYW5nZUV2ZW50XyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoRXZlbnRUeXBlLkNIQU5HRSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuaGFuZGxlSW1hZ2VFcnJvcl8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5pbWFnZVN0YXRlXyA9IEltYWdlU3RhdGUuRVJST1I7XG4gICAgdGhpcy51bmxpc3RlbkltYWdlXygpO1xuICAgIHRoaXMuZGlzcGF0Y2hDaGFuZ2VFdmVudF8oKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5oYW5kbGVJbWFnZUxvYWRfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaW1hZ2VTdGF0ZV8gPSBJbWFnZVN0YXRlLkxPQURFRDtcblxuICAgIGlmICh0aGlzLnNpemVfKSB7XG4gICAgICB0aGlzLmltYWdlXy53aWR0aCA9IHRoaXMuc2l6ZV9bMF07XG4gICAgICB0aGlzLmltYWdlXy5oZWlnaHQgPSB0aGlzLnNpemVfWzFdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNpemVfID0gW3RoaXMuaW1hZ2VfLndpZHRoLCB0aGlzLmltYWdlXy5oZWlnaHRdO1xuICAgIH1cblxuICAgIHRoaXMudW5saXN0ZW5JbWFnZV8oKTtcbiAgICB0aGlzLmRpc3BhdGNoQ2hhbmdlRXZlbnRfKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gSW1hZ2Ugb3IgQ2FudmFzIGVsZW1lbnQuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgdGhpcy5yZXBsYWNlQ29sb3JfKHBpeGVsUmF0aW8pO1xuICAgIHJldHVybiB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpb10gPyB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpb10gOiB0aGlzLmltYWdlXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEltYWdlIG9yIENhbnZhcyBlbGVtZW50LlxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuZ2V0UGl4ZWxSYXRpbyA9IGZ1bmN0aW9uIChwaXhlbFJhdGlvKSB7XG4gICAgdGhpcy5yZXBsYWNlQ29sb3JfKHBpeGVsUmF0aW8pO1xuICAgIHJldHVybiB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpb10gPyBwaXhlbFJhdGlvIDogMTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH0gSW1hZ2Ugc3RhdGUuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5nZXRJbWFnZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlU3RhdGVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gSW1hZ2UgZWxlbWVudC5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmdldEhpdERldGVjdGlvbkltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5oaXREZXRlY3Rpb25JbWFnZV8pIHtcbiAgICAgIGlmICh0aGlzLmlzVGFpbnRlZF8oKSkge1xuICAgICAgICB2YXIgd2lkdGggPSB0aGlzLnNpemVfWzBdO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gdGhpcy5zaXplX1sxXTtcbiAgICAgICAgdmFyIGNvbnRleHQgPSBjcmVhdGVDYW52YXNDb250ZXh0MkQod2lkdGgsIGhlaWdodCk7XG4gICAgICAgIGNvbnRleHQuZmlsbFJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VfID0gY29udGV4dC5jYW52YXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlXyA9IHRoaXMuaW1hZ2VfO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmhpdERldGVjdGlvbkltYWdlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc2l6ZSBvZiB0aGUgaWNvbiAoaW4gcGl4ZWxzKS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBJbWFnZSBzaXplLlxuICAgKi9cblxuXG4gIEljb25JbWFnZS5wcm90b3R5cGUuZ2V0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zaXplXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IEltYWdlIHNyYy5cbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLmdldFNyYyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zcmNfO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmltYWdlU3RhdGVfID09IEltYWdlU3RhdGUuSURMRSkge1xuICAgICAgdGhpcy5pbWFnZVN0YXRlXyA9IEltYWdlU3RhdGUuTE9BRElORztcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLyoqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fSAqL1xuICAgICAgICB0aGlzLmltYWdlXy5zcmMgPSB0aGlzLnNyY187XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlSW1hZ2VFcnJvcl8oKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy51bmxpc3Rlbl8gPSBsaXN0ZW5JbWFnZSh0aGlzLmltYWdlXywgdGhpcy5oYW5kbGVJbWFnZUxvYWRfLmJpbmQodGhpcyksIHRoaXMuaGFuZGxlSW1hZ2VFcnJvcl8uYmluZCh0aGlzKSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSWNvbkltYWdlLnByb3RvdHlwZS5yZXBsYWNlQ29sb3JfID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICBpZiAoIXRoaXMuY29sb3JfIHx8IHRoaXMuY2FudmFzX1twaXhlbFJhdGlvXSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICB0aGlzLmNhbnZhc19bcGl4ZWxSYXRpb10gPSBjYW52YXM7XG4gICAgY2FudmFzLndpZHRoID0gTWF0aC5jZWlsKHRoaXMuaW1hZ2VfLndpZHRoICogcGl4ZWxSYXRpbyk7XG4gICAgY2FudmFzLmhlaWdodCA9IE1hdGguY2VpbCh0aGlzLmltYWdlXy5oZWlnaHQgKiBwaXhlbFJhdGlvKTtcbiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgY3R4LnNjYWxlKHBpeGVsUmF0aW8sIHBpeGVsUmF0aW8pO1xuICAgIGN0eC5kcmF3SW1hZ2UodGhpcy5pbWFnZV8sIDAsIDApO1xuICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnbXVsdGlwbHknOyAvLyBJbnRlcm5ldCBFeHBsb3JlciAxMSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBtdWx0aXBseSBvcGVyYXRpb24uXG4gICAgLy8gSWYgdGhlIGNhbnZhcyBpcyB0YWludGVkIGluIEludGVybmV0IEV4cGxvcmVyIHRoaXMgc3RpbGwgcHJvZHVjZXNcbiAgICAvLyBhIHNvbGlkIGNvbG9yIGltYWdlIHdpdGggdGhlIHNoYXBlIG9mIHRoZSBpY29uLlxuXG4gICAgaWYgKGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPT09ICdtdWx0aXBseScgfHwgdGhpcy5pc1RhaW50ZWRfKCkpIHtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBhc1N0cmluZyh0aGlzLmNvbG9yXyk7XG4gICAgICBjdHguZmlsbFJlY3QoMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICAgIGN0eC5nbG9iYWxDb21wb3NpdGVPcGVyYXRpb24gPSAnZGVzdGluYXRpb24taW4nO1xuICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLmltYWdlXywgMCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBpbWdEYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgICAgdmFyIGRhdGEgPSBpbWdEYXRhLmRhdGE7XG4gICAgICB2YXIgciA9IHRoaXMuY29sb3JfWzBdIC8gMjU1LjA7XG4gICAgICB2YXIgZyA9IHRoaXMuY29sb3JfWzFdIC8gMjU1LjA7XG4gICAgICB2YXIgYiA9IHRoaXMuY29sb3JfWzJdIC8gMjU1LjA7XG4gICAgICB2YXIgYSA9IHRoaXMuY29sb3JfWzNdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBkYXRhLmxlbmd0aDsgaSA8IGlpOyBpICs9IDQpIHtcbiAgICAgICAgZGF0YVtpXSAqPSByO1xuICAgICAgICBkYXRhW2kgKyAxXSAqPSBnO1xuICAgICAgICBkYXRhW2kgKyAyXSAqPSBiO1xuICAgICAgICBkYXRhW2kgKyAzXSAqPSBhO1xuICAgICAgfVxuXG4gICAgICBjdHgucHV0SW1hZ2VEYXRhKGltZ0RhdGEsIDAsIDApO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIERpc2NhcmRzIGV2ZW50IGhhbmRsZXJzIHdoaWNoIGxpc3RlbiBmb3IgbG9hZCBjb21wbGV0aW9uIG9yIGVycm9ycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJY29uSW1hZ2UucHJvdG90eXBlLnVubGlzdGVuSW1hZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnVubGlzdGVuXykge1xuICAgICAgdGhpcy51bmxpc3Rlbl8oKTtcbiAgICAgIHRoaXMudW5saXN0ZW5fID0gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIEljb25JbWFnZTtcbn0oRXZlbnRUYXJnZXQpO1xuLyoqXG4gKiBAcGFyYW0ge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9IGltYWdlIEltYWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNyYyBTcmMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBTaXplLlxuICogQHBhcmFtIHs/c3RyaW5nfSBjcm9zc09yaWdpbiBDcm9zcyBvcmlnaW4uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH0gaW1hZ2VTdGF0ZSBJbWFnZSBzdGF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J9IGNvbG9yIENvbG9yLlxuICogQHJldHVybiB7SWNvbkltYWdlfSBJY29uIGltYWdlLlxuICovXG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldChpbWFnZSwgc3JjLCBzaXplLCBjcm9zc09yaWdpbiwgaW1hZ2VTdGF0ZSwgY29sb3IpIHtcbiAgdmFyIGljb25JbWFnZSA9IGljb25JbWFnZUNhY2hlLmdldChzcmMsIGNyb3NzT3JpZ2luLCBjb2xvcik7XG5cbiAgaWYgKCFpY29uSW1hZ2UpIHtcbiAgICBpY29uSW1hZ2UgPSBuZXcgSWNvbkltYWdlKGltYWdlLCBzcmMsIHNpemUsIGNyb3NzT3JpZ2luLCBpbWFnZVN0YXRlLCBjb2xvcik7XG4gICAgaWNvbkltYWdlQ2FjaGUuc2V0KHNyYywgY3Jvc3NPcmlnaW4sIGNvbG9yLCBpY29uSW1hZ2UpO1xuICB9XG5cbiAgcmV0dXJuIGljb25JbWFnZTtcbn1cbmV4cG9ydCBkZWZhdWx0IEljb25JbWFnZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL0ljb25cbiAqL1xuXG5cbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi4vZXZlbnRzL0V2ZW50VHlwZS5qcyc7XG5pbXBvcnQgSWNvbkFuY2hvclVuaXRzIGZyb20gJy4vSWNvbkFuY2hvclVuaXRzLmpzJztcbmltcG9ydCBJY29uT3JpZ2luIGZyb20gJy4vSWNvbk9yaWdpbi5qcyc7XG5pbXBvcnQgSW1hZ2VTdGF0ZSBmcm9tICcuLi9JbWFnZVN0YXRlLmpzJztcbmltcG9ydCBJbWFnZVN0eWxlIGZyb20gJy4vSW1hZ2UuanMnO1xuaW1wb3J0IHsgYXNBcnJheSB9IGZyb20gJy4uL2NvbG9yLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgZ2V0IGFzIGdldEljb25JbWFnZSB9IGZyb20gJy4vSWNvbkltYWdlLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uL3V0aWwuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFthbmNob3I9WzAuNSwgMC41XV0gQW5jaG9yLiBEZWZhdWx0IHZhbHVlIGlzIHRoZSBpY29uIGNlbnRlci5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9JY29uT3JpZ2luLmpzXCIpLmRlZmF1bHR9IFthbmNob3JPcmlnaW49J3RvcC1sZWZ0J10gT3JpZ2luIG9mIHRoZSBhbmNob3I6IGBib3R0b20tbGVmdGAsIGBib3R0b20tcmlnaHRgLFxuICogYHRvcC1sZWZ0YCBvciBgdG9wLXJpZ2h0YC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9JY29uQW5jaG9yVW5pdHMuanNcIikuZGVmYXVsdH0gW2FuY2hvclhVbml0cz0nZnJhY3Rpb24nXSBVbml0cyBpbiB3aGljaCB0aGUgYW5jaG9yIHggdmFsdWUgaXNcbiAqIHNwZWNpZmllZC4gQSB2YWx1ZSBvZiBgJ2ZyYWN0aW9uJ2AgaW5kaWNhdGVzIHRoZSB4IHZhbHVlIGlzIGEgZnJhY3Rpb24gb2YgdGhlIGljb24uIEEgdmFsdWUgb2YgYCdwaXhlbHMnYCBpbmRpY2F0ZXNcbiAqIHRoZSB4IHZhbHVlIGluIHBpeGVscy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9JY29uQW5jaG9yVW5pdHMuanNcIikuZGVmYXVsdH0gW2FuY2hvcllVbml0cz0nZnJhY3Rpb24nXSBVbml0cyBpbiB3aGljaCB0aGUgYW5jaG9yIHkgdmFsdWUgaXNcbiAqIHNwZWNpZmllZC4gQSB2YWx1ZSBvZiBgJ2ZyYWN0aW9uJ2AgaW5kaWNhdGVzIHRoZSB5IHZhbHVlIGlzIGEgZnJhY3Rpb24gb2YgdGhlIGljb24uIEEgdmFsdWUgb2YgYCdwaXhlbHMnYCBpbmRpY2F0ZXNcbiAqIHRoZSB5IHZhbHVlIGluIHBpeGVscy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29sb3IuanNcIikuQ29sb3J8c3RyaW5nfSBbY29sb3JdIENvbG9yIHRvIHRpbnQgdGhlIGljb24uIElmIG5vdCBzcGVjaWZpZWQsXG4gKiB0aGUgaWNvbiB3aWxsIGJlIGxlZnQgYXMgaXMuXG4gKiBAcHJvcGVydHkge251bGx8c3RyaW5nfSBbY3Jvc3NPcmlnaW5dIFRoZSBgY3Jvc3NPcmlnaW5gIGF0dHJpYnV0ZSBmb3IgbG9hZGVkIGltYWdlcy4gTm90ZSB0aGF0IHlvdSBtdXN0IHByb3ZpZGUgYVxuICogYGNyb3NzT3JpZ2luYCB2YWx1ZSBpZiB5b3Ugd2FudCB0byBhY2Nlc3MgcGl4ZWwgZGF0YSB3aXRoIHRoZSBDYW52YXMgcmVuZGVyZXIuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9DT1JTX2VuYWJsZWRfaW1hZ2UgZm9yIG1vcmUgZGV0YWlsLlxuICogQHByb3BlcnR5IHtIVE1MSW1hZ2VFbGVtZW50fEhUTUxDYW52YXNFbGVtZW50fSBbaW1nXSBJbWFnZSBvYmplY3QgZm9yIHRoZSBpY29uLiBJZiB0aGUgYHNyY2Agb3B0aW9uIGlzIG5vdCBwcm92aWRlZCB0aGVuIHRoZVxuICogcHJvdmlkZWQgaW1hZ2UgbXVzdCBhbHJlYWR5IGJlIGxvYWRlZC4gQW5kIGluIHRoYXQgY2FzZSwgaXQgaXMgcmVxdWlyZWRcbiAqIHRvIHByb3ZpZGUgdGhlIHNpemUgb2YgdGhlIGltYWdlLCB3aXRoIHRoZSBgaW1nU2l6ZWAgb3B0aW9uLlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbb2Zmc2V0PVswLCAwXV0gT2Zmc2V0LCB3aGljaCwgdG9nZXRoZXIgd2l0aCB0aGUgc2l6ZSBhbmQgdGhlIG9mZnNldCBvcmlnaW4sIGRlZmluZSB0aGVcbiAqIHN1Yi1yZWN0YW5nbGUgdG8gdXNlIGZyb20gdGhlIG9yaWdpbmFsIGljb24gaW1hZ2UuXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtkaXNwbGFjZW1lbnQ9WzAsMF1dIERpc3BsYWNlbWVudCB0aGUgaWNvblxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ljb25PcmlnaW4uanNcIikuZGVmYXVsdH0gW29mZnNldE9yaWdpbj0ndG9wLWxlZnQnXSBPcmlnaW4gb2YgdGhlIG9mZnNldDogYGJvdHRvbS1sZWZ0YCwgYGJvdHRvbS1yaWdodGAsXG4gKiBgdG9wLWxlZnRgIG9yIGB0b3AtcmlnaHRgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtvcGFjaXR5PTFdIE9wYWNpdHkgb2YgdGhlIGljb24uXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFtzY2FsZT0xXSBTY2FsZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3JvdGF0ZVdpdGhWaWV3PWZhbHNlXSBXaGV0aGVyIHRvIHJvdGF0ZSB0aGUgaWNvbiB3aXRoIHRoZSB2aWV3LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyb3RhdGlvbj0wXSBSb3RhdGlvbiBpbiByYWRpYW5zIChwb3NpdGl2ZSByb3RhdGlvbiBjbG9ja3dpc2UpLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFtzaXplXSBJY29uIHNpemUgaW4gcGl4ZWwuIENhbiBiZSB1c2VkIHRvZ2V0aGVyIHdpdGggYG9mZnNldGAgdG8gZGVmaW5lIHRoZVxuICogc3ViLXJlY3RhbmdsZSB0byB1c2UgZnJvbSB0aGUgb3JpZ2luIChzcHJpdGUpIGljb24gaW1hZ2UuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gW2ltZ1NpemVdIEltYWdlIHNpemUgaW4gcGl4ZWxzLiBPbmx5IHJlcXVpcmVkIGlmIGBpbWdgIGlzIHNldCBhbmQgYHNyY2AgaXMgbm90LCBhbmRcbiAqIGZvciBTVkcgaW1hZ2VzIGluIEludGVybmV0IEV4cGxvcmVyIDExLiBUaGUgcHJvdmlkZWQgYGltZ1NpemVgIG5lZWRzIHRvIG1hdGNoIHRoZSBhY3R1YWwgc2l6ZSBvZiB0aGUgaW1hZ2UuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3NyY10gSW1hZ2Ugc291cmNlIFVSSS5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFNldCBpY29uIHN0eWxlIGZvciB2ZWN0b3IgZmVhdHVyZXMuXG4gKiBAYXBpXG4gKi9cblxudmFyIEljb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoSWNvbiwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gSWNvbihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zIHx8IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB2YXIgb3BhY2l0eSA9IG9wdGlvbnMub3BhY2l0eSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vcGFjaXR5IDogMTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdmFyIHJvdGF0aW9uID0gb3B0aW9ucy5yb3RhdGlvbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5yb3RhdGlvbiA6IDA7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICB2YXIgc2NhbGUgPSBvcHRpb25zLnNjYWxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnNjYWxlIDogMTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHZhciByb3RhdGVXaXRoVmlldyA9IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucm90YXRlV2l0aFZpZXcgOiBmYWxzZTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIG9wYWNpdHk6IG9wYWNpdHksXG4gICAgICByb3RhdGlvbjogcm90YXRpb24sXG4gICAgICBzY2FsZTogc2NhbGUsXG4gICAgICBkaXNwbGFjZW1lbnQ6IG9wdGlvbnMuZGlzcGxhY2VtZW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmRpc3BsYWNlbWVudCA6IFswLCAwXSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiByb3RhdGVXaXRoVmlld1xuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLmFuY2hvcl8gPSBvcHRpb25zLmFuY2hvciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5hbmNob3IgOiBbMC41LCAwLjVdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5ub3JtYWxpemVkQW5jaG9yXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JY29uT3JpZ2luLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5hbmNob3JPcmlnaW5fID0gb3B0aW9ucy5hbmNob3JPcmlnaW4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYW5jaG9yT3JpZ2luIDogSWNvbk9yaWdpbi5UT1BfTEVGVDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ljb25BbmNob3JVbml0cy5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yWFVuaXRzXyA9IG9wdGlvbnMuYW5jaG9yWFVuaXRzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFuY2hvclhVbml0cyA6IEljb25BbmNob3JVbml0cy5GUkFDVElPTjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL0ljb25BbmNob3JVbml0cy5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5jaG9yWVVuaXRzXyA9IG9wdGlvbnMuYW5jaG9yWVVuaXRzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmFuY2hvcllVbml0cyA6IEljb25BbmNob3JVbml0cy5GUkFDVElPTjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMuY3Jvc3NPcmlnaW5fID0gb3B0aW9ucy5jcm9zc09yaWdpbiAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jcm9zc09yaWdpbiA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cbiAgICB2YXIgaW1hZ2UgPSBvcHRpb25zLmltZyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbWcgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICovXG5cbiAgICB2YXIgaW1nU2l6ZSA9IG9wdGlvbnMuaW1nU2l6ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbWdTaXplIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHZhciBzcmMgPSBvcHRpb25zLnNyYztcbiAgICBhc3NlcnQoIShzcmMgIT09IHVuZGVmaW5lZCAmJiBpbWFnZSksIDQpOyAvLyBgaW1hZ2VgIGFuZCBgc3JjYCBjYW5ub3QgYmUgcHJvdmlkZWQgYXQgdGhlIHNhbWUgdGltZVxuXG4gICAgYXNzZXJ0KCFpbWFnZSB8fCBpbWFnZSAmJiBpbWdTaXplLCA1KTsgLy8gYGltZ1NpemVgIG11c3QgYmUgc2V0IHdoZW4gYGltYWdlYCBpcyBwcm92aWRlZFxuXG4gICAgaWYgKChzcmMgPT09IHVuZGVmaW5lZCB8fCBzcmMubGVuZ3RoID09PSAwKSAmJiBpbWFnZSkge1xuICAgICAgc3JjID1cbiAgICAgIC8qKiBAdHlwZSB7SFRNTEltYWdlRWxlbWVudH0gKi9cbiAgICAgIGltYWdlLnNyYyB8fCBnZXRVaWQoaW1hZ2UpO1xuICAgIH1cblxuICAgIGFzc2VydChzcmMgIT09IHVuZGVmaW5lZCAmJiBzcmMubGVuZ3RoID4gMCwgNik7IC8vIEEgZGVmaW5lZCBhbmQgbm9uLWVtcHR5IGBzcmNgIG9yIGBpbWFnZWAgbXVzdCBiZSBwcm92aWRlZFxuXG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL0ltYWdlU3RhdGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHZhciBpbWFnZVN0YXRlID0gb3B0aW9ucy5zcmMgIT09IHVuZGVmaW5lZCA/IEltYWdlU3RhdGUuSURMRSA6IEltYWdlU3RhdGUuTE9BREVEO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfVxuICAgICAqL1xuXG4gICAgX3RoaXMuY29sb3JfID0gb3B0aW9ucy5jb2xvciAhPT0gdW5kZWZpbmVkID8gYXNBcnJheShvcHRpb25zLmNvbG9yKSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JY29uSW1hZ2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmljb25JbWFnZV8gPSBnZXRJY29uSW1hZ2UoaW1hZ2UsXG4gICAgLyoqIEB0eXBlIHtzdHJpbmd9ICovXG4gICAgc3JjLCBpbWdTaXplLCBfdGhpcy5jcm9zc09yaWdpbl8sIGltYWdlU3RhdGUsIF90aGlzLmNvbG9yXyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIF90aGlzLm9mZnNldF8gPSBvcHRpb25zLm9mZnNldCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vZmZzZXQgOiBbMCwgMF07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9JY29uT3JpZ2luLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5vZmZzZXRPcmlnaW5fID0gb3B0aW9ucy5vZmZzZXRPcmlnaW4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMub2Zmc2V0T3JpZ2luIDogSWNvbk9yaWdpbi5UT1BfTEVGVDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMub3JpZ2luXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgX3RoaXMuc2l6ZV8gPSBvcHRpb25zLnNpemUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc2l6ZSA6IG51bGw7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLiBUaGUgdW5kZXJseWluZyBJbWFnZS9IVE1MQ2FudmFzRWxlbWVudCBpcyBub3QgY2xvbmVkLlxuICAgKiBAcmV0dXJuIHtJY29ufSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5nZXRTY2FsZSgpO1xuICAgIHJldHVybiBuZXcgSWNvbih7XG4gICAgICBhbmNob3I6IHRoaXMuYW5jaG9yXy5zbGljZSgpLFxuICAgICAgYW5jaG9yT3JpZ2luOiB0aGlzLmFuY2hvck9yaWdpbl8sXG4gICAgICBhbmNob3JYVW5pdHM6IHRoaXMuYW5jaG9yWFVuaXRzXyxcbiAgICAgIGFuY2hvcllVbml0czogdGhpcy5hbmNob3JZVW5pdHNfLFxuICAgICAgY3Jvc3NPcmlnaW46IHRoaXMuY3Jvc3NPcmlnaW5fLFxuICAgICAgY29sb3I6IHRoaXMuY29sb3JfICYmIHRoaXMuY29sb3JfLnNsaWNlID8gdGhpcy5jb2xvcl8uc2xpY2UoKSA6IHRoaXMuY29sb3JfIHx8IHVuZGVmaW5lZCxcbiAgICAgIHNyYzogdGhpcy5nZXRTcmMoKSxcbiAgICAgIG9mZnNldDogdGhpcy5vZmZzZXRfLnNsaWNlKCksXG4gICAgICBvZmZzZXRPcmlnaW46IHRoaXMub2Zmc2V0T3JpZ2luXyxcbiAgICAgIHNpemU6IHRoaXMuc2l6ZV8gIT09IG51bGwgPyB0aGlzLnNpemVfLnNsaWNlKCkgOiB1bmRlZmluZWQsXG4gICAgICBvcGFjaXR5OiB0aGlzLmdldE9wYWNpdHkoKSxcbiAgICAgIHNjYWxlOiBBcnJheS5pc0FycmF5KHNjYWxlKSA/IHNjYWxlLnNsaWNlKCkgOiBzY2FsZSxcbiAgICAgIHJvdGF0aW9uOiB0aGlzLmdldFJvdGF0aW9uKCksXG4gICAgICByb3RhdGVXaXRoVmlldzogdGhpcy5nZXRSb3RhdGVXaXRoVmlldygpXG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFuY2hvciBwb2ludCBpbiBwaXhlbHMuIFRoZSBhbmNob3IgZGV0ZXJtaW5lcyB0aGUgY2VudGVyIHBvaW50IGZvciB0aGVcbiAgICogc3ltYm9saXplci5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gQW5jaG9yLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0QW5jaG9yID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLm5vcm1hbGl6ZWRBbmNob3JfKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVkQW5jaG9yXztcbiAgICB9XG5cbiAgICB2YXIgYW5jaG9yID0gdGhpcy5hbmNob3JfO1xuICAgIHZhciBzaXplID0gdGhpcy5nZXRTaXplKCk7XG5cbiAgICBpZiAodGhpcy5hbmNob3JYVW5pdHNfID09IEljb25BbmNob3JVbml0cy5GUkFDVElPTiB8fCB0aGlzLmFuY2hvcllVbml0c18gPT0gSWNvbkFuY2hvclVuaXRzLkZSQUNUSU9OKSB7XG4gICAgICBpZiAoIXNpemUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGFuY2hvciA9IHRoaXMuYW5jaG9yXy5zbGljZSgpO1xuXG4gICAgICBpZiAodGhpcy5hbmNob3JYVW5pdHNfID09IEljb25BbmNob3JVbml0cy5GUkFDVElPTikge1xuICAgICAgICBhbmNob3JbMF0gKj0gc2l6ZVswXTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYW5jaG9yWVVuaXRzXyA9PSBJY29uQW5jaG9yVW5pdHMuRlJBQ1RJT04pIHtcbiAgICAgICAgYW5jaG9yWzFdICo9IHNpemVbMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYW5jaG9yT3JpZ2luXyAhPSBJY29uT3JpZ2luLlRPUF9MRUZUKSB7XG4gICAgICBpZiAoIXNpemUpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChhbmNob3IgPT09IHRoaXMuYW5jaG9yXykge1xuICAgICAgICBhbmNob3IgPSB0aGlzLmFuY2hvcl8uc2xpY2UoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuYW5jaG9yT3JpZ2luXyA9PSBJY29uT3JpZ2luLlRPUF9SSUdIVCB8fCB0aGlzLmFuY2hvck9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fUklHSFQpIHtcbiAgICAgICAgYW5jaG9yWzBdID0gLWFuY2hvclswXSArIHNpemVbMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmFuY2hvck9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fTEVGVCB8fCB0aGlzLmFuY2hvck9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fUklHSFQpIHtcbiAgICAgICAgYW5jaG9yWzFdID0gLWFuY2hvclsxXSArIHNpemVbMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5ub3JtYWxpemVkQW5jaG9yXyA9IGFuY2hvcjtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVkQW5jaG9yXztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgYW5jaG9yIHBvaW50LiBUaGUgYW5jaG9yIGRldGVybWluZXMgdGhlIGNlbnRlciBwb2ludCBmb3IgdGhlXG4gICAqIHN5bWJvbGl6ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gYW5jaG9yIEFuY2hvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLnNldEFuY2hvciA9IGZ1bmN0aW9uIChhbmNob3IpIHtcbiAgICB0aGlzLmFuY2hvcl8gPSBhbmNob3I7XG4gICAgdGhpcy5ub3JtYWxpemVkQW5jaG9yXyA9IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGljb24gY29sb3IuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2NvbG9yLmpzXCIpLkNvbG9yfSBDb2xvci5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldENvbG9yID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbG9yXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgaW1hZ2UgaWNvbi5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEByZXR1cm4ge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9IEltYWdlIG9yIENhbnZhcyBlbGVtZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIHJldHVybiB0aGlzLmljb25JbWFnZV8uZ2V0SW1hZ2UocGl4ZWxSYXRpbyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgcGl4ZWwgcmF0aW9uIG9mIHRoZSBpbWFnZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldFBpeGVsUmF0aW8gPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIHJldHVybiB0aGlzLmljb25JbWFnZV8uZ2V0UGl4ZWxSYXRpbyhwaXhlbFJhdGlvKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gSW1hZ2Ugc2l6ZS5cbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRJbWFnZVNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWNvbkltYWdlXy5nZXRTaXplKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFNpemUgb2YgdGhlIGhpdC1kZXRlY3Rpb24gaW1hZ2UuXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0SGl0RGV0ZWN0aW9uSW1hZ2VTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldEltYWdlU2l6ZSgpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vSW1hZ2VTdGF0ZS5qc1wiKS5kZWZhdWx0fSBJbWFnZSBzdGF0ZS5cbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRJbWFnZVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmljb25JbWFnZV8uZ2V0SW1hZ2VTdGF0ZSgpO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7SFRNTEltYWdlRWxlbWVudHxIVE1MQ2FudmFzRWxlbWVudH0gSW1hZ2UgZWxlbWVudC5cbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRIaXREZXRlY3Rpb25JbWFnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pY29uSW1hZ2VfLmdldEhpdERldGVjdGlvbkltYWdlKCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG9yaWdpbiBvZiB0aGUgc3ltYm9saXplci5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3JpZ2luLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUuZ2V0T3JpZ2luID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLm9yaWdpbl8pIHtcbiAgICAgIHJldHVybiB0aGlzLm9yaWdpbl87XG4gICAgfVxuXG4gICAgdmFyIG9mZnNldCA9IHRoaXMub2Zmc2V0XztcbiAgICB2YXIgZGlzcGxhY2VtZW50ID0gdGhpcy5nZXREaXNwbGFjZW1lbnQoKTtcblxuICAgIGlmICh0aGlzLm9mZnNldE9yaWdpbl8gIT0gSWNvbk9yaWdpbi5UT1BfTEVGVCkge1xuICAgICAgdmFyIHNpemUgPSB0aGlzLmdldFNpemUoKTtcbiAgICAgIHZhciBpY29uSW1hZ2VTaXplID0gdGhpcy5pY29uSW1hZ2VfLmdldFNpemUoKTtcblxuICAgICAgaWYgKCFzaXplIHx8ICFpY29uSW1hZ2VTaXplKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICBvZmZzZXQgPSBvZmZzZXQuc2xpY2UoKTtcblxuICAgICAgaWYgKHRoaXMub2Zmc2V0T3JpZ2luXyA9PSBJY29uT3JpZ2luLlRPUF9SSUdIVCB8fCB0aGlzLm9mZnNldE9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fUklHSFQpIHtcbiAgICAgICAgb2Zmc2V0WzBdID0gaWNvbkltYWdlU2l6ZVswXSAtIHNpemVbMF0gLSBvZmZzZXRbMF07XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLm9mZnNldE9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fTEVGVCB8fCB0aGlzLm9mZnNldE9yaWdpbl8gPT0gSWNvbk9yaWdpbi5CT1RUT01fUklHSFQpIHtcbiAgICAgICAgb2Zmc2V0WzFdID0gaWNvbkltYWdlU2l6ZVsxXSAtIHNpemVbMV0gLSBvZmZzZXRbMV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgb2Zmc2V0WzBdICs9IGRpc3BsYWNlbWVudFswXTtcbiAgICBvZmZzZXRbMV0gKz0gZGlzcGxhY2VtZW50WzFdO1xuICAgIHRoaXMub3JpZ2luXyA9IG9mZnNldDtcbiAgICByZXR1cm4gdGhpcy5vcmlnaW5fO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBVUkwuXG4gICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IEltYWdlIHNyYy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmdldFNyYyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pY29uSW1hZ2VfLmdldFNyYygpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzaXplIG9mIHRoZSBpY29uIChpbiBwaXhlbHMpLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IEltYWdlIHNpemUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAhdGhpcy5zaXplXyA/IHRoaXMuaWNvbkltYWdlXy5nZXRTaXplKCkgOiB0aGlzLnNpemVfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9ldmVudHMvRXZlbnQuanNcIikuZGVmYXVsdCk6IHZvaWR9IGxpc3RlbmVyIExpc3RlbmVyIGZ1bmN0aW9uLlxuICAgKi9cblxuXG4gIEljb24ucHJvdG90eXBlLmxpc3RlbkltYWdlQ2hhbmdlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XG4gICAgdGhpcy5pY29uSW1hZ2VfLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgbGlzdGVuZXIpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqIFdoZW4gcmVuZGVyaW5nIGEgZmVhdHVyZSB3aXRoIGFuIGljb24gc3R5bGUsIHRoZSB2ZWN0b3IgcmVuZGVyZXIgd2lsbFxuICAgKiBhdXRvbWF0aWNhbGx5IGNhbGwgdGhpcyBtZXRob2QuIEhvd2V2ZXIsIHlvdSBtaWdodCB3YW50IHRvIGNhbGwgdGhpc1xuICAgKiBtZXRob2QgeW91cnNlbGYgZm9yIHByZWxvYWRpbmcgb3Igb3RoZXIgcHVycG9zZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBJY29uLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuaWNvbkltYWdlXy5sb2FkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0KTogdm9pZH0gbGlzdGVuZXIgTGlzdGVuZXIgZnVuY3Rpb24uXG4gICAqL1xuXG5cbiAgSWNvbi5wcm90b3R5cGUudW5saXN0ZW5JbWFnZUNoYW5nZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgIHRoaXMuaWNvbkltYWdlXy5yZW1vdmVFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIGxpc3RlbmVyKTtcbiAgfTtcblxuICByZXR1cm4gSWNvbjtcbn0oSW1hZ2VTdHlsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IEljb247IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9jYW52YXMvaGl0ZGV0ZWN0XG4gKi9cbmltcG9ydCBDYW52YXNJbW1lZGlhdGVSZW5kZXJlciBmcm9tICcuL0ltbWVkaWF0ZS5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4uLy4uL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBJY29uQW5jaG9yVW5pdHMgZnJvbSAnLi4vLi4vc3R5bGUvSWNvbkFuY2hvclVuaXRzLmpzJztcbmltcG9ydCB7IEljb24gfSBmcm9tICcuLi8uLi9zdHlsZS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVDYW52YXNDb250ZXh0MkQgfSBmcm9tICcuLi8uLi9kb20uanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0cyB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBudW1iZXJTYWZlQ29tcGFyZUZ1bmN0aW9uIH0gZnJvbSAnLi4vLi4vYXJyYXkuanMnO1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBDYW52YXMgc2l6ZSBpbiBjc3MgcGl4ZWxzLlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi8uLi90cmFuc2Zvcm0uanNcIikuVHJhbnNmb3JtPn0gdHJhbnNmb3JtcyBUcmFuc2Zvcm1zXG4gKiBmb3IgcmVuZGVyaW5nIGZlYXR1cmVzIHRvIGFsbCB3b3JsZHMgb2YgdGhlIHZpZXdwb3J0LCBmcm9tIGNvb3JkaW5hdGVzIHRvIGNzc1xuICogcGl4ZWxzLlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gZmVhdHVyZXNcbiAqIEZlYXR1cmVzIHRvIGNvbnNpZGVyIGZvciBoaXQgZGV0ZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUZ1bmN0aW9ufHVuZGVmaW5lZH0gc3R5bGVGdW5jdGlvblxuICogTGF5ZXIgc3R5bGUgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICogQHJldHVybiB7SW1hZ2VEYXRhfSBIaXQgZGV0ZWN0aW9uIGltYWdlIGRhdGEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YShzaXplLCB0cmFuc2Zvcm1zLCBmZWF0dXJlcywgc3R5bGVGdW5jdGlvbiwgZXh0ZW50LCByZXNvbHV0aW9uLCByb3RhdGlvbikge1xuICB2YXIgd2lkdGggPSBzaXplWzBdIC8gMjtcbiAgdmFyIGhlaWdodCA9IHNpemVbMV0gLyAyO1xuICB2YXIgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCh3aWR0aCwgaGVpZ2h0KTtcbiAgY29udGV4dC5pbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgdmFyIGNhbnZhcyA9IGNvbnRleHQuY2FudmFzO1xuICB2YXIgcmVuZGVyZXIgPSBuZXcgQ2FudmFzSW1tZWRpYXRlUmVuZGVyZXIoY29udGV4dCwgMC41LCBleHRlbnQsIG51bGwsIHJvdGF0aW9uKTtcbiAgdmFyIGZlYXR1cmVDb3VudCA9IGZlYXR1cmVzLmxlbmd0aDsgLy8gU3RyZXRjaCBoaXQgZGV0ZWN0aW9uIGluZGV4IHRvIHVzZSB0aGUgd2hvbGUgYXZhaWxhYmxlIGNvbG9yIHJhbmdlXG5cbiAgdmFyIGluZGV4RmFjdG9yID0gTWF0aC5mbG9vcigoMjU2ICogMjU2ICogMjU2IC0gMSkgLyBmZWF0dXJlQ291bnQpO1xuICB2YXIgZmVhdHVyZXNCeVpJbmRleCA9IHt9O1xuXG4gIGZvciAodmFyIGkgPSAxOyBpIDw9IGZlYXR1cmVDb3VudDsgKytpKSB7XG4gICAgdmFyIGZlYXR1cmUgPSBmZWF0dXJlc1tpIC0gMV07XG4gICAgdmFyIGZlYXR1cmVTdHlsZUZ1bmN0aW9uID0gZmVhdHVyZS5nZXRTdHlsZUZ1bmN0aW9uKCkgfHwgc3R5bGVGdW5jdGlvbjtcblxuICAgIGlmICghc3R5bGVGdW5jdGlvbikge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdmFyIHN0eWxlcyA9IGZlYXR1cmVTdHlsZUZ1bmN0aW9uKGZlYXR1cmUsIHJlc29sdXRpb24pO1xuXG4gICAgaWYgKCFzdHlsZXMpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShzdHlsZXMpKSB7XG4gICAgICBzdHlsZXMgPSBbc3R5bGVzXTtcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBpICogaW5kZXhGYWN0b3I7XG4gICAgdmFyIGNvbG9yID0gJyMnICsgKCcwMDAwMDAnICsgaW5kZXgudG9TdHJpbmcoMTYpKS5zbGljZSgtNik7XG5cbiAgICBmb3IgKHZhciBqID0gMCwgamogPSBzdHlsZXMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgdmFyIG9yaWdpbmFsU3R5bGUgPSBzdHlsZXNbal07XG4gICAgICB2YXIgc3R5bGUgPSBvcmlnaW5hbFN0eWxlLmNsb25lKCk7XG4gICAgICB2YXIgZmlsbCA9IHN0eWxlLmdldEZpbGwoKTtcblxuICAgICAgaWYgKGZpbGwpIHtcbiAgICAgICAgZmlsbC5zZXRDb2xvcihjb2xvcik7XG4gICAgICB9XG5cbiAgICAgIHZhciBzdHJva2UgPSBzdHlsZS5nZXRTdHJva2UoKTtcblxuICAgICAgaWYgKHN0cm9rZSkge1xuICAgICAgICBzdHJva2Uuc2V0Q29sb3IoY29sb3IpO1xuICAgICAgfVxuXG4gICAgICBzdHlsZS5zZXRUZXh0KHVuZGVmaW5lZCk7XG4gICAgICB2YXIgaW1hZ2UgPSBvcmlnaW5hbFN0eWxlLmdldEltYWdlKCk7XG5cbiAgICAgIGlmIChpbWFnZSkge1xuICAgICAgICB2YXIgaW1nU2l6ZSA9IGltYWdlLmdldEltYWdlU2l6ZSgpO1xuXG4gICAgICAgIGlmICghaW1nU2l6ZSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNhbnZhc18xID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgICAgIGNhbnZhc18xLndpZHRoID0gaW1nU2l6ZVswXTtcbiAgICAgICAgY2FudmFzXzEuaGVpZ2h0ID0gaW1nU2l6ZVsxXTtcbiAgICAgICAgdmFyIGltZ0NvbnRleHQgPSBjYW52YXNfMS5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgICAgICBhbHBoYTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGltZ0NvbnRleHQuZmlsbFN0eWxlID0gY29sb3I7XG4gICAgICAgIHZhciBpbWcgPSBpbWdDb250ZXh0LmNhbnZhcztcbiAgICAgICAgaW1nQ29udGV4dC5maWxsUmVjdCgwLCAwLCBpbWcud2lkdGgsIGltZy5oZWlnaHQpO1xuICAgICAgICB2YXIgd2lkdGhfMSA9IGltZ1NpemUgPyBpbWdTaXplWzBdIDogaW1nLndpZHRoO1xuICAgICAgICB2YXIgaGVpZ2h0XzEgPSBpbWdTaXplID8gaW1nU2l6ZVsxXSA6IGltZy5oZWlnaHQ7XG4gICAgICAgIHZhciBpY29uQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRCh3aWR0aF8xLCBoZWlnaHRfMSk7XG4gICAgICAgIGljb25Db250ZXh0LmRyYXdJbWFnZShpbWcsIDAsIDApO1xuICAgICAgICBzdHlsZS5zZXRJbWFnZShuZXcgSWNvbih7XG4gICAgICAgICAgaW1nOiBpbWcsXG4gICAgICAgICAgaW1nU2l6ZTogaW1nU2l6ZSxcbiAgICAgICAgICBhbmNob3I6IGltYWdlLmdldEFuY2hvcigpLFxuICAgICAgICAgIGFuY2hvclhVbml0czogSWNvbkFuY2hvclVuaXRzLlBJWEVMUyxcbiAgICAgICAgICBhbmNob3JZVW5pdHM6IEljb25BbmNob3JVbml0cy5QSVhFTFMsXG4gICAgICAgICAgb2Zmc2V0OiBpbWFnZS5nZXRPcmlnaW4oKSxcbiAgICAgICAgICBzaXplOiBpbWFnZS5nZXRTaXplKCksXG4gICAgICAgICAgb3BhY2l0eTogaW1hZ2UuZ2V0T3BhY2l0eSgpLFxuICAgICAgICAgIHNjYWxlOiBpbWFnZS5nZXRTY2FsZSgpLFxuICAgICAgICAgIHJvdGF0aW9uOiBpbWFnZS5nZXRSb3RhdGlvbigpLFxuICAgICAgICAgIHJvdGF0ZVdpdGhWaWV3OiBpbWFnZS5nZXRSb3RhdGVXaXRoVmlldygpXG4gICAgICAgIH0pKTtcbiAgICAgIH1cblxuICAgICAgdmFyIHpJbmRleCA9IE51bWJlcihzdHlsZS5nZXRaSW5kZXgoKSk7XG4gICAgICB2YXIgYnlHZW9tZXRyeVR5cGUgPSBmZWF0dXJlc0J5WkluZGV4W3pJbmRleF07XG5cbiAgICAgIGlmICghYnlHZW9tZXRyeVR5cGUpIHtcbiAgICAgICAgYnlHZW9tZXRyeVR5cGUgPSB7fTtcbiAgICAgICAgZmVhdHVyZXNCeVpJbmRleFt6SW5kZXhdID0gYnlHZW9tZXRyeVR5cGU7XG4gICAgICAgIGJ5R2VvbWV0cnlUeXBlW0dlb21ldHJ5VHlwZS5QT0xZR09OXSA9IFtdO1xuICAgICAgICBieUdlb21ldHJ5VHlwZVtHZW9tZXRyeVR5cGUuQ0lSQ0xFXSA9IFtdO1xuICAgICAgICBieUdlb21ldHJ5VHlwZVtHZW9tZXRyeVR5cGUuTElORV9TVFJJTkddID0gW107XG4gICAgICAgIGJ5R2VvbWV0cnlUeXBlW0dlb21ldHJ5VHlwZS5QT0lOVF0gPSBbXTtcbiAgICAgIH1cblxuICAgICAgdmFyIGdlb21ldHJ5ID0gc3R5bGUuZ2V0R2VvbWV0cnlGdW5jdGlvbigpKGZlYXR1cmUpO1xuXG4gICAgICBpZiAoZ2VvbWV0cnkgJiYgaW50ZXJzZWN0cyhleHRlbnQsIGdlb21ldHJ5LmdldEV4dGVudCgpKSkge1xuICAgICAgICBieUdlb21ldHJ5VHlwZVtnZW9tZXRyeS5nZXRUeXBlKCkucmVwbGFjZSgnTXVsdGknLCAnJyldLnB1c2goZ2VvbWV0cnksIHN0eWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2YXIgekluZGV4S2V5cyA9IE9iamVjdC5rZXlzKGZlYXR1cmVzQnlaSW5kZXgpLm1hcChOdW1iZXIpLnNvcnQobnVtYmVyU2FmZUNvbXBhcmVGdW5jdGlvbik7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gekluZGV4S2V5cy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGJ5R2VvbWV0cnlUeXBlID0gZmVhdHVyZXNCeVpJbmRleFt6SW5kZXhLZXlzW2ldXTtcblxuICAgIGZvciAodmFyIHR5cGUgaW4gYnlHZW9tZXRyeVR5cGUpIHtcbiAgICAgIHZhciBnZW9tQW5kU3R5bGUgPSBieUdlb21ldHJ5VHlwZVt0eXBlXTtcblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gZ2VvbUFuZFN0eWxlLmxlbmd0aDsgaiA8IGpqOyBqICs9IDIpIHtcbiAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUoZ2VvbUFuZFN0eWxlW2ogKyAxXSk7XG5cbiAgICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gdHJhbnNmb3Jtcy5sZW5ndGg7IGsgPCBrazsgKytrKSB7XG4gICAgICAgICAgcmVuZGVyZXIuc2V0VHJhbnNmb3JtKHRyYW5zZm9ybXNba10pO1xuICAgICAgICAgIHJlbmRlcmVyLmRyYXdHZW9tZXRyeShnZW9tQW5kU3R5bGVbal0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbnRleHQuZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcGl4ZWxcIikuUGl4ZWx9IHBpeGVsIFBpeGVsIGNvb3JkaW5hdGUgb24gdGhlIGhpdFxuICogZGV0ZWN0aW9uIGNhbnZhcyBpbiBjc3MgcGl4ZWxzLlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlXCIpLkZlYXR1cmVMaWtlPn0gZmVhdHVyZXMgRmVhdHVyZXMuIEhhcyB0b1xuICogbWF0Y2ggdGhlIGBmZWF0dXJlc2AgYXJyYXkgdGhhdCB3YXMgcGFzc2VkIHRvIGBjcmVhdGVIaXREZXRlY3Rpb25JbWFnZURhdGEoKWAuXG4gKiBAcGFyYW0ge0ltYWdlRGF0YX0gaW1hZ2VEYXRhIEhpdCBkZXRlY3Rpb24gaW1hZ2UgZGF0YSBnZW5lcmF0ZWQgYnlcbiAqIGBjcmVhdGVIaXREZXRlY3Rpb25JbWFnZURhdGEoKWAuXG4gKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlXCIpLkZlYXR1cmVMaWtlPn0gZmVhdHVyZXMgRmVhdHVyZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGhpdERldGVjdChwaXhlbCwgZmVhdHVyZXMsIGltYWdlRGF0YSkge1xuICB2YXIgcmVzdWx0RmVhdHVyZXMgPSBbXTtcblxuICBpZiAoaW1hZ2VEYXRhKSB7XG4gICAgdmFyIGluZGV4ID0gKE1hdGgucm91bmQocGl4ZWxbMF0gLyAyKSArIE1hdGgucm91bmQocGl4ZWxbMV0gLyAyKSAqIGltYWdlRGF0YS53aWR0aCkgKiA0O1xuICAgIHZhciByID0gaW1hZ2VEYXRhLmRhdGFbaW5kZXhdO1xuICAgIHZhciBnID0gaW1hZ2VEYXRhLmRhdGFbaW5kZXggKyAxXTtcbiAgICB2YXIgYiA9IGltYWdlRGF0YS5kYXRhW2luZGV4ICsgMl07XG4gICAgdmFyIGkgPSBiICsgMjU2ICogKGcgKyAyNTYgKiByKTtcbiAgICB2YXIgaW5kZXhGYWN0b3IgPSBNYXRoLmZsb29yKCgyNTYgKiAyNTYgKiAyNTYgLSAxKSAvIGZlYXR1cmVzLmxlbmd0aCk7XG5cbiAgICBpZiAoaSAmJiBpICUgaW5kZXhGYWN0b3IgPT09IDApIHtcbiAgICAgIHJlc3VsdEZlYXR1cmVzLnB1c2goZmVhdHVyZXNbaSAvIGluZGV4RmFjdG9yIC0gMV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRGZWF0dXJlcztcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvdmVjdG9yXG4gKi9cbmltcG9ydCBCdWlsZGVyVHlwZSBmcm9tICcuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJUeXBlLmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IEltYWdlU3RhdGUgZnJvbSAnLi4vSW1hZ2VTdGF0ZS5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi91dGlsLmpzJztcbi8qKlxuICogRmVhdHVyZSBjYWxsYmFjay4gVGhlIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdpdGggdGhyZWUgYXJndW1lbnRzLiBUaGUgZmlyc3RcbiAqIGFyZ3VtZW50IGlzIG9uZSB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmUgZmVhdHVyZX0gb3Ige0BsaW5rIG1vZHVsZTpvbC9yZW5kZXIvRmVhdHVyZSByZW5kZXIgZmVhdHVyZX1cbiAqIGF0IHRoZSBwaXhlbCwgdGhlIHNlY29uZCBpcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9sYXllci9MYXllciBsYXllcn0gb2YgdGhlIGZlYXR1cmUgYW5kIHdpbGwgYmUgbnVsbCBmb3JcbiAqIHVubWFuYWdlZCBsYXllcnMuIFRoZSB0aGlyZCBpcyB0aGUge0BsaW5rIG1vZHVsZTpvbC9nZW9tL1NpbXBsZUdlb21ldHJ5fSBvZiB0aGUgZmVhdHVyZS4gRm9yIGZlYXR1cmVzXG4gKiB3aXRoIGEgR2VvbWV0cnlDb2xsZWN0aW9uIGdlb21ldHJ5LCBpdCB3aWxsIGJlIHRoZSBmaXJzdCBkZXRlY3RlZCBnZW9tZXRyeSBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlLCBpbXBvcnQoXCIuLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHQpOiBUfSBGZWF0dXJlQ2FsbGJhY2tcbiAqL1xuXG4vKipcbiAqIFRvbGVyYW5jZSBmb3IgZ2VvbWV0cnkgc2ltcGxpZmljYXRpb24gaW4gZGV2aWNlIHBpeGVscy5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cblxudmFyIFNJTVBMSUZZX1RPTEVSQU5DRSA9IDAuNTtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7T2JqZWN0PGltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlUeXBlLmpzXCIpLmRlZmF1bHQsXG4gKiAgICAgICAgICAgICAgICBmdW5jdGlvbihpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0LCBpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHQsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICBpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0LCBPYmplY3QpOiB2b2lkPn1cbiAqL1xuXG52YXIgR0VPTUVUUllfUkVOREVSRVJTID0ge1xuICAnUG9pbnQnOiByZW5kZXJQb2ludEdlb21ldHJ5LFxuICAnTGluZVN0cmluZyc6IHJlbmRlckxpbmVTdHJpbmdHZW9tZXRyeSxcbiAgJ1BvbHlnb24nOiByZW5kZXJQb2x5Z29uR2VvbWV0cnksXG4gICdNdWx0aVBvaW50JzogcmVuZGVyTXVsdGlQb2ludEdlb21ldHJ5LFxuICAnTXVsdGlMaW5lU3RyaW5nJzogcmVuZGVyTXVsdGlMaW5lU3RyaW5nR2VvbWV0cnksXG4gICdNdWx0aVBvbHlnb24nOiByZW5kZXJNdWx0aVBvbHlnb25HZW9tZXRyeSxcbiAgJ0dlb21ldHJ5Q29sbGVjdGlvbic6IHJlbmRlckdlb21ldHJ5Q29sbGVjdGlvbkdlb21ldHJ5LFxuICAnQ2lyY2xlJzogcmVuZGVyQ2lyY2xlR2VvbWV0cnlcbn07XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZTEgRmVhdHVyZSAxLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlMiBGZWF0dXJlIDIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE9yZGVyLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0T3JkZXIoZmVhdHVyZTEsIGZlYXR1cmUyKSB7XG4gIHJldHVybiBwYXJzZUludChnZXRVaWQoZmVhdHVyZTEpLCAxMCkgLSBwYXJzZUludChnZXRVaWQoZmVhdHVyZTIpLCAxMCk7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAqIEByZXR1cm4ge251bWJlcn0gU3F1YXJlZCBwaXhlbCB0b2xlcmFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNxdWFyZWRUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykge1xuICB2YXIgdG9sZXJhbmNlID0gZ2V0VG9sZXJhbmNlKHJlc29sdXRpb24sIHBpeGVsUmF0aW8pO1xuICByZXR1cm4gdG9sZXJhbmNlICogdG9sZXJhbmNlO1xufVxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFBpeGVsIHRvbGVyYW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9sZXJhbmNlKHJlc29sdXRpb24sIHBpeGVsUmF0aW8pIHtcbiAgcmV0dXJuIFNJTVBMSUZZX1RPTEVSQU5DRSAqIHJlc29sdXRpb24gLyBwaXhlbFJhdGlvO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBCdWlsZGVyIGdyb3VwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0NpcmNsZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuZnVuY3Rpb24gcmVuZGVyQ2lyY2xlR2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGZpbGxTdHlsZSA9IHN0eWxlLmdldEZpbGwoKTtcbiAgdmFyIHN0cm9rZVN0eWxlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgaWYgKGZpbGxTdHlsZSB8fCBzdHJva2VTdHlsZSkge1xuICAgIHZhciBjaXJjbGVSZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuQ0lSQ0xFKTtcbiAgICBjaXJjbGVSZXBsYXkuc2V0RmlsbFN0cm9rZVN0eWxlKGZpbGxTdHlsZSwgc3Ryb2tlU3R5bGUpO1xuICAgIGNpcmNsZVJlcGxheS5kcmF3Q2lyY2xlKGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxuXG4gIHZhciB0ZXh0U3R5bGUgPSBzdHlsZS5nZXRUZXh0KCk7XG5cbiAgaWYgKHRleHRTdHlsZSAmJiB0ZXh0U3R5bGUuZ2V0VGV4dCgpKSB7XG4gICAgdmFyIHRleHRSZXBsYXkgPSAob3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCB8fCBidWlsZGVyR3JvdXApLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLlRFWFQpO1xuICAgIHRleHRSZXBsYXkuc2V0VGV4dFN0eWxlKHRleHRTdHlsZSk7XG4gICAgdGV4dFJlcGxheS5kcmF3VGV4dChnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSByZXBsYXlHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHQpOiB2b2lkfSBsaXN0ZW5lciBMaXN0ZW5lciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gW29wdF90cmFuc2Zvcm1dIFRyYW5zZm9ybSBmcm9tIHVzZXIgdG8gdmlldyBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgc3R5bGUgaXMgbG9hZGluZy5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJGZWF0dXJlKHJlcGxheUdyb3VwLCBmZWF0dXJlLCBzdHlsZSwgc3F1YXJlZFRvbGVyYW5jZSwgbGlzdGVuZXIsIG9wdF90cmFuc2Zvcm0sIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGxvYWRpbmcgPSBmYWxzZTtcbiAgdmFyIGltYWdlU3R5bGUgPSBzdHlsZS5nZXRJbWFnZSgpO1xuXG4gIGlmIChpbWFnZVN0eWxlKSB7XG4gICAgdmFyIGltYWdlU3RhdGUgPSBpbWFnZVN0eWxlLmdldEltYWdlU3RhdGUoKTtcblxuICAgIGlmIChpbWFnZVN0YXRlID09IEltYWdlU3RhdGUuTE9BREVEIHx8IGltYWdlU3RhdGUgPT0gSW1hZ2VTdGF0ZS5FUlJPUikge1xuICAgICAgaW1hZ2VTdHlsZS51bmxpc3RlbkltYWdlQ2hhbmdlKGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGltYWdlU3RhdGUgPT0gSW1hZ2VTdGF0ZS5JRExFKSB7XG4gICAgICAgIGltYWdlU3R5bGUubG9hZCgpO1xuICAgICAgfVxuXG4gICAgICBpbWFnZVN0YXRlID0gaW1hZ2VTdHlsZS5nZXRJbWFnZVN0YXRlKCk7XG4gICAgICBpbWFnZVN0eWxlLmxpc3RlbkltYWdlQ2hhbmdlKGxpc3RlbmVyKTtcbiAgICAgIGxvYWRpbmcgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJlbmRlckZlYXR1cmVJbnRlcm5hbChyZXBsYXlHcm91cCwgZmVhdHVyZSwgc3R5bGUsIHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0sIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApO1xuICByZXR1cm4gbG9hZGluZztcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSByZXBsYXlHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gW29wdF90cmFuc2Zvcm1dIE9wdGlvbmFsIHRyYW5zZm9ybSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cbmZ1bmN0aW9uIHJlbmRlckZlYXR1cmVJbnRlcm5hbChyZXBsYXlHcm91cCwgZmVhdHVyZSwgc3R5bGUsIHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0sIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGdlb21ldHJ5ID0gc3R5bGUuZ2V0R2VvbWV0cnlGdW5jdGlvbigpKGZlYXR1cmUpO1xuXG4gIGlmICghZ2VvbWV0cnkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2ltcGxpZmllZEdlb21ldHJ5ID0gZ2VvbWV0cnkuc2ltcGxpZnlUcmFuc2Zvcm1lZChzcXVhcmVkVG9sZXJhbmNlLCBvcHRfdHJhbnNmb3JtKTtcbiAgdmFyIHJlbmRlcmVyID0gc3R5bGUuZ2V0UmVuZGVyZXIoKTtcblxuICBpZiAocmVuZGVyZXIpIHtcbiAgICByZW5kZXJHZW9tZXRyeShyZXBsYXlHcm91cCwgc2ltcGxpZmllZEdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGdlb21ldHJ5UmVuZGVyZXIgPSBHRU9NRVRSWV9SRU5ERVJFUlNbc2ltcGxpZmllZEdlb21ldHJ5LmdldFR5cGUoKV07XG4gICAgZ2VvbWV0cnlSZW5kZXJlcihyZXBsYXlHcm91cCwgc2ltcGxpZmllZEdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSByZXBsYXlHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlbmRlckdlb21ldHJ5KHJlcGxheUdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUpIHtcbiAgaWYgKGdlb21ldHJ5LmdldFR5cGUoKSA9PSBHZW9tZXRyeVR5cGUuR0VPTUVUUllfQ09MTEVDVElPTikge1xuICAgIHZhciBnZW9tZXRyaWVzID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgZ2VvbWV0cnkuZ2V0R2VvbWV0cmllcygpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICByZW5kZXJHZW9tZXRyeShyZXBsYXlHcm91cCwgZ2VvbWV0cmllc1tpXSwgc3R5bGUsIGZlYXR1cmUpO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciByZXBsYXkgPSByZXBsYXlHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5ERUZBVUxUKTtcbiAgcmVwbGF5LmRyYXdDdXN0b20oXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSAqL1xuICBnZW9tZXRyeSwgZmVhdHVyZSwgc3R5bGUuZ2V0UmVuZGVyZXIoKSk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gcmVwbGF5R3JvdXAgUmVwbGF5IGdyb3VwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5Q29sbGVjdGlvbi5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJHZW9tZXRyeUNvbGxlY3Rpb25HZW9tZXRyeShyZXBsYXlHcm91cCwgZ2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gIHZhciBnZW9tZXRyaWVzID0gZ2VvbWV0cnkuZ2V0R2VvbWV0cmllc0FycmF5KCk7XG4gIHZhciBpLCBpaTtcblxuICBmb3IgKGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBnZW9tZXRyeVJlbmRlcmVyID0gR0VPTUVUUllfUkVOREVSRVJTW2dlb21ldHJpZXNbaV0uZ2V0VHlwZSgpXTtcbiAgICBnZW9tZXRyeVJlbmRlcmVyKHJlcGxheUdyb3VwLCBnZW9tZXRyaWVzW2ldLCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSBidWlsZGVyR3JvdXAgUmVwbGF5IGdyb3VwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0xpbmVTdHJpbmcuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyTGluZVN0cmluZ0dlb21ldHJ5KGJ1aWxkZXJHcm91cCwgZ2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gIHZhciBzdHJva2VTdHlsZSA9IHN0eWxlLmdldFN0cm9rZSgpO1xuXG4gIGlmIChzdHJva2VTdHlsZSkge1xuICAgIHZhciBsaW5lU3RyaW5nUmVwbGF5ID0gYnVpbGRlckdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLkxJTkVfU1RSSU5HKTtcbiAgICBsaW5lU3RyaW5nUmVwbGF5LnNldEZpbGxTdHJva2VTdHlsZShudWxsLCBzdHJva2VTdHlsZSk7XG4gICAgbGluZVN0cmluZ1JlcGxheS5kcmF3TGluZVN0cmluZyhnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cblxuICB2YXIgdGV4dFN0eWxlID0gc3R5bGUuZ2V0VGV4dCgpO1xuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgfHwgYnVpbGRlckdyb3VwKS5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5URVhUKTtcbiAgICB0ZXh0UmVwbGF5LnNldFRleHRTdHlsZSh0ZXh0U3R5bGUpO1xuICAgIHRleHRSZXBsYXkuZHJhd1RleHQoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdH0gYnVpbGRlckdyb3VwIFJlcGxheSBncm91cC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9NdWx0aUxpbmVTdHJpbmcuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyTXVsdGlMaW5lU3RyaW5nR2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIHN0cm9rZVN0eWxlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgaWYgKHN0cm9rZVN0eWxlKSB7XG4gICAgdmFyIGxpbmVTdHJpbmdSZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuTElORV9TVFJJTkcpO1xuICAgIGxpbmVTdHJpbmdSZXBsYXkuc2V0RmlsbFN0cm9rZVN0eWxlKG51bGwsIHN0cm9rZVN0eWxlKTtcbiAgICBsaW5lU3RyaW5nUmVwbGF5LmRyYXdNdWx0aUxpbmVTdHJpbmcoZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG5cbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcblxuICBpZiAodGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkpIHtcbiAgICB2YXIgdGV4dFJlcGxheSA9IChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIHx8IGJ1aWxkZXJHcm91cCkuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlKTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vTXVsdGlQb2x5Z29uLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlbmRlck11bHRpUG9seWdvbkdlb21ldHJ5KGJ1aWxkZXJHcm91cCwgZ2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gIHZhciBmaWxsU3R5bGUgPSBzdHlsZS5nZXRGaWxsKCk7XG4gIHZhciBzdHJva2VTdHlsZSA9IHN0eWxlLmdldFN0cm9rZSgpO1xuXG4gIGlmIChzdHJva2VTdHlsZSB8fCBmaWxsU3R5bGUpIHtcbiAgICB2YXIgcG9seWdvblJlcGxheSA9IGJ1aWxkZXJHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5QT0xZR09OKTtcbiAgICBwb2x5Z29uUmVwbGF5LnNldEZpbGxTdHJva2VTdHlsZShmaWxsU3R5bGUsIHN0cm9rZVN0eWxlKTtcbiAgICBwb2x5Z29uUmVwbGF5LmRyYXdNdWx0aVBvbHlnb24oZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG5cbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcblxuICBpZiAodGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkpIHtcbiAgICB2YXIgdGV4dFJlcGxheSA9IChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIHx8IGJ1aWxkZXJHcm91cCkuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlKTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vUG9pbnQuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyUG9pbnRHZW9tZXRyeShidWlsZGVyR3JvdXAsIGdlb21ldHJ5LCBzdHlsZSwgZmVhdHVyZSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICB2YXIgaW1hZ2VTdHlsZSA9IHN0eWxlLmdldEltYWdlKCk7XG4gIHZhciB0ZXh0U3R5bGUgPSBzdHlsZS5nZXRUZXh0KCk7XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy5qc1wiKS5EZWNsdXR0ZXJJbWFnZVdpdGhUZXh0fSAqL1xuXG4gIHZhciBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0O1xuXG4gIGlmIChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gICAgYnVpbGRlckdyb3VwID0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cDtcbiAgICBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0ID0gaW1hZ2VTdHlsZSAmJiB0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSA/IHt9IDogdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKGltYWdlU3R5bGUpIHtcbiAgICBpZiAoaW1hZ2VTdHlsZS5nZXRJbWFnZVN0YXRlKCkgIT0gSW1hZ2VTdGF0ZS5MT0FERUQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW1hZ2VSZXBsYXkgPSBidWlsZGVyR3JvdXAuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuSU1BR0UpO1xuICAgIGltYWdlUmVwbGF5LnNldEltYWdlU3R5bGUoaW1hZ2VTdHlsZSwgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCk7XG4gICAgaW1hZ2VSZXBsYXkuZHJhd1BvaW50KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxuXG4gIGlmICh0ZXh0U3R5bGUgJiYgdGV4dFN0eWxlLmdldFRleHQoKSkge1xuICAgIHZhciB0ZXh0UmVwbGF5ID0gYnVpbGRlckdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLlRFWFQpO1xuICAgIHRleHRSZXBsYXkuc2V0VGV4dFN0eWxlKHRleHRTdHlsZSwgZGVjbHV0dGVySW1hZ2VXaXRoVGV4dCk7XG4gICAgdGV4dFJlcGxheS5kcmF3VGV4dChnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSBidWlsZGVyR3JvdXAgUmVwbGF5IGdyb3VwLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL011bHRpUG9pbnQuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdH0gc3R5bGUgU3R5bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IGZlYXR1cmUgRmVhdHVyZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcmVuZGVyL2NhbnZhcy9CdWlsZGVyR3JvdXAuanNcIikuZGVmYXVsdD19IG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXAgQnVpbGRlciBmb3IgZGVjbHV0dGVyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVuZGVyTXVsdGlQb2ludEdlb21ldHJ5KGJ1aWxkZXJHcm91cCwgZ2VvbWV0cnksIHN0eWxlLCBmZWF0dXJlLCBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gIHZhciBpbWFnZVN0eWxlID0gc3R5bGUuZ2V0SW1hZ2UoKTtcbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzLmpzXCIpLkRlY2x1dHRlckltYWdlV2l0aFRleHR9ICovXG5cbiAgdmFyIGRlY2x1dHRlckltYWdlV2l0aFRleHQ7XG5cbiAgaWYgKG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgICBidWlsZGVyR3JvdXAgPSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwO1xuICAgIGRlY2x1dHRlckltYWdlV2l0aFRleHQgPSBpbWFnZVN0eWxlICYmIHRleHRTdHlsZSAmJiB0ZXh0U3R5bGUuZ2V0VGV4dCgpID8ge30gOiB1bmRlZmluZWQ7XG4gIH1cblxuICBpZiAoaW1hZ2VTdHlsZSkge1xuICAgIGlmIChpbWFnZVN0eWxlLmdldEltYWdlU3RhdGUoKSAhPSBJbWFnZVN0YXRlLkxPQURFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBpbWFnZVJlcGxheSA9IGJ1aWxkZXJHcm91cC5nZXRCdWlsZGVyKHN0eWxlLmdldFpJbmRleCgpLCBCdWlsZGVyVHlwZS5JTUFHRSk7XG4gICAgaW1hZ2VSZXBsYXkuc2V0SW1hZ2VTdHlsZShpbWFnZVN0eWxlLCBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0KTtcbiAgICBpbWFnZVJlcGxheS5kcmF3TXVsdGlQb2ludChnZW9tZXRyeSwgZmVhdHVyZSk7XG4gIH1cblxuICBpZiAodGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkpIHtcbiAgICB2YXIgdGV4dFJlcGxheSA9IChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIHx8IGJ1aWxkZXJHcm91cCkuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlLCBkZWNsdXR0ZXJJbWFnZVdpdGhUZXh0KTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBSZXBsYXkgZ3JvdXAuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vUG9seWdvbi5qc1wiKS5kZWZhdWx0fGltcG9ydChcIi4uL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBzdHlsZSBTdHlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCBCdWlsZGVyIGZvciBkZWNsdXR0ZXJpbmcuXG4gKi9cblxuXG5mdW5jdGlvbiByZW5kZXJQb2x5Z29uR2VvbWV0cnkoYnVpbGRlckdyb3VwLCBnZW9tZXRyeSwgc3R5bGUsIGZlYXR1cmUsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgdmFyIGZpbGxTdHlsZSA9IHN0eWxlLmdldEZpbGwoKTtcbiAgdmFyIHN0cm9rZVN0eWxlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG5cbiAgaWYgKGZpbGxTdHlsZSB8fCBzdHJva2VTdHlsZSkge1xuICAgIHZhciBwb2x5Z29uUmVwbGF5ID0gYnVpbGRlckdyb3VwLmdldEJ1aWxkZXIoc3R5bGUuZ2V0WkluZGV4KCksIEJ1aWxkZXJUeXBlLlBPTFlHT04pO1xuICAgIHBvbHlnb25SZXBsYXkuc2V0RmlsbFN0cm9rZVN0eWxlKGZpbGxTdHlsZSwgc3Ryb2tlU3R5bGUpO1xuICAgIHBvbHlnb25SZXBsYXkuZHJhd1BvbHlnb24oZ2VvbWV0cnksIGZlYXR1cmUpO1xuICB9XG5cbiAgdmFyIHRleHRTdHlsZSA9IHN0eWxlLmdldFRleHQoKTtcblxuICBpZiAodGV4dFN0eWxlICYmIHRleHRTdHlsZS5nZXRUZXh0KCkpIHtcbiAgICB2YXIgdGV4dFJlcGxheSA9IChvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIHx8IGJ1aWxkZXJHcm91cCkuZ2V0QnVpbGRlcihzdHlsZS5nZXRaSW5kZXgoKSwgQnVpbGRlclR5cGUuVEVYVCk7XG4gICAgdGV4dFJlcGxheS5zZXRUZXh0U3R5bGUodGV4dFN0eWxlKTtcbiAgICB0ZXh0UmVwbGF5LmRyYXdUZXh0KGdlb21ldHJ5LCBmZWF0dXJlKTtcbiAgfVxufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvcmVuZGVyZXIvY2FudmFzL1ZlY3RvckxheWVyXG4gKi9cblxuXG5pbXBvcnQgQ2FudmFzQnVpbGRlckdyb3VwIGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzJztcbmltcG9ydCBDYW52YXNMYXllclJlbmRlcmVyIGZyb20gJy4vTGF5ZXIuanMnO1xuaW1wb3J0IEV4ZWN1dG9yR3JvdXAgZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwLmpzJztcbmltcG9ydCBWaWV3SGludCBmcm9tICcuLi8uLi9WaWV3SGludC5qcyc7XG5pbXBvcnQgeyBhcHBseSwgbWFrZUludmVyc2UsIG1ha2VTY2FsZSwgdG9TdHJpbmcgYXMgdHJhbnNmb3JtVG9TdHJpbmcgfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgYnVmZmVyLCBjb250YWluc0V4dGVudCwgY3JlYXRlRW1wdHksIGdldFdpZHRoLCBpbnRlcnNlY3RzIGFzIGludGVyc2VjdHNFeHRlbnQsIHdyYXBYIGFzIHdyYXBFeHRlbnRYIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YSwgaGl0RGV0ZWN0IH0gZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9oaXRkZXRlY3QuanMnO1xuaW1wb3J0IHsgZGVmYXVsdE9yZGVyIGFzIGRlZmF1bHRSZW5kZXJPcmRlciwgZ2V0VG9sZXJhbmNlIGFzIGdldFJlbmRlclRvbGVyYW5jZSwgZ2V0U3F1YXJlZFRvbGVyYW5jZSBhcyBnZXRTcXVhcmVkUmVuZGVyVG9sZXJhbmNlLCByZW5kZXJGZWF0dXJlIH0gZnJvbSAnLi4vdmVjdG9yLmpzJztcbmltcG9ydCB7IGZyb21Vc2VyRXh0ZW50LCBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMsIGdldFVzZXJQcm9qZWN0aW9uLCB0b1VzZXJFeHRlbnQgfSBmcm9tICcuLi8uLi9wcm9qLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uLy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgd3JhcFggYXMgd3JhcENvb3JkaW5hdGVYIH0gZnJvbSAnLi4vLi4vY29vcmRpbmF0ZS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENhbnZhcyByZW5kZXJlciBmb3IgdmVjdG9yIGxheWVycy5cbiAqIEBhcGlcbiAqL1xuXG52YXIgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3IuanNcIikuZGVmYXVsdH0gdmVjdG9yTGF5ZXIgVmVjdG9yIGxheWVyLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIodmVjdG9yTGF5ZXIpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB2ZWN0b3JMYXllcikgfHwgdGhpcztcbiAgICAvKiogQHByaXZhdGUgKi9cblxuXG4gICAgX3RoaXMuYm91bmRIYW5kbGVTdHlsZUltYWdlQ2hhbmdlXyA9IF90aGlzLmhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfLmJpbmQoX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuYW5pbWF0aW5nT3JJbnRlcmFjdGluZ187XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRpcnR5XyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtJbWFnZURhdGF9XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGFfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkRmVhdHVyZXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUmVzb2x1dGlvbl8gPSBOYU47XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkRXh0ZW50XyA9IGNyZWF0ZUVtcHR5KCk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRSb3RhdGlvbl87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZVwiKS5Db29yZGluYXRlfVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRDZW50ZXJfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb25cIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUHJvamVjdGlvbl8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKGltcG9ydChcIi4uLy4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdCwgaW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0KTogbnVtYmVyfG51bGx9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJlbmRlck9yZGVyXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZXBsYXlHcm91cF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEEgbmV3IHJlcGxheSBncm91cCBoYWQgdG8gYmUgY3JlYXRlZCBieSBgcHJlcGFyZUZyYW1lKClgXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5yZXBsYXlHcm91cENoYW5nZWQgPSB0cnVlO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9yZW5kZXIvY2FudmFzL0V4ZWN1dG9yR3JvdXBcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXAgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIENsaXBwaW5nIHRvIGJlIHBlcmZvcm1lZCBieSBgcmVuZGVyRnJhbWUoKWBcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmNsaXBwaW5nID0gdHJ1ZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIHJlbmRlcmluZyBjb250YWluZXIgZnJvbSBhbiBleGlzdGluZyB0YXJnZXQsIGlmIGNvbXBhdGlibGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBQb3RlbnRpYWwgcmVuZGVyIHRhcmdldC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRyYW5zZm9ybSBDU1MgVHJhbnNmb3JtLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb3BhY2l0eSBPcGFjaXR5LlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLnVzZUNvbnRhaW5lciA9IGZ1bmN0aW9uICh0YXJnZXQsIHRyYW5zZm9ybSwgb3BhY2l0eSkge1xuICAgIGlmIChvcGFjaXR5IDwgMSkge1xuICAgICAgdGFyZ2V0ID0gbnVsbDtcbiAgICB9XG5cbiAgICBfc3VwZXIucHJvdG90eXBlLnVzZUNvbnRhaW5lci5jYWxsKHRoaXMsIHRhcmdldCwgdHJhbnNmb3JtLCBvcGFjaXR5KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RXhlY3V0b3JHcm91cH0gZXhlY3V0b3JHcm91cCBFeGVjdXRvciBncm91cC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCJyYnVzaFwiKS5kZWZhdWx0PX0gb3B0X2RlY2x1dHRlclRyZWUgRGVjbHV0dGVyIHRyZWUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyV29ybGRzID0gZnVuY3Rpb24gKGV4ZWN1dG9yR3JvdXAsIGZyYW1lU3RhdGUsIG9wdF9kZWNsdXR0ZXJUcmVlKSB7XG4gICAgdmFyIGV4dGVudCA9IGZyYW1lU3RhdGUuZXh0ZW50O1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgY2VudGVyID0gdmlld1N0YXRlLmNlbnRlcjtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciBwcm9qZWN0aW9uID0gdmlld1N0YXRlLnByb2plY3Rpb247XG4gICAgdmFyIHJvdGF0aW9uID0gdmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIHZhciBwcm9qZWN0aW9uRXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcbiAgICB2YXIgdmVjdG9yU291cmNlID0gdGhpcy5nZXRMYXllcigpLmdldFNvdXJjZSgpO1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciB2aWV3SGludHMgPSBmcmFtZVN0YXRlLnZpZXdIaW50cztcbiAgICB2YXIgc25hcFRvUGl4ZWwgPSAhKHZpZXdIaW50c1tWaWV3SGludC5BTklNQVRJTkddIHx8IHZpZXdIaW50c1tWaWV3SGludC5JTlRFUkFDVElOR10pO1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoZnJhbWVTdGF0ZS5zaXplWzBdICogcGl4ZWxSYXRpbyk7XG4gICAgdmFyIGhlaWdodCA9IE1hdGgucm91bmQoZnJhbWVTdGF0ZS5zaXplWzFdICogcGl4ZWxSYXRpbyk7XG4gICAgdmFyIG11bHRpV29ybGQgPSB2ZWN0b3JTb3VyY2UuZ2V0V3JhcFgoKSAmJiBwcm9qZWN0aW9uLmNhbldyYXBYKCk7XG4gICAgdmFyIHdvcmxkV2lkdGggPSBtdWx0aVdvcmxkID8gZ2V0V2lkdGgocHJvamVjdGlvbkV4dGVudCkgOiBudWxsO1xuICAgIHZhciBlbmRXb3JsZCA9IG11bHRpV29ybGQgPyBNYXRoLmNlaWwoKGV4dGVudFsyXSAtIHByb2plY3Rpb25FeHRlbnRbMl0pIC8gd29ybGRXaWR0aCkgKyAxIDogMTtcbiAgICB2YXIgd29ybGQgPSBtdWx0aVdvcmxkID8gTWF0aC5mbG9vcigoZXh0ZW50WzBdIC0gcHJvamVjdGlvbkV4dGVudFswXSkgLyB3b3JsZFdpZHRoKSA6IDA7XG5cbiAgICBkbyB7XG4gICAgICB2YXIgdHJhbnNmb3JtID0gdGhpcy5nZXRSZW5kZXJUcmFuc2Zvcm0oY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgcGl4ZWxSYXRpbywgd2lkdGgsIGhlaWdodCwgd29ybGQgKiB3b3JsZFdpZHRoKTtcbiAgICAgIGV4ZWN1dG9yR3JvdXAuZXhlY3V0ZShjb250ZXh0LCAxLCB0cmFuc2Zvcm0sIHJvdGF0aW9uLCBzbmFwVG9QaXhlbCwgdW5kZWZpbmVkLCBvcHRfZGVjbHV0dGVyVHJlZSk7XG4gICAgfSB3aGlsZSAoKyt3b3JsZCA8IGVuZFdvcmxkKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciBkZWNsdXR0ZXIgaXRlbXMgZm9yIHRoaXMgbGF5ZXJcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJEZWNsdXR0ZXIgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIGlmICh0aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXApIHtcbiAgICAgIHRoaXMucmVuZGVyV29ybGRzKHRoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cCwgZnJhbWVTdGF0ZSwgZnJhbWVTdGF0ZS5kZWNsdXR0ZXJUcmVlKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgdGhlIGxheWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YXJnZXQgVGFyZ2V0IHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVuZGVyIGNvbnRlbnQgdG8uXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgcmVuZGVyZWQgZWxlbWVudC5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0YXJnZXQpIHtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgbGF5ZXJTdGF0ZSA9IGZyYW1lU3RhdGUubGF5ZXJTdGF0ZXNBcnJheVtmcmFtZVN0YXRlLmxheWVySW5kZXhdOyAvLyBzZXQgZm9yd2FyZCBhbmQgaW52ZXJzZSBwaXhlbCB0cmFuc2Zvcm1zXG5cbiAgICBtYWtlU2NhbGUodGhpcy5waXhlbFRyYW5zZm9ybSwgMSAvIHBpeGVsUmF0aW8sIDEgLyBwaXhlbFJhdGlvKTtcbiAgICBtYWtlSW52ZXJzZSh0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybSwgdGhpcy5waXhlbFRyYW5zZm9ybSk7XG4gICAgdmFyIGNhbnZhc1RyYW5zZm9ybSA9IHRyYW5zZm9ybVRvU3RyaW5nKHRoaXMucGl4ZWxUcmFuc2Zvcm0pO1xuICAgIHRoaXMudXNlQ29udGFpbmVyKHRhcmdldCwgY2FudmFzVHJhbnNmb3JtLCBsYXllclN0YXRlLm9wYWNpdHkpO1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgIHZhciBjYW52YXMgPSBjb250ZXh0LmNhbnZhcztcbiAgICB2YXIgcmVwbGF5R3JvdXAgPSB0aGlzLnJlcGxheUdyb3VwXztcbiAgICB2YXIgZGVjbHV0dGVyRXhlY3V0b3JHcm91cCA9IHRoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cDtcblxuICAgIGlmICgoIXJlcGxheUdyb3VwIHx8IHJlcGxheUdyb3VwLmlzRW1wdHkoKSkgJiYgKCFkZWNsdXR0ZXJFeGVjdXRvckdyb3VwIHx8IGRlY2x1dHRlckV4ZWN1dG9yR3JvdXAuaXNFbXB0eSgpKSkge1xuICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lclJldXNlZCAmJiBjYW52YXMud2lkdGggPiAwKSB7XG4gICAgICAgIGNhbnZhcy53aWR0aCA9IDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbnRhaW5lcjtcbiAgICB9IC8vIHJlc2l6ZSBhbmQgY2xlYXJcblxuXG4gICAgdmFyIHdpZHRoID0gTWF0aC5yb3VuZChmcmFtZVN0YXRlLnNpemVbMF0gKiBwaXhlbFJhdGlvKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChmcmFtZVN0YXRlLnNpemVbMV0gKiBwaXhlbFJhdGlvKTtcblxuICAgIGlmIChjYW52YXMud2lkdGggIT0gd2lkdGggfHwgY2FudmFzLmhlaWdodCAhPSBoZWlnaHQpIHtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcblxuICAgICAgaWYgKGNhbnZhcy5zdHlsZS50cmFuc2Zvcm0gIT09IGNhbnZhc1RyYW5zZm9ybSkge1xuICAgICAgICBjYW52YXMuc3R5bGUudHJhbnNmb3JtID0gY2FudmFzVHJhbnNmb3JtO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIXRoaXMuY29udGFpbmVyUmV1c2VkKSB7XG4gICAgICBjb250ZXh0LmNsZWFyUmVjdCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG5cbiAgICB0aGlzLnByZVJlbmRlcihjb250ZXh0LCBmcmFtZVN0YXRlKTtcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdmFyIHByb2plY3Rpb24gPSB2aWV3U3RhdGUucHJvamVjdGlvbjsgLy8gY2xpcHBlZCByZW5kZXJpbmcgaWYgbGF5ZXIgZXh0ZW50IGlzIHNldFxuXG4gICAgdmFyIGNsaXBwZWQgPSBmYWxzZTtcblxuICAgIGlmIChsYXllclN0YXRlLmV4dGVudCAmJiB0aGlzLmNsaXBwaW5nKSB7XG4gICAgICB2YXIgbGF5ZXJFeHRlbnQgPSBmcm9tVXNlckV4dGVudChsYXllclN0YXRlLmV4dGVudCwgcHJvamVjdGlvbik7XG4gICAgICBjbGlwcGVkID0gIWNvbnRhaW5zRXh0ZW50KGxheWVyRXh0ZW50LCBmcmFtZVN0YXRlLmV4dGVudCkgJiYgaW50ZXJzZWN0c0V4dGVudChsYXllckV4dGVudCwgZnJhbWVTdGF0ZS5leHRlbnQpO1xuXG4gICAgICBpZiAoY2xpcHBlZCkge1xuICAgICAgICB0aGlzLmNsaXBVbnJvdGF0ZWQoY29udGV4dCwgZnJhbWVTdGF0ZSwgbGF5ZXJFeHRlbnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucmVuZGVyV29ybGRzKHJlcGxheUdyb3VwLCBmcmFtZVN0YXRlKTtcblxuICAgIGlmIChjbGlwcGVkKSB7XG4gICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvc3RSZW5kZXIoY29udGV4dCwgZnJhbWVTdGF0ZSk7XG4gICAgdmFyIG9wYWNpdHkgPSBsYXllclN0YXRlLm9wYWNpdHk7XG4gICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuXG4gICAgaWYgKG9wYWNpdHkgIT09IHBhcnNlRmxvYXQoY29udGFpbmVyLnN0eWxlLm9wYWNpdHkpKSB7XG4gICAgICBjb250YWluZXIuc3R5bGUub3BhY2l0eSA9IG9wYWNpdHkgPT09IDEgPyAnJyA6IFN0cmluZyhvcGFjaXR5KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5yZW5kZXJlZFJvdGF0aW9uXyAhPT0gdmlld1N0YXRlLnJvdGF0aW9uKSB7XG4gICAgICB0aGlzLnJlbmRlcmVkUm90YXRpb25fID0gdmlld1N0YXRlLnJvdGF0aW9uO1xuICAgICAgdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGFfID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH07XG4gIC8qKlxuICAgKiBBc3luY2hyb25vdXMgbGF5ZXIgbGV2ZWwgaGl0IGRldGVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9waXhlbC5qc1wiKS5QaXhlbH0gcGl4ZWwgUGl4ZWwuXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8aW1wb3J0KFwiLi4vLi4vRmVhdHVyZVwiKS5kZWZhdWx0Pj59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGZlYXR1cmVzLlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldEZlYXR1cmVzID0gZnVuY3Rpb24gKHBpeGVsKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oQXJyYXk8aW1wb3J0KFwiLi4vLi4vRmVhdHVyZVwiKS5kZWZhdWx0fGltcG9ydChcIi4uLy4uL3JlbmRlci9GZWF0dXJlXCIpLmRlZmF1bHQ+KTogdm9pZH0gcmVzb2x2ZSBSZXNvbHZlciBmdW5jdGlvbi5cbiAgICAgKiBAdGhpcyB7Q2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlcn1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgaWYgKCF0aGlzLmhpdERldGVjdGlvbkltYWdlRGF0YV8gJiYgIXRoaXMuYW5pbWF0aW5nT3JJbnRlcmFjdGluZ18pIHtcbiAgICAgICAgdmFyIHNpemUgPSBbdGhpcy5jb250ZXh0LmNhbnZhcy53aWR0aCwgdGhpcy5jb250ZXh0LmNhbnZhcy5oZWlnaHRdO1xuICAgICAgICBhcHBseSh0aGlzLnBpeGVsVHJhbnNmb3JtLCBzaXplKTtcbiAgICAgICAgdmFyIGNlbnRlciA9IHRoaXMucmVuZGVyZWRDZW50ZXJfO1xuICAgICAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMucmVuZGVyZWRSZXNvbHV0aW9uXztcbiAgICAgICAgdmFyIHJvdGF0aW9uID0gdGhpcy5yZW5kZXJlZFJvdGF0aW9uXztcbiAgICAgICAgdmFyIHByb2plY3Rpb24gPSB0aGlzLnJlbmRlcmVkUHJvamVjdGlvbl87XG4gICAgICAgIHZhciBleHRlbnQgPSB0aGlzLnJlbmRlcmVkRXh0ZW50XztcbiAgICAgICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgICAgICB2YXIgdHJhbnNmb3JtcyA9IFtdO1xuICAgICAgICB2YXIgd2lkdGggPSBzaXplWzBdIC8gMjtcbiAgICAgICAgdmFyIGhlaWdodCA9IHNpemVbMV0gLyAyO1xuICAgICAgICB0cmFuc2Zvcm1zLnB1c2godGhpcy5nZXRSZW5kZXJUcmFuc2Zvcm0oY2VudGVyLCByZXNvbHV0aW9uLCByb3RhdGlvbiwgMC41LCB3aWR0aCwgaGVpZ2h0LCAwKS5zbGljZSgpKTtcbiAgICAgICAgdmFyIHNvdXJjZSA9IGxheWVyLmdldFNvdXJjZSgpO1xuICAgICAgICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG5cbiAgICAgICAgaWYgKHNvdXJjZS5nZXRXcmFwWCgpICYmIHByb2plY3Rpb24uY2FuV3JhcFgoKSAmJiAhY29udGFpbnNFeHRlbnQocHJvamVjdGlvbkV4dGVudCwgZXh0ZW50KSkge1xuICAgICAgICAgIHZhciBzdGFydFggPSBleHRlbnRbMF07XG4gICAgICAgICAgdmFyIHdvcmxkV2lkdGggPSBnZXRXaWR0aChwcm9qZWN0aW9uRXh0ZW50KTtcbiAgICAgICAgICB2YXIgd29ybGQgPSAwO1xuICAgICAgICAgIHZhciBvZmZzZXRYID0gdm9pZCAwO1xuXG4gICAgICAgICAgd2hpbGUgKHN0YXJ0WCA8IHByb2plY3Rpb25FeHRlbnRbMF0pIHtcbiAgICAgICAgICAgIC0td29ybGQ7XG4gICAgICAgICAgICBvZmZzZXRYID0gd29ybGRXaWR0aCAqIHdvcmxkO1xuICAgICAgICAgICAgdHJhbnNmb3Jtcy5wdXNoKHRoaXMuZ2V0UmVuZGVyVHJhbnNmb3JtKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIDAuNSwgd2lkdGgsIGhlaWdodCwgb2Zmc2V0WCkuc2xpY2UoKSk7XG4gICAgICAgICAgICBzdGFydFggKz0gd29ybGRXaWR0aDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB3b3JsZCA9IDA7XG4gICAgICAgICAgc3RhcnRYID0gZXh0ZW50WzJdO1xuXG4gICAgICAgICAgd2hpbGUgKHN0YXJ0WCA+IHByb2plY3Rpb25FeHRlbnRbMl0pIHtcbiAgICAgICAgICAgICsrd29ybGQ7XG4gICAgICAgICAgICBvZmZzZXRYID0gd29ybGRXaWR0aCAqIHdvcmxkO1xuICAgICAgICAgICAgdHJhbnNmb3Jtcy5wdXNoKHRoaXMuZ2V0UmVuZGVyVHJhbnNmb3JtKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIDAuNSwgd2lkdGgsIGhlaWdodCwgb2Zmc2V0WCkuc2xpY2UoKSk7XG4gICAgICAgICAgICBzdGFydFggLT0gd29ybGRXaWR0aDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhpdERldGVjdGlvbkltYWdlRGF0YV8gPSBjcmVhdGVIaXREZXRlY3Rpb25JbWFnZURhdGEoc2l6ZSwgdHJhbnNmb3JtcywgdGhpcy5yZW5kZXJlZEZlYXR1cmVzXywgbGF5ZXIuZ2V0U3R5bGVGdW5jdGlvbigpLCBleHRlbnQsIHJlc29sdXRpb24sIHJvdGF0aW9uKTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZShoaXREZXRlY3QocGl4ZWwsIHRoaXMucmVuZGVyZWRGZWF0dXJlc18sIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhXykpO1xuICAgIH0uYmluZCh0aGlzKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaGl0VG9sZXJhbmNlIEhpdCB0b2xlcmFuY2UgaW4gcGl4ZWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3ZlY3Rvci5qc1wiKS5GZWF0dXJlQ2FsbGJhY2s8VD59IGNhbGxiYWNrIEZlYXR1cmUgY2FsbGJhY2suXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vTWFwLmpzXCIpLkhpdE1hdGNoPFQ+Pn0gbWF0Y2hlcyBUaGUgaGl0IGRldGVjdGVkIG1hdGNoZXMgd2l0aCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgZnJhbWVTdGF0ZSwgaGl0VG9sZXJhbmNlLCBjYWxsYmFjaywgbWF0Y2hlcykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICBpZiAoIXRoaXMucmVwbGF5R3JvdXBfKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHZhciByZXNvbHV0aW9uID0gZnJhbWVTdGF0ZS52aWV3U3RhdGUucmVzb2x1dGlvbjtcbiAgICB2YXIgcm90YXRpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG4gICAgLyoqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vTWFwLmpzXCIpLkhpdE1hdGNoPFQ+fHRydWU+fSAqL1xuXG4gICAgdmFyIGZlYXR1cmVzID0ge307XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBmZWF0dXJlIEZlYXR1cmUuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9nZW9tL1NpbXBsZUdlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkaXN0YW5jZVNxIFRoZSBzcXVhcmVkIGRpc3RhbmNlIHRvIHRoZSBjbGljayBwb3NpdGlvblxuICAgICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBDYWxsYmFjayByZXN1bHQuXG4gICAgICovXG5cbiAgICB2YXIgZmVhdHVyZUNhbGxiYWNrID0gZnVuY3Rpb24gZmVhdHVyZUNhbGxiYWNrKGZlYXR1cmUsIGdlb21ldHJ5LCBkaXN0YW5jZVNxKSB7XG4gICAgICB2YXIga2V5ID0gZ2V0VWlkKGZlYXR1cmUpO1xuICAgICAgdmFyIG1hdGNoID0gZmVhdHVyZXNba2V5XTtcblxuICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICBpZiAoZGlzdGFuY2VTcSA9PT0gMCkge1xuICAgICAgICAgIGZlYXR1cmVzW2tleV0gPSB0cnVlO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhmZWF0dXJlLCBsYXllciwgZ2VvbWV0cnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWF0Y2hlcy5wdXNoKGZlYXR1cmVzW2tleV0gPSB7XG4gICAgICAgICAgZmVhdHVyZTogZmVhdHVyZSxcbiAgICAgICAgICBsYXllcjogbGF5ZXIsXG4gICAgICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5LFxuICAgICAgICAgIGRpc3RhbmNlU3E6IGRpc3RhbmNlU3EsXG4gICAgICAgICAgY2FsbGJhY2s6IGNhbGxiYWNrXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChtYXRjaCAhPT0gdHJ1ZSAmJiBkaXN0YW5jZVNxIDwgbWF0Y2guZGlzdGFuY2VTcSkge1xuICAgICAgICBpZiAoZGlzdGFuY2VTcSA9PT0gMCkge1xuICAgICAgICAgIGZlYXR1cmVzW2tleV0gPSB0cnVlO1xuICAgICAgICAgIG1hdGNoZXMuc3BsaWNlKG1hdGNoZXMubGFzdEluZGV4T2YobWF0Y2gpLCAxKTtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZmVhdHVyZSwgbGF5ZXIsIGdlb21ldHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1hdGNoLmdlb21ldHJ5ID0gZ2VvbWV0cnk7XG4gICAgICAgIG1hdGNoLmRpc3RhbmNlU3EgPSBkaXN0YW5jZVNxO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH07XG5cbiAgICB2YXIgcmVzdWx0O1xuICAgIHZhciBleGVjdXRvckdyb3VwcyA9IFt0aGlzLnJlcGxheUdyb3VwX107XG5cbiAgICBpZiAodGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwKSB7XG4gICAgICBleGVjdXRvckdyb3Vwcy5wdXNoKHRoaXMuZGVjbHV0dGVyRXhlY3V0b3JHcm91cCk7XG4gICAgfVxuXG4gICAgZXhlY3V0b3JHcm91cHMuc29tZShmdW5jdGlvbiAoZXhlY3V0b3JHcm91cCkge1xuICAgICAgcmV0dXJuIHJlc3VsdCA9IGV4ZWN1dG9yR3JvdXAuZm9yRWFjaEZlYXR1cmVBdENvb3JkaW5hdGUoY29vcmRpbmF0ZSwgcmVzb2x1dGlvbiwgcm90YXRpb24sIGhpdFRvbGVyYW5jZSwgZmVhdHVyZUNhbGxiYWNrLCBleGVjdXRvckdyb3VwID09PSBfdGhpcy5kZWNsdXR0ZXJFeGVjdXRvckdyb3VwID8gZnJhbWVTdGF0ZS5kZWNsdXR0ZXJUcmVlLmFsbCgpLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICByZXR1cm4gaXRlbS52YWx1ZTtcbiAgICAgIH0pIDogbnVsbCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcbiAgLyoqXG4gICAqIFBlcmZvcm0gYWN0aW9uIG5lY2Vzc2FyeSB0byBnZXQgdGhlIGxheWVyIHJlbmRlcmVkIGFmdGVyIG5ldyBmb250cyBoYXZlIGxvYWRlZFxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIucHJvdG90eXBlLmhhbmRsZUZvbnRzQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG5cbiAgICBpZiAobGF5ZXIuZ2V0VmlzaWJsZSgpICYmIHRoaXMucmVwbGF5R3JvdXBfKSB7XG4gICAgICBsYXllci5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlIGNoYW5nZXMgaW4gaW1hZ2Ugc3R5bGUgc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEltYWdlIHN0eWxlIGNoYW5nZSBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5oYW5kbGVTdHlsZUltYWdlQ2hhbmdlXyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIHRoaXMucmVuZGVySWZSZWFkeUFuZFZpc2libGUoKTtcbiAgfTtcbiAgLyoqXG4gICAqIERldGVybWluZSB3aGV0aGVyIHJlbmRlciBzaG91bGQgYmUgY2FsbGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBMYXllciBpcyByZWFkeSB0byBiZSByZW5kZXJlZC5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyLnByb3RvdHlwZS5wcmVwYXJlRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHZhciB2ZWN0b3JMYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgdmVjdG9yU291cmNlID0gdmVjdG9yTGF5ZXIuZ2V0U291cmNlKCk7XG5cbiAgICBpZiAoIXZlY3RvclNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBhbmltYXRpbmcgPSBmcmFtZVN0YXRlLnZpZXdIaW50c1tWaWV3SGludC5BTklNQVRJTkddO1xuICAgIHZhciBpbnRlcmFjdGluZyA9IGZyYW1lU3RhdGUudmlld0hpbnRzW1ZpZXdIaW50LklOVEVSQUNUSU5HXTtcbiAgICB2YXIgdXBkYXRlV2hpbGVBbmltYXRpbmcgPSB2ZWN0b3JMYXllci5nZXRVcGRhdGVXaGlsZUFuaW1hdGluZygpO1xuICAgIHZhciB1cGRhdGVXaGlsZUludGVyYWN0aW5nID0gdmVjdG9yTGF5ZXIuZ2V0VXBkYXRlV2hpbGVJbnRlcmFjdGluZygpO1xuXG4gICAgaWYgKCF0aGlzLmRpcnR5XyAmJiAhdXBkYXRlV2hpbGVBbmltYXRpbmcgJiYgYW5pbWF0aW5nIHx8ICF1cGRhdGVXaGlsZUludGVyYWN0aW5nICYmIGludGVyYWN0aW5nKSB7XG4gICAgICB0aGlzLmFuaW1hdGluZ09ySW50ZXJhY3RpbmdfID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHRoaXMuYW5pbWF0aW5nT3JJbnRlcmFjdGluZ18gPSBmYWxzZTtcbiAgICB2YXIgZnJhbWVTdGF0ZUV4dGVudCA9IGZyYW1lU3RhdGUuZXh0ZW50O1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgcHJvamVjdGlvbiA9IHZpZXdTdGF0ZS5wcm9qZWN0aW9uO1xuICAgIHZhciByZXNvbHV0aW9uID0gdmlld1N0YXRlLnJlc29sdXRpb247XG4gICAgdmFyIHBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW87XG4gICAgdmFyIHZlY3RvckxheWVyUmV2aXNpb24gPSB2ZWN0b3JMYXllci5nZXRSZXZpc2lvbigpO1xuICAgIHZhciB2ZWN0b3JMYXllclJlbmRlckJ1ZmZlciA9IHZlY3RvckxheWVyLmdldFJlbmRlckJ1ZmZlcigpO1xuICAgIHZhciB2ZWN0b3JMYXllclJlbmRlck9yZGVyID0gdmVjdG9yTGF5ZXIuZ2V0UmVuZGVyT3JkZXIoKTtcblxuICAgIGlmICh2ZWN0b3JMYXllclJlbmRlck9yZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHZlY3RvckxheWVyUmVuZGVyT3JkZXIgPSBkZWZhdWx0UmVuZGVyT3JkZXI7XG4gICAgfVxuXG4gICAgdmFyIGNlbnRlciA9IHZpZXdTdGF0ZS5jZW50ZXIuc2xpY2UoKTtcbiAgICB2YXIgZXh0ZW50ID0gYnVmZmVyKGZyYW1lU3RhdGVFeHRlbnQsIHZlY3RvckxheWVyUmVuZGVyQnVmZmVyICogcmVzb2x1dGlvbik7XG4gICAgdmFyIGxvYWRFeHRlbnRzID0gW2V4dGVudC5zbGljZSgpXTtcbiAgICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG5cbiAgICBpZiAodmVjdG9yU291cmNlLmdldFdyYXBYKCkgJiYgcHJvamVjdGlvbi5jYW5XcmFwWCgpICYmICFjb250YWluc0V4dGVudChwcm9qZWN0aW9uRXh0ZW50LCBmcmFtZVN0YXRlLmV4dGVudCkpIHtcbiAgICAgIC8vIEZvciB0aGUgcmVwbGF5IGdyb3VwLCB3ZSBuZWVkIGFuIGV4dGVudCB0aGF0IGludGVyc2VjdHMgdGhlIHJlYWwgd29ybGRcbiAgICAgIC8vICgtMTgwwrAgdG8gKzE4MMKwKS4gVG8gc3VwcG9ydCBnZW9tZXRyaWVzIGluIGEgY29vcmRpbmF0ZSByYW5nZSBmcm9tIC01NDDCsFxuICAgICAgLy8gdG8gKzU0MMKwLCB3ZSBhZGQgYXQgbGVhc3QgMSB3b3JsZCB3aWR0aCBvbiBlYWNoIHNpZGUgb2YgdGhlIHByb2plY3Rpb25cbiAgICAgIC8vIGV4dGVudC4gSWYgdGhlIHZpZXdwb3J0IGlzIHdpZGVyIHRoYW4gdGhlIHdvcmxkLCB3ZSBuZWVkIHRvIGFkZCBoYWxmIG9mXG4gICAgICAvLyB0aGUgdmlld3BvcnQgd2lkdGggdG8gbWFrZSBzdXJlIHdlIGNvdmVyIHRoZSB3aG9sZSB2aWV3cG9ydC5cbiAgICAgIHZhciB3b3JsZFdpZHRoID0gZ2V0V2lkdGgocHJvamVjdGlvbkV4dGVudCk7XG4gICAgICB2YXIgZ3V0dGVyID0gTWF0aC5tYXgoZ2V0V2lkdGgoZXh0ZW50KSAvIDIsIHdvcmxkV2lkdGgpO1xuICAgICAgZXh0ZW50WzBdID0gcHJvamVjdGlvbkV4dGVudFswXSAtIGd1dHRlcjtcbiAgICAgIGV4dGVudFsyXSA9IHByb2plY3Rpb25FeHRlbnRbMl0gKyBndXR0ZXI7XG4gICAgICB3cmFwQ29vcmRpbmF0ZVgoY2VudGVyLCBwcm9qZWN0aW9uKTtcbiAgICAgIHZhciBsb2FkRXh0ZW50ID0gd3JhcEV4dGVudFgobG9hZEV4dGVudHNbMF0sIHByb2plY3Rpb24pOyAvLyBJZiB0aGUgZXh0ZW50IGNyb3NzZXMgdGhlIGRhdGUgbGluZSwgd2UgbG9hZCBkYXRhIGZvciBib3RoIGVkZ2VzIG9mIHRoZSB3b3JsZHNcblxuICAgICAgaWYgKGxvYWRFeHRlbnRbMF0gPCBwcm9qZWN0aW9uRXh0ZW50WzBdICYmIGxvYWRFeHRlbnRbMl0gPCBwcm9qZWN0aW9uRXh0ZW50WzJdKSB7XG4gICAgICAgIGxvYWRFeHRlbnRzLnB1c2goW2xvYWRFeHRlbnRbMF0gKyB3b3JsZFdpZHRoLCBsb2FkRXh0ZW50WzFdLCBsb2FkRXh0ZW50WzJdICsgd29ybGRXaWR0aCwgbG9hZEV4dGVudFszXV0pO1xuICAgICAgfSBlbHNlIGlmIChsb2FkRXh0ZW50WzBdID4gcHJvamVjdGlvbkV4dGVudFswXSAmJiBsb2FkRXh0ZW50WzJdID4gcHJvamVjdGlvbkV4dGVudFsyXSkge1xuICAgICAgICBsb2FkRXh0ZW50cy5wdXNoKFtsb2FkRXh0ZW50WzBdIC0gd29ybGRXaWR0aCwgbG9hZEV4dGVudFsxXSwgbG9hZEV4dGVudFsyXSAtIHdvcmxkV2lkdGgsIGxvYWRFeHRlbnRbM11dKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZGlydHlfICYmIHRoaXMucmVuZGVyZWRSZXNvbHV0aW9uXyA9PSByZXNvbHV0aW9uICYmIHRoaXMucmVuZGVyZWRSZXZpc2lvbl8gPT0gdmVjdG9yTGF5ZXJSZXZpc2lvbiAmJiB0aGlzLnJlbmRlcmVkUmVuZGVyT3JkZXJfID09IHZlY3RvckxheWVyUmVuZGVyT3JkZXIgJiYgY29udGFpbnNFeHRlbnQodGhpcy5yZW5kZXJlZEV4dGVudF8sIGV4dGVudCkpIHtcbiAgICAgIHRoaXMucmVwbGF5R3JvdXBDaGFuZ2VkID0gZmFsc2U7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcGxheUdyb3VwXyA9IG51bGw7XG4gICAgdGhpcy5kaXJ0eV8gPSBmYWxzZTtcbiAgICB2YXIgcmVwbGF5R3JvdXAgPSBuZXcgQ2FudmFzQnVpbGRlckdyb3VwKGdldFJlbmRlclRvbGVyYW5jZShyZXNvbHV0aW9uLCBwaXhlbFJhdGlvKSwgZXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKTtcbiAgICB2YXIgZGVjbHV0dGVyQnVpbGRlckdyb3VwO1xuXG4gICAgaWYgKHRoaXMuZ2V0TGF5ZXIoKS5nZXREZWNsdXR0ZXIoKSkge1xuICAgICAgZGVjbHV0dGVyQnVpbGRlckdyb3VwID0gbmV3IENhbnZhc0J1aWxkZXJHcm91cChnZXRSZW5kZXJUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbyksIGV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbyk7XG4gICAgfVxuXG4gICAgdmFyIHVzZXJQcm9qZWN0aW9uID0gZ2V0VXNlclByb2plY3Rpb24oKTtcbiAgICB2YXIgdXNlclRyYW5zZm9ybTtcblxuICAgIGlmICh1c2VyUHJvamVjdGlvbikge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbG9hZEV4dGVudHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2ZWN0b3JTb3VyY2UubG9hZEZlYXR1cmVzKHRvVXNlckV4dGVudChsb2FkRXh0ZW50c1tpXSwgcHJvamVjdGlvbiksIHJlc29sdXRpb24sIHVzZXJQcm9qZWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgdXNlclRyYW5zZm9ybSA9IGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyh1c2VyUHJvamVjdGlvbiwgcHJvamVjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxvYWRFeHRlbnRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmVjdG9yU291cmNlLmxvYWRGZWF0dXJlcyhsb2FkRXh0ZW50c1tpXSwgcmVzb2x1dGlvbiwgcHJvamVjdGlvbik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHNxdWFyZWRUb2xlcmFuY2UgPSBnZXRTcXVhcmVkUmVuZGVyVG9sZXJhbmNlKHJlc29sdXRpb24sIHBpeGVsUmF0aW8pO1xuXG4gICAgdmFyIHJlbmRlciA9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICAgKiBAdGhpcyB7Q2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlcn1cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgdmFyIHN0eWxlcztcbiAgICAgIHZhciBzdHlsZUZ1bmN0aW9uID0gZmVhdHVyZS5nZXRTdHlsZUZ1bmN0aW9uKCkgfHwgdmVjdG9yTGF5ZXIuZ2V0U3R5bGVGdW5jdGlvbigpO1xuXG4gICAgICBpZiAoc3R5bGVGdW5jdGlvbikge1xuICAgICAgICBzdHlsZXMgPSBzdHlsZUZ1bmN0aW9uKGZlYXR1cmUsIHJlc29sdXRpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3R5bGVzKSB7XG4gICAgICAgIHZhciBkaXJ0eSA9IHRoaXMucmVuZGVyRmVhdHVyZShmZWF0dXJlLCBzcXVhcmVkVG9sZXJhbmNlLCBzdHlsZXMsIHJlcGxheUdyb3VwLCB1c2VyVHJhbnNmb3JtLCBkZWNsdXR0ZXJCdWlsZGVyR3JvdXApO1xuICAgICAgICB0aGlzLmRpcnR5XyA9IHRoaXMuZGlydHlfIHx8IGRpcnR5O1xuICAgICAgfVxuICAgIH0uYmluZCh0aGlzKTtcblxuICAgIHZhciB1c2VyRXh0ZW50ID0gdG9Vc2VyRXh0ZW50KGV4dGVudCwgcHJvamVjdGlvbik7XG4gICAgLyoqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuXG4gICAgdmFyIGZlYXR1cmVzID0gdmVjdG9yU291cmNlLmdldEZlYXR1cmVzSW5FeHRlbnQodXNlckV4dGVudCk7XG5cbiAgICBpZiAodmVjdG9yTGF5ZXJSZW5kZXJPcmRlcikge1xuICAgICAgZmVhdHVyZXMuc29ydCh2ZWN0b3JMYXllclJlbmRlck9yZGVyKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBmZWF0dXJlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICByZW5kZXIoZmVhdHVyZXNbaV0pO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWRGZWF0dXJlc18gPSBmZWF0dXJlcztcbiAgICB2YXIgcmVwbGF5R3JvdXBJbnN0cnVjdGlvbnMgPSByZXBsYXlHcm91cC5maW5pc2goKTtcbiAgICB2YXIgZXhlY3V0b3JHcm91cCA9IG5ldyBFeGVjdXRvckdyb3VwKGV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgdmVjdG9yU291cmNlLmdldE92ZXJsYXBzKCksIHJlcGxheUdyb3VwSW5zdHJ1Y3Rpb25zLCB2ZWN0b3JMYXllci5nZXRSZW5kZXJCdWZmZXIoKSk7XG5cbiAgICBpZiAoZGVjbHV0dGVyQnVpbGRlckdyb3VwKSB7XG4gICAgICB0aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXAgPSBuZXcgRXhlY3V0b3JHcm91cChleHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8sIHZlY3RvclNvdXJjZS5nZXRPdmVybGFwcygpLCBkZWNsdXR0ZXJCdWlsZGVyR3JvdXAuZmluaXNoKCksIHZlY3RvckxheWVyLmdldFJlbmRlckJ1ZmZlcigpKTtcbiAgICB9XG5cbiAgICB0aGlzLnJlbmRlcmVkUmVzb2x1dGlvbl8gPSByZXNvbHV0aW9uO1xuICAgIHRoaXMucmVuZGVyZWRSZXZpc2lvbl8gPSB2ZWN0b3JMYXllclJldmlzaW9uO1xuICAgIHRoaXMucmVuZGVyZWRSZW5kZXJPcmRlcl8gPSB2ZWN0b3JMYXllclJlbmRlck9yZGVyO1xuICAgIHRoaXMucmVuZGVyZWRFeHRlbnRfID0gZXh0ZW50O1xuICAgIHRoaXMucmVuZGVyZWRDZW50ZXJfID0gY2VudGVyO1xuICAgIHRoaXMucmVuZGVyZWRQcm9qZWN0aW9uXyA9IHByb2plY3Rpb247XG4gICAgdGhpcy5yZXBsYXlHcm91cF8gPSBleGVjdXRvckdyb3VwO1xuICAgIHRoaXMuaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhXyA9IG51bGw7XG4gICAgdGhpcy5yZXBsYXlHcm91cENoYW5nZWQgPSB0cnVlO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCByZW5kZXIgdG9sZXJhbmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHR8QXJyYXk8aW1wb3J0KFwiLi4vLi4vc3R5bGUvU3R5bGUuanNcIikuZGVmYXVsdD59IHN0eWxlcyBUaGUgc3R5bGUgb3IgYXJyYXkgb2Ygc3R5bGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHR9IGJ1aWxkZXJHcm91cCBCdWlsZGVyIGdyb3VwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb249fSBvcHRfdHJhbnNmb3JtIFRyYW5zZm9ybSBmcm9tIHVzZXIgdG8gdmlldyBwcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZm9yIGRlY2x1dHRlcmluZy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIGFuIGltYWdlIGlzIGxvYWRpbmcuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyRmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlLCBzcXVhcmVkVG9sZXJhbmNlLCBzdHlsZXMsIGJ1aWxkZXJHcm91cCwgb3B0X3RyYW5zZm9ybSwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICAgIGlmICghc3R5bGVzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIGxvYWRpbmcgPSBmYWxzZTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHN0eWxlcykpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHN0eWxlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGxvYWRpbmcgPSByZW5kZXJGZWF0dXJlKGJ1aWxkZXJHcm91cCwgZmVhdHVyZSwgc3R5bGVzW2ldLCBzcXVhcmVkVG9sZXJhbmNlLCB0aGlzLmJvdW5kSGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8sIG9wdF90cmFuc2Zvcm0sIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHx8IGxvYWRpbmc7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvYWRpbmcgPSByZW5kZXJGZWF0dXJlKGJ1aWxkZXJHcm91cCwgZmVhdHVyZSwgc3R5bGVzLCBzcXVhcmVkVG9sZXJhbmNlLCB0aGlzLmJvdW5kSGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8sIG9wdF90cmFuc2Zvcm0sIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApO1xuICAgIH1cblxuICAgIHJldHVybiBsb2FkaW5nO1xuICB9O1xuXG4gIHJldHVybiBDYW52YXNWZWN0b3JMYXllclJlbmRlcmVyO1xufShDYW52YXNMYXllclJlbmRlcmVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzVmVjdG9yTGF5ZXJSZW5kZXJlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL1ZlY3RvclxuICovXG5cblxuaW1wb3J0IEJhc2VWZWN0b3JMYXllciBmcm9tICcuL0Jhc2VWZWN0b3IuanMnO1xuaW1wb3J0IENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIgZnJvbSAnLi4vcmVuZGVyZXIvY2FudmFzL1ZlY3RvckxheWVyLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogVmVjdG9yIGRhdGEgdGhhdCBpcyByZW5kZXJlZCBjbGllbnQtc2lkZS5cbiAqIE5vdGUgdGhhdCBhbnkgcHJvcGVydHkgc2V0IGluIHRoZSBvcHRpb25zIGlzIHNldCBhcyBhIHtAbGluayBtb2R1bGU6b2wvT2JqZWN0fkJhc2VPYmplY3R9XG4gKiBwcm9wZXJ0eSBvbiB0aGUgbGF5ZXIgb2JqZWN0OyBmb3IgZXhhbXBsZSwgc2V0dGluZyBgdGl0bGU6ICdNeSBUaXRsZSdgIGluIHRoZVxuICogb3B0aW9ucyBtZWFucyB0aGF0IGB0aXRsZWAgaXMgb2JzZXJ2YWJsZSwgYW5kIGhhcyBnZXQvc2V0IGFjY2Vzc29ycy5cbiAqXG4gKiBAZXh0ZW5kcyB7QmFzZVZlY3RvckxheWVyPGltcG9ydChcIi4uL3NvdXJjZS9WZWN0b3IuanNcIikuZGVmYXVsdD59XG4gKiBAYXBpXG4gKi9cblxudmFyIFZlY3RvckxheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFZlY3RvckxheWVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0Jhc2VWZWN0b3IuanNcIikuT3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVmVjdG9yTGF5ZXIob3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgb3B0X29wdGlvbnMpIHx8IHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHJlbmRlcmVyIGZvciB0aGlzIGxheWVyLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9yZW5kZXJlci9MYXllci5qc1wiKS5kZWZhdWx0fSBBIGxheWVyIHJlbmRlcmVyLlxuICAgKi9cblxuXG4gIFZlY3RvckxheWVyLnByb3RvdHlwZS5jcmVhdGVSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbmV3IENhbnZhc1ZlY3RvckxheWVyUmVuZGVyZXIodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIFZlY3RvckxheWVyO1xufShCYXNlVmVjdG9yTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JMYXllcjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc3RydWN0cy9SQnVzaFxuICovXG5pbXBvcnQgUkJ1c2hfIGZyb20gJ3JidXNoJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlLCBlcXVhbHMgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBpc0VtcHR5IH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRW50cnlcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtaW5YXG4gKiBAcHJvcGVydHkge251bWJlcn0gbWluWVxuICogQHByb3BlcnR5IHtudW1iZXJ9IG1heFhcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtYXhZXG4gKiBAcHJvcGVydHkge09iamVjdH0gW3ZhbHVlXVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogV3JhcHBlciBhcm91bmQgdGhlIFJCdXNoIGJ5IFZsYWRpbWlyIEFnYWZvbmtpbi5cbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbW91cm5lci9yYnVzaC5cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICovXG5cbnZhciBSQnVzaCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9tYXhFbnRyaWVzIE1heCBlbnRyaWVzLlxuICAgKi9cbiAgZnVuY3Rpb24gUkJ1c2gob3B0X21heEVudHJpZXMpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMucmJ1c2hfID0gbmV3IFJCdXNoXyhvcHRfbWF4RW50cmllcyk7XG4gICAgLyoqXG4gICAgICogQSBtYXBwaW5nIGJldHdlZW4gdGhlIG9iamVjdHMgYWRkZWQgdG8gdGhpcyByYnVzaCB3cmFwcGVyXG4gICAgICogYW5kIHRoZSBvYmplY3RzIHRoYXQgYXJlIGFjdHVhbGx5IGFkZGVkIHRvIHRoZSBpbnRlcm5hbCByYnVzaC5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBFbnRyeT59XG4gICAgICovXG5cbiAgICB0aGlzLml0ZW1zXyA9IHt9O1xuICB9XG4gIC8qKlxuICAgKiBJbnNlcnQgYSB2YWx1ZSBpbnRvIHRoZSBSQnVzaC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge1R9IHZhbHVlIFZhbHVlLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5pbnNlcnQgPSBmdW5jdGlvbiAoZXh0ZW50LCB2YWx1ZSkge1xuICAgIC8qKiBAdHlwZSB7RW50cnl9ICovXG4gICAgdmFyIGl0ZW0gPSB7XG4gICAgICBtaW5YOiBleHRlbnRbMF0sXG4gICAgICBtaW5ZOiBleHRlbnRbMV0sXG4gICAgICBtYXhYOiBleHRlbnRbMl0sXG4gICAgICBtYXhZOiBleHRlbnRbM10sXG4gICAgICB2YWx1ZTogdmFsdWVcbiAgICB9O1xuICAgIHRoaXMucmJ1c2hfLmluc2VydChpdGVtKTtcbiAgICB0aGlzLml0ZW1zX1tnZXRVaWQodmFsdWUpXSA9IGl0ZW07XG4gIH07XG4gIC8qKlxuICAgKiBCdWxrLWluc2VydCB2YWx1ZXMgaW50byB0aGUgUkJ1c2guXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD59IGV4dGVudHMgRXh0ZW50cy5cbiAgICogQHBhcmFtIHtBcnJheTxUPn0gdmFsdWVzIFZhbHVlcy5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uIChleHRlbnRzLCB2YWx1ZXMpIHtcbiAgICB2YXIgaXRlbXMgPSBuZXcgQXJyYXkodmFsdWVzLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBleHRlbnQgPSBleHRlbnRzW2ldO1xuICAgICAgdmFyIHZhbHVlID0gdmFsdWVzW2ldO1xuICAgICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cblxuICAgICAgdmFyIGl0ZW0gPSB7XG4gICAgICAgIG1pblg6IGV4dGVudFswXSxcbiAgICAgICAgbWluWTogZXh0ZW50WzFdLFxuICAgICAgICBtYXhYOiBleHRlbnRbMl0sXG4gICAgICAgIG1heFk6IGV4dGVudFszXSxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICB9O1xuICAgICAgaXRlbXNbaV0gPSBpdGVtO1xuICAgICAgdGhpcy5pdGVtc19bZ2V0VWlkKHZhbHVlKV0gPSBpdGVtO1xuICAgIH1cblxuICAgIHRoaXMucmJ1c2hfLmxvYWQoaXRlbXMpO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGEgdmFsdWUgZnJvbSB0aGUgUkJ1c2guXG4gICAqIEBwYXJhbSB7VH0gdmFsdWUgVmFsdWUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFJlbW92ZWQuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciB1aWQgPSBnZXRVaWQodmFsdWUpOyAvLyBnZXQgdGhlIG9iamVjdCBpbiB3aGljaCB0aGUgdmFsdWUgd2FzIHdyYXBwZWQgd2hlbiBhZGRpbmcgdG8gdGhlXG4gICAgLy8gaW50ZXJuYWwgcmJ1c2guIHRoZW4gdXNlIHRoYXQgb2JqZWN0IHRvIGRvIHRoZSByZW1vdmFsLlxuXG4gICAgdmFyIGl0ZW0gPSB0aGlzLml0ZW1zX1t1aWRdO1xuICAgIGRlbGV0ZSB0aGlzLml0ZW1zX1t1aWRdO1xuICAgIHJldHVybiB0aGlzLnJidXNoXy5yZW1vdmUoaXRlbSkgIT09IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGV4dGVudCBvZiBhIHZhbHVlIGluIHRoZSBSQnVzaC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge1R9IHZhbHVlIFZhbHVlLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZXh0ZW50LCB2YWx1ZSkge1xuICAgIHZhciBpdGVtID0gdGhpcy5pdGVtc19bZ2V0VWlkKHZhbHVlKV07XG4gICAgdmFyIGJib3ggPSBbaXRlbS5taW5YLCBpdGVtLm1pblksIGl0ZW0ubWF4WCwgaXRlbS5tYXhZXTtcblxuICAgIGlmICghZXF1YWxzKGJib3gsIGV4dGVudCkpIHtcbiAgICAgIHRoaXMucmVtb3ZlKHZhbHVlKTtcbiAgICAgIHRoaXMuaW5zZXJ0KGV4dGVudCwgdmFsdWUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiBhbGwgdmFsdWVzIGluIHRoZSBSQnVzaC5cbiAgICogQHJldHVybiB7QXJyYXk8VD59IEFsbC5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuZ2V0QWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBpdGVtcyA9IHRoaXMucmJ1c2hfLmFsbCgpO1xuICAgIHJldHVybiBpdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIGFsbCB2YWx1ZXMgaW4gdGhlIGdpdmVuIGV4dGVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxUPn0gQWxsIGluIGV4dGVudC5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuZ2V0SW5FeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICB2YXIgYmJveCA9IHtcbiAgICAgIG1pblg6IGV4dGVudFswXSxcbiAgICAgIG1pblk6IGV4dGVudFsxXSxcbiAgICAgIG1heFg6IGV4dGVudFsyXSxcbiAgICAgIG1heFk6IGV4dGVudFszXVxuICAgIH07XG4gICAgdmFyIGl0ZW1zID0gdGhpcy5yYnVzaF8uc2VhcmNoKGJib3gpO1xuICAgIHJldHVybiBpdGVtcy5tYXAoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogQ2FsbHMgYSBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIGVhY2ggdmFsdWUgaW4gdGhlIHRyZWUuXG4gICAqIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgdHJ1dGh5IHZhbHVlLCB0aGlzIHZhbHVlIGlzIHJldHVybmVkIHdpdGhvdXRcbiAgICogY2hlY2tpbmcgdGhlIHJlc3Qgb2YgdGhlIHRyZWUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCk6ICp9IGNhbGxiYWNrIENhbGxiYWNrLlxuICAgKiBAcmV0dXJuIHsqfSBDYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5mb3JFYWNoXyh0aGlzLmdldEFsbCgpLCBjYWxsYmFjayk7XG4gIH07XG4gIC8qKlxuICAgKiBDYWxscyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggZWFjaCB2YWx1ZSBpbiB0aGUgcHJvdmlkZWQgZXh0ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCk6ICp9IGNhbGxiYWNrIENhbGxiYWNrLlxuICAgKiBAcmV0dXJuIHsqfSBDYWxsYmFjayByZXR1cm4gdmFsdWUuXG4gICAqL1xuXG5cbiAgUkJ1c2gucHJvdG90eXBlLmZvckVhY2hJbkV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9yRWFjaF8odGhpcy5nZXRJbkV4dGVudChleHRlbnQpLCBjYWxsYmFjayk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PFQ+fSB2YWx1ZXMgVmFsdWVzLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFQpOiAqfSBjYWxsYmFjayBDYWxsYmFjay5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7Kn0gQ2FsbGJhY2sgcmV0dXJuIHZhbHVlLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5mb3JFYWNoXyA9IGZ1bmN0aW9uICh2YWx1ZXMsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgcmVzdWx0ID0gY2FsbGJhY2sodmFsdWVzW2ldKTtcblxuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJcyBlbXB0eS5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaXNFbXB0eSh0aGlzLml0ZW1zXyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIHZhbHVlcyBmcm9tIHRoZSBSQnVzaC5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yYnVzaF8uY2xlYXIoKTtcbiAgICB0aGlzLml0ZW1zXyA9IHt9O1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICovXG5cblxuICBSQnVzaC5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKG9wdF9leHRlbnQpIHtcbiAgICB2YXIgZGF0YSA9IHRoaXMucmJ1c2hfLnRvSlNPTigpO1xuICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZShkYXRhLm1pblgsIGRhdGEubWluWSwgZGF0YS5tYXhYLCBkYXRhLm1heFksIG9wdF9leHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtSQnVzaH0gcmJ1c2ggUi1UcmVlLlxuICAgKi9cblxuXG4gIFJCdXNoLnByb3RvdHlwZS5jb25jYXQgPSBmdW5jdGlvbiAocmJ1c2gpIHtcbiAgICB0aGlzLnJidXNoXy5sb2FkKHJidXNoLnJidXNoXy5hbGwoKSk7XG5cbiAgICBmb3IgKHZhciBpIGluIHJidXNoLml0ZW1zXykge1xuICAgICAgdGhpcy5pdGVtc19baV0gPSByYnVzaC5pdGVtc19baV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBSQnVzaDtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgUkJ1c2g7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvU291cmNlXG4gKi9cblxuXG5pbXBvcnQgQmFzZU9iamVjdCBmcm9tICcuLi9PYmplY3QuanMnO1xuaW1wb3J0IFNvdXJjZVN0YXRlIGZyb20gJy4vU3RhdGUuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IGdldCBhcyBnZXRQcm9qZWN0aW9uIH0gZnJvbSAnLi4vcHJvai5qcyc7XG4vKipcbiAqIEEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgc3RyaW5nIG9yIGFuIGFycmF5IG9mIHN0cmluZ3MgcmVwcmVzZW50aW5nIHNvdXJjZVxuICogYXR0cmlidXRpb25zLlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZSk6IChzdHJpbmd8QXJyYXk8c3RyaW5nPil9IEF0dHJpYnV0aW9uXG4gKi9cblxuLyoqXG4gKiBBIHR5cGUgdGhhdCBjYW4gYmUgdXNlZCB0byBwcm92aWRlIGF0dHJpYnV0aW9uIGluZm9ybWF0aW9uIGZvciBkYXRhIHNvdXJjZXMuXG4gKlxuICogSXQgcmVwcmVzZW50cyBlaXRoZXJcbiAqICogYSBzaW1wbGUgc3RyaW5nIChlLmcuIGAnwqkgQWNtZSBJbmMuJ2ApXG4gKiAqIGFuIGFycmF5IG9mIHNpbXBsZSBzdHJpbmdzIChlLmcuIGBbJ8KpIEFjbWUgSW5jLicsICfCqSBCYWNtZSBJbmMuJ11gKVxuICogKiBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHN0cmluZyBvciBhcnJheSBvZiBzdHJpbmdzICh7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9Tb3VyY2V+QXR0cmlidXRpb259KVxuICpcbiAqIEB0eXBlZGVmIHtzdHJpbmd8QXJyYXk8c3RyaW5nPnxBdHRyaWJ1dGlvbn0gQXR0cmlidXRpb25MaWtlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge0F0dHJpYnV0aW9uTGlrZX0gW2F0dHJpYnV0aW9uc11cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2F0dHJpYnV0aW9uc0NvbGxhcHNpYmxlPXRydWVdIEF0dHJpYnV0aW9ucyBhcmUgY29sbGFwc2libGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uXSBQcm9qZWN0aW9uLiBEZWZhdWx0IGlzIHRoZSB2aWV3IHByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH0gW3N0YXRlPSdyZWFkeSddXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt3cmFwWD1mYWxzZV1cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3M7IG5vcm1hbGx5IG9ubHkgdXNlZCBmb3IgY3JlYXRpbmcgc3ViY2xhc3NlcyBhbmQgbm90XG4gKiBpbnN0YW50aWF0ZWQgaW4gYXBwcy5cbiAqIEJhc2UgY2xhc3MgZm9yIHtAbGluayBtb2R1bGU6b2wvbGF5ZXIvTGF5ZXJ+TGF5ZXJ9IHNvdXJjZXMuXG4gKlxuICogQSBnZW5lcmljIGBjaGFuZ2VgIGV2ZW50IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBzdGF0ZSBvZiB0aGUgc291cmNlIGNoYW5nZXMuXG4gKiBAYWJzdHJhY3RcbiAqIEBhcGlcbiAqL1xuXG52YXIgU291cmNlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFNvdXJjZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBTb3VyY2Ugb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBTb3VyY2Uob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cblxuICAgIF90aGlzLnByb2plY3Rpb25fID0gZ2V0UHJvamVjdGlvbihvcHRpb25zLnByb2plY3Rpb24pO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9BdHRyaWJ1dGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmF0dHJpYnV0aW9uc18gPSBhZGFwdEF0dHJpYnV0aW9ucyhvcHRpb25zLmF0dHJpYnV0aW9ucyk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlXyA9IG9wdGlvbnMuYXR0cmlidXRpb25zQ29sbGFwc2libGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYXR0cmlidXRpb25zQ29sbGFwc2libGUgOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIFRoaXMgc291cmNlIGlzIGN1cnJlbnRseSBsb2FkaW5nIGRhdGEuIFNvdXJjZXMgdGhhdCBkZWZlciBsb2FkaW5nIHRvIHRoZVxuICAgICAqIG1hcCdzIHRpbGUgcXVldWUgbmV2ZXIgc2V0IHRoaXMgdG8gYHRydWVgLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMubG9hZGluZyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vU3RhdGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnN0YXRlXyA9IG9wdGlvbnMuc3RhdGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3RhdGUgOiBTb3VyY2VTdGF0ZS5SRUFEWTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMud3JhcFhfID0gb3B0aW9ucy53cmFwWCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy53cmFwWCA6IGZhbHNlO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBhdHRyaWJ1dGlvbiBmdW5jdGlvbiBmb3IgdGhlIHNvdXJjZS5cbiAgICogQHJldHVybiB7P0F0dHJpYnV0aW9ufSBBdHRyaWJ1dGlvbiBmdW5jdGlvbi5cbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLmdldEF0dHJpYnV0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGlvbnNfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLmdldEF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcHJvamVjdGlvbiBvZiB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gUHJvamVjdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuZ2V0UHJvamVjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9qZWN0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fHVuZGVmaW5lZH0gUmVzb2x1dGlvbnMuXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5nZXRSZXNvbHV0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3RhdGUgb2YgdGhlIHNvdXJjZSwgc2VlIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1N0YXRlflN0YXRlfSBmb3IgcG9zc2libGUgc3RhdGVzLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFN0YXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgU291cmNlLnByb3RvdHlwZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufHVuZGVmaW5lZH0gV3JhcCBYLlxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuZ2V0V3JhcFggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMud3JhcFhfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH0gQ29udGV4dCBvcHRpb25zLlxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuZ2V0Q29udGV4dE9wdGlvbnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfTtcbiAgLyoqXG4gICAqIFJlZnJlc2hlcyB0aGUgc291cmNlLiBUaGUgc291cmNlIHdpbGwgYmUgY2xlYXJlZCwgYW5kIGRhdGEgZnJvbSB0aGUgc2VydmVyIHdpbGwgYmUgcmVsb2FkZWQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGF0dHJpYnV0aW9ucyBvZiB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge0F0dHJpYnV0aW9uTGlrZXx1bmRlZmluZWR9IGF0dHJpYnV0aW9ucyBBdHRyaWJ1dGlvbnMuXG4gICAqICAgICBDYW4gYmUgcGFzc2VkIGFzIGBzdHJpbmdgLCBgQXJyYXk8c3RyaW5nPmAsIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1NvdXJjZX5BdHRyaWJ1dGlvbn0sXG4gICAqICAgICBvciBgdW5kZWZpbmVkYC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFNvdXJjZS5wcm90b3R5cGUuc2V0QXR0cmlidXRpb25zID0gZnVuY3Rpb24gKGF0dHJpYnV0aW9ucykge1xuICAgIHRoaXMuYXR0cmlidXRpb25zXyA9IGFkYXB0QXR0cmlidXRpb25zKGF0dHJpYnV0aW9ucyk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHN0YXRlIG9mIHRoZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9TdGF0ZS5qc1wiKS5kZWZhdWx0fSBzdGF0ZSBTdGF0ZS5cbiAgICovXG5cblxuICBTb3VyY2UucHJvdG90eXBlLnNldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgdGhpcy5zdGF0ZV8gPSBzdGF0ZTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gU291cmNlO1xufShCYXNlT2JqZWN0KTtcbi8qKlxuICogVHVybnMgdGhlIGF0dHJpYnV0aW9ucyBvcHRpb24gaW50byBhbiBhdHRyaWJ1dGlvbnMgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge0F0dHJpYnV0aW9uTGlrZXx1bmRlZmluZWR9IGF0dHJpYnV0aW9uTGlrZSBUaGUgYXR0cmlidXRpb24gb3B0aW9uLlxuICogQHJldHVybiB7P0F0dHJpYnV0aW9ufSBBbiBhdHRyaWJ1dGlvbiBmdW5jdGlvbiAob3IgbnVsbCkuXG4gKi9cblxuXG5mdW5jdGlvbiBhZGFwdEF0dHJpYnV0aW9ucyhhdHRyaWJ1dGlvbkxpa2UpIHtcbiAgaWYgKCFhdHRyaWJ1dGlvbkxpa2UpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KGF0dHJpYnV0aW9uTGlrZSkpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGZyYW1lU3RhdGUpIHtcbiAgICAgIHJldHVybiBhdHRyaWJ1dGlvbkxpa2U7XG4gICAgfTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYXR0cmlidXRpb25MaWtlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGF0dHJpYnV0aW9uTGlrZTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHJldHVybiBbYXR0cmlidXRpb25MaWtlXTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgU291cmNlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvVmVjdG9yRXZlbnRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIGZlYXR1cmUgaXMgYWRkZWQgdG8gdGhlIHNvdXJjZS5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I2FkZGZlYXR1cmVcbiAgICogQGFwaVxuICAgKi9cbiAgQURERkVBVFVSRTogJ2FkZGZlYXR1cmUnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiBhIGZlYXR1cmUgaXMgdXBkYXRlZC5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I2NoYW5nZWZlYXR1cmVcbiAgICogQGFwaVxuICAgKi9cbiAgQ0hBTkdFRkVBVFVSRTogJ2NoYW5nZWZlYXR1cmUnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgd2hlbiB0aGUgY2xlYXIgbWV0aG9kIGlzIGNhbGxlZCBvbiB0aGUgc291cmNlLlxuICAgKiBAZXZlbnQgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3IuVmVjdG9yU291cmNlRXZlbnQjY2xlYXJcbiAgICogQGFwaVxuICAgKi9cbiAgQ0xFQVI6ICdjbGVhcicsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgZmVhdHVyZSBpcyByZW1vdmVkIGZyb20gdGhlIHNvdXJjZS5cbiAgICogU2VlIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3RvciNjbGVhciBzb3VyY2UuY2xlYXIoKX0gZm9yIGV4Y2VwdGlvbnMuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvci5WZWN0b3JTb3VyY2VFdmVudCNyZW1vdmVmZWF0dXJlXG4gICAqIEBhcGlcbiAgICovXG4gIFJFTU9WRUZFQVRVUkU6ICdyZW1vdmVmZWF0dXJlJyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gZmVhdHVyZXMgc3RhcnRzIGxvYWRpbmcuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvci5WZWN0b3JTb3VyY2VFdmVudCNmZWF0dXJlc2xvYWRzdGFydFxuICAgKiBAYXBpXG4gICAqL1xuICBGRUFUVVJFU0xPQURTVEFSVDogJ2ZlYXR1cmVzbG9hZHN0YXJ0JyxcblxuICAvKipcbiAgICogVHJpZ2dlcmVkIHdoZW4gZmVhdHVyZXMgZmluaXNoZXMgbG9hZGluZy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yLlZlY3RvclNvdXJjZUV2ZW50I2ZlYXR1cmVzbG9hZGVuZFxuICAgKiBAYXBpXG4gICAqL1xuICBGRUFUVVJFU0xPQURFTkQ6ICdmZWF0dXJlc2xvYWRlbmQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgaWYgZmVhdHVyZSBsb2FkaW5nIHJlc3VsdHMgaW4gYW4gZXJyb3IuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvci5WZWN0b3JTb3VyY2VFdmVudCNmZWF0dXJlc2xvYWRlcnJvclxuICAgKiBAYXBpXG4gICAqL1xuICBGRUFUVVJFU0xPQURFUlJPUjogJ2ZlYXR1cmVzbG9hZGVycm9yJ1xufTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvbG9hZGluZ3N0cmF0ZWd5XG4gKi9cblxuLyoqXG4gKiBTdHJhdGVneSBmdW5jdGlvbiBmb3IgbG9hZGluZyBhbGwgZmVhdHVyZXMgd2l0aCBhIHNpbmdsZSByZXF1ZXN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50Pn0gRXh0ZW50cy5cbiAqIEBhcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFsbChleHRlbnQsIHJlc29sdXRpb24pIHtcbiAgcmV0dXJuIFtbLUluZmluaXR5LCAtSW5maW5pdHksIEluZmluaXR5LCBJbmZpbml0eV1dO1xufVxuLyoqXG4gKiBTdHJhdGVneSBmdW5jdGlvbiBmb3IgbG9hZGluZyBmZWF0dXJlcyBiYXNlZCBvbiB0aGUgdmlldydzIGV4dGVudCBhbmRcbiAqIHJlc29sdXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQ+fSBFeHRlbnRzLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBiYm94KGV4dGVudCwgcmVzb2x1dGlvbikge1xuICByZXR1cm4gW2V4dGVudF07XG59XG4vKipcbiAqIENyZWF0ZXMgYSBzdHJhdGVneSBmdW5jdGlvbiBmb3IgbG9hZGluZyBmZWF0dXJlcyBiYXNlZCBvbiBhIHRpbGUgZ3JpZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0aWxlR3JpZCBUaWxlIGdyaWQuXG4gKiBAcmV0dXJuIHtmdW5jdGlvbihpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQsIG51bWJlcik6IEFycmF5PGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD59IExvYWRpbmcgc3RyYXRlZ3kuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRpbGUodGlsZUdyaWQpIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD59IEV4dGVudHMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGV4dGVudCwgcmVzb2x1dGlvbikge1xuICAgICAgdmFyIHogPSB0aWxlR3JpZC5nZXRaRm9yUmVzb2x1dGlvbihyZXNvbHV0aW9uKTtcbiAgICAgIHZhciB0aWxlUmFuZ2UgPSB0aWxlR3JpZC5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKGV4dGVudCwgeik7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudD59ICovXG5cbiAgICAgIHZhciBleHRlbnRzID0gW107XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gKi9cblxuICAgICAgdmFyIHRpbGVDb29yZCA9IFt6LCAwLCAwXTtcblxuICAgICAgZm9yICh0aWxlQ29vcmRbMV0gPSB0aWxlUmFuZ2UubWluWDsgdGlsZUNvb3JkWzFdIDw9IHRpbGVSYW5nZS5tYXhYOyArK3RpbGVDb29yZFsxXSkge1xuICAgICAgICBmb3IgKHRpbGVDb29yZFsyXSA9IHRpbGVSYW5nZS5taW5ZOyB0aWxlQ29vcmRbMl0gPD0gdGlsZVJhbmdlLm1heFk7ICsrdGlsZUNvb3JkWzJdKSB7XG4gICAgICAgICAgZXh0ZW50cy5wdXNoKHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlQ29vcmQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXh0ZW50cztcbiAgICB9XG4gICk7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Zvcm1hdC9Gb3JtYXRUeXBlXG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIEFSUkFZX0JVRkZFUjogJ2FycmF5YnVmZmVyJyxcbiAgSlNPTjogJ2pzb24nLFxuICBURVhUOiAndGV4dCcsXG4gIFhNTDogJ3htbCdcbn07IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2ZlYXR1cmVsb2FkZXJcbiAqL1xuaW1wb3J0IEZvcm1hdFR5cGUgZnJvbSAnLi9mb3JtYXQvRm9ybWF0VHlwZS5qcyc7XG5pbXBvcnQgeyBWT0lEIH0gZnJvbSAnLi9mdW5jdGlvbnMuanMnO1xuLyoqXG4gKlxuICogQHR5cGUge2Jvb2xlYW59XG4gKiBAcHJpdmF0ZVxuICovXG5cbnZhciB3aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcbi8qKlxuICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yfSBzb3VyY2VzIHVzZSBhIGZ1bmN0aW9uIG9mIHRoaXMgdHlwZSB0b1xuICogbG9hZCBmZWF0dXJlcy5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvZXh0ZW50fkV4dGVudH0gcmVwcmVzZW50aW5nIHRoZSBhcmVhIHRvIGJlIGxvYWRlZCxcbiAqIGEgYHtudW1iZXJ9YCByZXByZXNlbnRpbmcgdGhlIHJlc29sdXRpb24gKG1hcCB1bml0cyBwZXIgcGl4ZWwpLCBhblxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259IGZvciB0aGUgcHJvamVjdGlvbiBhbmQgc3VjY2VzcyBhbmQgZmFpbHVyZSBjYWxsYmFja3MgYXNcbiAqIGFyZ3VtZW50cy4gYHRoaXNgIHdpdGhpbiB0aGUgZnVuY3Rpb24gaXMgYm91bmQgdG8gdGhlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J9IGl0J3MgY2FsbGVkIGZyb20uXG4gKlxuICogVGhlIGZ1bmN0aW9uIGlzIHJlc3BvbnNpYmxlIGZvciBsb2FkaW5nIHRoZSBmZWF0dXJlcyBhbmQgYWRkaW5nIHRoZW0gdG8gdGhlXG4gKiBzb3VyY2UuXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24odGhpczooaW1wb3J0KFwiLi9zb3VyY2UvVmVjdG9yXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHQpLFxuICogICAgICAgICAgIGltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudCxcbiAqICAgICAgICAgICBudW1iZXIsXG4gKiAgICAgICAgICAgaW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdCxcbiAqICAgICAgICAgICBmdW5jdGlvbihBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdD4pOiB2b2lkPSxcbiAqICAgICAgICAgICBmdW5jdGlvbigpOiB2b2lkPSk6IHZvaWR9IEZlYXR1cmVMb2FkZXJcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn0gc291cmNlcyB1c2UgYSBmdW5jdGlvbiBvZiB0aGlzIHR5cGUgdG9cbiAqIGdldCB0aGUgdXJsIHRvIGxvYWQgZmVhdHVyZXMgZnJvbS5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHRha2VzIGFuIHtAbGluayBtb2R1bGU6b2wvZXh0ZW50fkV4dGVudH0gcmVwcmVzZW50aW5nIHRoZSBhcmVhXG4gKiB0byBiZSBsb2FkZWQsIGEgYHtudW1iZXJ9YCByZXByZXNlbnRpbmcgdGhlIHJlc29sdXRpb24gKG1hcCB1bml0cyBwZXIgcGl4ZWwpXG4gKiBhbmQgYW4ge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259IGZvciB0aGUgcHJvamVjdGlvbiAgYXNcbiAqIGFyZ3VtZW50cyBhbmQgcmV0dXJucyBhIGB7c3RyaW5nfWAgcmVwcmVzZW50aW5nIHRoZSBVUkwuXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50LCBudW1iZXIsIGltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQpOiBzdHJpbmd9IEZlYXR1cmVVcmxGdW5jdGlvblxuICogQGFwaVxuICovXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd8RmVhdHVyZVVybEZ1bmN0aW9ufSB1cmwgRmVhdHVyZSBVUkwgc2VydmljZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9mb3JtYXQvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmb3JtYXQgRmVhdHVyZSBmb3JtYXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oQXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+LCBpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0KTogdm9pZH0gc3VjY2VzcyBTdWNjZXNzXG4gKiAgICAgIEZ1bmN0aW9uIGNhbGxlZCB3aXRoIHRoZSBsb2FkZWQgZmVhdHVyZXMgYW5kIG9wdGlvbmFsbHkgd2l0aCB0aGUgZGF0YSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbigpOiB2b2lkfSBmYWlsdXJlIEZhaWx1cmVcbiAqICAgICAgRnVuY3Rpb24gY2FsbGVkIHdoZW4gbG9hZGluZyBmYWlsZWQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRGZWF0dXJlc1hocih1cmwsIGZvcm1hdCwgZXh0ZW50LCByZXNvbHV0aW9uLCBwcm9qZWN0aW9uLCBzdWNjZXNzLCBmYWlsdXJlKSB7XG4gIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgeGhyLm9wZW4oJ0dFVCcsIHR5cGVvZiB1cmwgPT09ICdmdW5jdGlvbicgPyB1cmwoZXh0ZW50LCByZXNvbHV0aW9uLCBwcm9qZWN0aW9uKSA6IHVybCwgdHJ1ZSk7XG5cbiAgaWYgKGZvcm1hdC5nZXRUeXBlKCkgPT0gRm9ybWF0VHlwZS5BUlJBWV9CVUZGRVIpIHtcbiAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgfVxuXG4gIHhoci53aXRoQ3JlZGVudGlhbHMgPSB3aXRoQ3JlZGVudGlhbHM7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0V2ZW50fSBldmVudCBFdmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIC8vIHN0YXR1cyB3aWxsIGJlIDAgZm9yIGZpbGU6Ly8gdXJsc1xuICAgIGlmICgheGhyLnN0YXR1cyB8fCB4aHIuc3RhdHVzID49IDIwMCAmJiB4aHIuc3RhdHVzIDwgMzAwKSB7XG4gICAgICB2YXIgdHlwZSA9IGZvcm1hdC5nZXRUeXBlKCk7XG4gICAgICAvKiogQHR5cGUge0RvY3VtZW50fE5vZGV8T2JqZWN0fHN0cmluZ3x1bmRlZmluZWR9ICovXG5cbiAgICAgIHZhciBzb3VyY2UgPSB2b2lkIDA7XG5cbiAgICAgIGlmICh0eXBlID09IEZvcm1hdFR5cGUuSlNPTiB8fCB0eXBlID09IEZvcm1hdFR5cGUuVEVYVCkge1xuICAgICAgICBzb3VyY2UgPSB4aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09IEZvcm1hdFR5cGUuWE1MKSB7XG4gICAgICAgIHNvdXJjZSA9IHhoci5yZXNwb25zZVhNTDtcblxuICAgICAgICBpZiAoIXNvdXJjZSkge1xuICAgICAgICAgIHNvdXJjZSA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcoeGhyLnJlc3BvbnNlVGV4dCwgJ2FwcGxpY2F0aW9uL3htbCcpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gRm9ybWF0VHlwZS5BUlJBWV9CVUZGRVIpIHtcbiAgICAgICAgc291cmNlID1cbiAgICAgICAgLyoqIEB0eXBlIHtBcnJheUJ1ZmZlcn0gKi9cbiAgICAgICAgeGhyLnJlc3BvbnNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIHN1Y2Nlc3MoXG4gICAgICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICAgICAgICBmb3JtYXQucmVhZEZlYXR1cmVzKHNvdXJjZSwge1xuICAgICAgICAgIGV4dGVudDogZXh0ZW50LFxuICAgICAgICAgIGZlYXR1cmVQcm9qZWN0aW9uOiBwcm9qZWN0aW9uXG4gICAgICAgIH0pLCBmb3JtYXQucmVhZFByb2plY3Rpb24oc291cmNlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmYWlsdXJlKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZhaWx1cmUoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIHhoci5vbmVycm9yID0gZmFpbHVyZTtcbiAgeGhyLnNlbmQoKTtcbn1cbi8qKlxuICogQ3JlYXRlIGFuIFhIUiBmZWF0dXJlIGxvYWRlciBmb3IgYSBgdXJsYCBhbmQgYGZvcm1hdGAuIFRoZSBmZWF0dXJlIGxvYWRlclxuICogbG9hZHMgZmVhdHVyZXMgKHdpdGggWEhSKSwgcGFyc2VzIHRoZSBmZWF0dXJlcywgYW5kIGFkZHMgdGhlbSB0byB0aGVcbiAqIHZlY3RvciBzb3VyY2UuXG4gKiBAcGFyYW0ge3N0cmluZ3xGZWF0dXJlVXJsRnVuY3Rpb259IHVybCBGZWF0dXJlIFVSTCBzZXJ2aWNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IGZvcm1hdCBGZWF0dXJlIGZvcm1hdC5cbiAqIEByZXR1cm4ge0ZlYXR1cmVMb2FkZXJ9IFRoZSBmZWF0dXJlIGxvYWRlci5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24geGhyKHVybCwgZm9ybWF0KSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oKTogdm9pZD19IHN1Y2Nlc3MgU3VjY2Vzc1xuICAgKiAgICAgIEZ1bmN0aW9uIGNhbGxlZCB3aGVuIGxvYWRpbmcgc3VjY2VlZGVkLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCk6IHZvaWQ9fSBmYWlsdXJlIEZhaWx1cmVcbiAgICogICAgICBGdW5jdGlvbiBjYWxsZWQgd2hlbiBsb2FkaW5nIGZhaWxlZC5cbiAgICogQHRoaXMge2ltcG9ydChcIi4vc291cmNlL1ZlY3RvclwiKS5kZWZhdWx0fVxuICAgKi9cbiAgcmV0dXJuIGZ1bmN0aW9uIChleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sIHN1Y2Nlc3MsIGZhaWx1cmUpIHtcbiAgICB2YXIgc291cmNlID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vc291cmNlL1ZlY3RvclwiKS5kZWZhdWx0fSAqL1xuICAgIHRoaXM7XG4gICAgbG9hZEZlYXR1cmVzWGhyKHVybCwgZm9ybWF0LCBleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59IGZlYXR1cmVzIFRoZSBsb2FkZWQgZmVhdHVyZXMuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkYXRhUHJvamVjdGlvbiBEYXRhXG4gICAgICogcHJvamVjdGlvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZmVhdHVyZXMsIGRhdGFQcm9qZWN0aW9uKSB7XG4gICAgICBpZiAoc3VjY2VzcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHN1Y2Nlc3MoZmVhdHVyZXMpO1xuICAgICAgfVxuXG4gICAgICBzb3VyY2UuYWRkRmVhdHVyZXMoZmVhdHVyZXMpO1xuICAgIH0sXG4gICAgLyogRklYTUUgaGFuZGxlIGVycm9yICovXG4gICAgZmFpbHVyZSA/IGZhaWx1cmUgOiBWT0lEKTtcbiAgfTtcbn1cbi8qKlxuICogU2V0dGVyIGZvciB0aGUgd2l0aENyZWRlbnRpYWxzIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBYSFIuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSB4aHJXaXRoQ3JlZGVudGlhbHMgVGhlIHZhbHVlIG9mIHdpdGhDcmVkZW50aWFscyB0byBzZXQuXG4gKiBDb21wYXJlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9YTUxIdHRwUmVxdWVzdC9cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0V2l0aENyZWRlbnRpYWxzKHhocldpdGhDcmVkZW50aWFscykge1xuICB3aXRoQ3JlZGVudGlhbHMgPSB4aHJXaXRoQ3JlZGVudGlhbHM7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9WZWN0b3JcbiAqL1xudmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcblxuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSAnLi4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgQ29sbGVjdGlvbkV2ZW50VHlwZSBmcm9tICcuLi9Db2xsZWN0aW9uRXZlbnRUeXBlLmpzJztcbmltcG9ydCBFdmVudCBmcm9tICcuLi9ldmVudHMvRXZlbnQuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBPYmplY3RFdmVudFR5cGUgZnJvbSAnLi4vT2JqZWN0RXZlbnRUeXBlLmpzJztcbmltcG9ydCBSQnVzaCBmcm9tICcuLi9zdHJ1Y3RzL1JCdXNoLmpzJztcbmltcG9ydCBTb3VyY2UgZnJvbSAnLi9Tb3VyY2UuanMnO1xuaW1wb3J0IFNvdXJjZVN0YXRlIGZyb20gJy4vU3RhdGUuanMnO1xuaW1wb3J0IFZlY3RvckV2ZW50VHlwZSBmcm9tICcuL1ZlY3RvckV2ZW50VHlwZS5qcyc7XG5pbXBvcnQgeyBUUlVFLCBWT0lEIH0gZnJvbSAnLi4vZnVuY3Rpb25zLmpzJztcbmltcG9ydCB7IGFsbCBhcyBhbGxTdHJhdGVneSB9IGZyb20gJy4uL2xvYWRpbmdzdHJhdGVneS5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGNvbnRhaW5zRXh0ZW50LCBlcXVhbHMgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBnZXRWYWx1ZXMsIGlzRW1wdHkgfSBmcm9tICcuLi9vYmouanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vZXZlbnRzLmpzJztcbmltcG9ydCB7IHhociB9IGZyb20gJy4uL2ZlYXR1cmVsb2FkZXIuanMnO1xuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9leHRlbnR+RXh0ZW50fSBhbmQgYSByZXNvbHV0aW9uIGFzIGFyZ3VtZW50cywgYW5kXG4gKiByZXR1cm5zIGFuIGFycmF5IG9mIHtAbGluayBtb2R1bGU6b2wvZXh0ZW50fkV4dGVudH0gd2l0aCB0aGUgZXh0ZW50cyB0byBsb2FkLiBVc3VhbGx5IHRoaXNcbiAqIGlzIG9uZSBvZiB0aGUgc3RhbmRhcmQge0BsaW5rIG1vZHVsZTpvbC9sb2FkaW5nc3RyYXRlZ3l9IHN0cmF0ZWdpZXMuXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQsIG51bWJlcik6IEFycmF5PGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQ+fSBMb2FkaW5nU3RyYXRlZ3lcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEV2ZW50cyBlbWl0dGVkIGJ5IHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn0gaW5zdGFuY2VzIGFyZSBpbnN0YW5jZXMgb2YgdGhpc1xuICogdHlwZS5cbiAqIEB0ZW1wbGF0ZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeVxuICovXG5cbnZhciBWZWN0b3JTb3VyY2VFdmVudCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhWZWN0b3JTb3VyY2VFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj19IG9wdF9mZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj49fSBvcHRfZmVhdHVyZXMgRmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVmVjdG9yU291cmNlRXZlbnQodHlwZSwgb3B0X2ZlYXR1cmUsIG9wdF9mZWF0dXJlcykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHR5cGUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogVGhlIGFkZGVkIG9yIHJlbW92ZWQgZmVhdHVyZSBmb3IgdGhlIGBBRERGRUFUVVJFYCBhbmQgYFJFTU9WRUZFQVRVUkVgIGV2ZW50cywgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fHVuZGVmaW5lZH1cbiAgICAgKiBAYXBpXG4gICAgICovXG5cblxuICAgIF90aGlzLmZlYXR1cmUgPSBvcHRfZmVhdHVyZTtcbiAgICAvKipcbiAgICAgKiBUaGUgbG9hZGVkIGZlYXR1cmVzIGZvciB0aGUgYEZFQVRVUkVTTE9BREVEYCBldmVudCwgYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLlxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pnx1bmRlZmluZWR9XG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmVhdHVyZXMgPSBvcHRfZmVhdHVyZXM7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFZlY3RvclNvdXJjZUV2ZW50O1xufShFdmVudCk7XG5cbmV4cG9ydCB7IFZlY3RvclNvdXJjZUV2ZW50IH07XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9Tb3VyY2UuanNcIikuQXR0cmlidXRpb25MaWtlfSBbYXR0cmlidXRpb25zXSBBdHRyaWJ1dGlvbnMuXG4gKiBAcHJvcGVydHkge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdD58Q29sbGVjdGlvbjxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSBbZmVhdHVyZXNdXG4gKiBGZWF0dXJlcy4gSWYgcHJvdmlkZWQgYXMge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufSwgdGhlIGZlYXR1cmVzIGluIHRoZSBzb3VyY2VcbiAqIGFuZCB0aGUgY29sbGVjdGlvbiB3aWxsIHN0YXkgaW4gc3luYy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gW2Zvcm1hdF0gVGhlIGZlYXR1cmUgZm9ybWF0IHVzZWQgYnkgdGhlIFhIUlxuICogZmVhdHVyZSBsb2FkZXIgd2hlbiBgdXJsYCBpcyBzZXQuIFJlcXVpcmVkIGlmIGB1cmxgIGlzIHNldCwgb3RoZXJ3aXNlIGlnbm9yZWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZUxvYWRlcn0gW2xvYWRlcl1cbiAqIFRoZSBsb2FkZXIgZnVuY3Rpb24gdXNlZCB0byBsb2FkIGZlYXR1cmVzLCBmcm9tIGEgcmVtb3RlIHNvdXJjZSBmb3IgZXhhbXBsZS5cbiAqIElmIHRoaXMgaXMgbm90IHNldCBhbmQgYHVybGAgaXMgc2V0LCB0aGUgc291cmNlIHdpbGwgY3JlYXRlIGFuZCB1c2UgYW4gWEhSXG4gKiBmZWF0dXJlIGxvYWRlci5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiBpbXBvcnQge1ZlY3Rvcn0gZnJvbSAnb2wvc291cmNlJztcbiAqIGltcG9ydCB7R2VvSlNPTn0gZnJvbSAnb2wvZm9ybWF0JztcbiAqIGltcG9ydCB7YmJveH0gZnJvbSAnb2wvbG9hZGluZ3N0cmF0ZWd5JztcbiAqXG4gKiB2YXIgdmVjdG9yU291cmNlID0gbmV3IFZlY3Rvcih7XG4gKiAgIGZvcm1hdDogbmV3IEdlb0pTT04oKSxcbiAqICAgbG9hZGVyOiBmdW5jdGlvbihleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIHtcbiAqICAgICAgdmFyIHByb2ogPSBwcm9qZWN0aW9uLmdldENvZGUoKTtcbiAqICAgICAgdmFyIHVybCA9ICdodHRwczovL2Fob2NldmFyLmNvbS9nZW9zZXJ2ZXIvd2ZzP3NlcnZpY2U9V0ZTJicgK1xuICogICAgICAgICAgJ3ZlcnNpb249MS4xLjAmcmVxdWVzdD1HZXRGZWF0dXJlJnR5cGVuYW1lPW9zbTp3YXRlcl9hcmVhcyYnICtcbiAqICAgICAgICAgICdvdXRwdXRGb3JtYXQ9YXBwbGljYXRpb24vanNvbiZzcnNuYW1lPScgKyBwcm9qICsgJyYnICtcbiAqICAgICAgICAgICdiYm94PScgKyBleHRlbnQuam9pbignLCcpICsgJywnICsgcHJvajtcbiAqICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICogICAgICB4aHIub3BlbignR0VUJywgdXJsKTtcbiAqICAgICAgdmFyIG9uRXJyb3IgPSBmdW5jdGlvbigpIHtcbiAqICAgICAgICB2ZWN0b3JTb3VyY2UucmVtb3ZlTG9hZGVkRXh0ZW50KGV4dGVudCk7XG4gKiAgICAgIH1cbiAqICAgICAgeGhyLm9uZXJyb3IgPSBvbkVycm9yO1xuICogICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgaWYgKHhoci5zdGF0dXMgPT0gMjAwKSB7XG4gKiAgICAgICAgICB2ZWN0b3JTb3VyY2UuYWRkRmVhdHVyZXMoXG4gKiAgICAgICAgICAgICAgdmVjdG9yU291cmNlLmdldEZvcm1hdCgpLnJlYWRGZWF0dXJlcyh4aHIucmVzcG9uc2VUZXh0KSk7XG4gKiAgICAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgIG9uRXJyb3IoKTtcbiAqICAgICAgICB9XG4gKiAgICAgIH1cbiAqICAgICAgeGhyLnNlbmQoKTtcbiAqICAgIH0sXG4gKiAgICBzdHJhdGVneTogYmJveFxuICogIH0pO1xuICogYGBgXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvdmVybGFwcz10cnVlXSBUaGlzIHNvdXJjZSBtYXkgaGF2ZSBvdmVybGFwcGluZyBnZW9tZXRyaWVzLlxuICogU2V0dGluZyB0aGlzIHRvIGBmYWxzZWAgKGUuZy4gZm9yIHNvdXJjZXMgd2l0aCBwb2x5Z29ucyB0aGF0IHJlcHJlc2VudCBhZG1pbmlzdHJhdGl2ZVxuICogYm91bmRhcmllcyBvciBUb3BvSlNPTiBzb3VyY2VzKSBhbGxvd3MgdGhlIHJlbmRlcmVyIHRvIG9wdGltaXNlIGZpbGwgYW5kXG4gKiBzdHJva2Ugb3BlcmF0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7TG9hZGluZ1N0cmF0ZWd5fSBbc3RyYXRlZ3ldIFRoZSBsb2FkaW5nIHN0cmF0ZWd5IHRvIHVzZS5cbiAqIEJ5IGRlZmF1bHQgYW4ge0BsaW5rIG1vZHVsZTpvbC9sb2FkaW5nc3RyYXRlZ3l+YWxsfVxuICogc3RyYXRlZ3kgaXMgdXNlZCwgYSBvbmUtb2ZmIHN0cmF0ZWd5IHdoaWNoIGxvYWRzIGFsbCBmZWF0dXJlcyBhdCBvbmNlLlxuICogQHByb3BlcnR5IHtzdHJpbmd8aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlVXJsRnVuY3Rpb259IFt1cmxdXG4gKiBTZXR0aW5nIHRoaXMgb3B0aW9uIGluc3RydWN0cyB0aGUgc291cmNlIHRvIGxvYWQgZmVhdHVyZXMgdXNpbmcgYW4gWEhSIGxvYWRlclxuICogKHNlZSB7QGxpbmsgbW9kdWxlOm9sL2ZlYXR1cmVsb2FkZXJ+eGhyfSkuIFVzZSBhIGBzdHJpbmdgIGFuZCBhblxuICoge0BsaW5rIG1vZHVsZTpvbC9sb2FkaW5nc3RyYXRlZ3l+YWxsfSBmb3IgYSBvbmUtb2ZmIGRvd25sb2FkIG9mIGFsbCBmZWF0dXJlcyBmcm9tXG4gKiB0aGUgZ2l2ZW4gVVJMLiBVc2UgYSB7QGxpbmsgbW9kdWxlOm9sL2ZlYXR1cmVsb2FkZXJ+RmVhdHVyZVVybEZ1bmN0aW9ufSB0byBnZW5lcmF0ZSB0aGUgdXJsIHdpdGhcbiAqIG90aGVyIGxvYWRpbmcgc3RyYXRlZ2llcy5cbiAqIFJlcXVpcmVzIGBmb3JtYXRgIHRvIGJlIHNldCBhcyB3ZWxsLlxuICogV2hlbiBkZWZhdWx0IFhIUiBmZWF0dXJlIGxvYWRlciBpcyBwcm92aWRlZCwgdGhlIGZlYXR1cmVzIHdpbGxcbiAqIGJlIHRyYW5zZm9ybWVkIGZyb20gdGhlIGRhdGEgcHJvamVjdGlvbiB0byB0aGUgdmlldyBwcm9qZWN0aW9uXG4gKiBkdXJpbmcgcGFyc2luZy4gSWYgeW91ciByZW1vdGUgZGF0YSBzb3VyY2UgZG9lcyBub3QgYWR2ZXJ0aXNlIGl0cyBwcm9qZWN0aW9uXG4gKiBwcm9wZXJseSwgdGhpcyB0cmFuc2Zvcm1hdGlvbiB3aWxsIGJlIGluY29ycmVjdC4gRm9yIHNvbWUgZm9ybWF0cywgdGhlXG4gKiBkZWZhdWx0IHByb2plY3Rpb24gKHVzdWFsbHkgRVBTRzo0MzI2KSBjYW4gYmUgb3ZlcnJpZGRlbiBieSBzZXR0aW5nIHRoZVxuICogZGF0YVByb2plY3Rpb24gY29uc3RydWN0b3Igb3B0aW9uIG9uIHRoZSBmb3JtYXQuXG4gKiBOb3RlIHRoYXQgaWYgYSBzb3VyY2UgY29udGFpbnMgbm9uLWZlYXR1cmUgZGF0YSwgc3VjaCBhcyBhIEdlb0pTT04gZ2VvbWV0cnlcbiAqIG9yIGEgS01MIE5ldHdvcmtMaW5rLCB0aGVzZSB3aWxsIGJlIGlnbm9yZWQuIFVzZSBhIGN1c3RvbSBsb2FkZXIgdG8gbG9hZCB0aGVzZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VzZVNwYXRpYWxJbmRleD10cnVlXVxuICogQnkgZGVmYXVsdCwgYW4gUlRyZWUgaXMgdXNlZCBhcyBzcGF0aWFsIGluZGV4LiBXaGVuIGZlYXR1cmVzIGFyZSByZW1vdmVkIGFuZFxuICogYWRkZWQgZnJlcXVlbnRseSwgYW5kIHRoZSB0b3RhbCBudW1iZXIgb2YgZmVhdHVyZXMgaXMgbG93LCBzZXR0aW5nIHRoaXMgdG9cbiAqIGBmYWxzZWAgbWF5IGltcHJvdmUgcGVyZm9ybWFuY2UuXG4gKlxuICogTm90ZSB0aGF0XG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2dldEZlYXR1cmVzSW5FeHRlbnR9LFxuICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yflZlY3RvclNvdXJjZSNnZXRDbG9zZXN0RmVhdHVyZVRvQ29vcmRpbmF0ZX0gYW5kXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2dldEV4dGVudH0gY2Fubm90IGJlIHVzZWQgd2hlbiBgdXNlU3BhdGlhbEluZGV4YCBpc1xuICogc2V0IHRvIGBmYWxzZWAsIGFuZCB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2ZvckVhY2hGZWF0dXJlSW5FeHRlbnR9IHdpbGwgbG9vcFxuICogdGhyb3VnaCBhbGwgZmVhdHVyZXMuXG4gKlxuICogV2hlbiBzZXQgdG8gYGZhbHNlYCwgdGhlIGZlYXR1cmVzIHdpbGwgYmUgbWFpbnRhaW5lZCBpbiBhblxuICoge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufSwgd2hpY2ggY2FuIGJlIHJldHJpZXZlZCB0aHJvdWdoXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2dldEZlYXR1cmVzQ29sbGVjdGlvbn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt3cmFwWD10cnVlXSBXcmFwIHRoZSB3b3JsZCBob3Jpem9udGFsbHkuIEZvciB2ZWN0b3IgZWRpdGluZyBhY3Jvc3MgdGhlXG4gKiAtMTgwwrAgYW5kIDE4MMKwIG1lcmlkaWFucyB0byB3b3JrIHByb3Blcmx5LCB0aGlzIHNob3VsZCBiZSBzZXQgdG8gYGZhbHNlYC4gVGhlXG4gKiByZXN1bHRpbmcgZ2VvbWV0cnkgY29vcmRpbmF0ZXMgd2lsbCB0aGVuIGV4Y2VlZCB0aGUgd29ybGQgYm91bmRzLlxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJvdmlkZXMgYSBzb3VyY2Ugb2YgZmVhdHVyZXMgZm9yIHZlY3RvciBsYXllcnMuIFZlY3RvciBmZWF0dXJlcyBwcm92aWRlZFxuICogYnkgdGhpcyBzb3VyY2UgYXJlIHN1aXRhYmxlIGZvciBlZGl0aW5nLiBTZWUge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yVGlsZX5WZWN0b3JUaWxlfSBmb3JcbiAqIHZlY3RvciBkYXRhIHRoYXQgaXMgb3B0aW1pemVkIGZvciByZW5kZXJpbmcuXG4gKlxuICogQGZpcmVzIFZlY3RvclNvdXJjZUV2ZW50XG4gKiBAYXBpXG4gKiBAdGVtcGxhdGUge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gR2VvbWV0cnlcbiAqL1xuXG52YXIgVmVjdG9yU291cmNlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFZlY3RvclNvdXJjZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFZlY3RvciBzb3VyY2Ugb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JTb3VyY2Uob3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGF0dHJpYnV0aW9uczogb3B0aW9ucy5hdHRyaWJ1dGlvbnMsXG4gICAgICBwcm9qZWN0aW9uOiB1bmRlZmluZWQsXG4gICAgICBzdGF0ZTogU291cmNlU3RhdGUuUkVBRFksXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy53cmFwWCA6IHRydWVcbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZUxvYWRlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxvYWRlcl8gPSBWT0lEO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZm9ybWF0XyA9IG9wdGlvbnMuZm9ybWF0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5vdmVybGFwc18gPSBvcHRpb25zLm92ZXJsYXBzID09PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0aW9ucy5vdmVybGFwcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd8aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlVXJsRnVuY3Rpb258dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMudXJsXyA9IG9wdGlvbnMudXJsO1xuXG4gICAgaWYgKG9wdGlvbnMubG9hZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIF90aGlzLmxvYWRlcl8gPSBvcHRpb25zLmxvYWRlcjtcbiAgICB9IGVsc2UgaWYgKF90aGlzLnVybF8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXNzZXJ0KF90aGlzLmZvcm1hdF8sIDcpOyAvLyBgZm9ybWF0YCBtdXN0IGJlIHNldCB3aGVuIGB1cmxgIGlzIHNldFxuICAgICAgLy8gY3JlYXRlIGEgWEhSIGZlYXR1cmUgbG9hZGVyIGZvciBcInVybFwiIGFuZCBcImZvcm1hdFwiXG5cbiAgICAgIF90aGlzLmxvYWRlcl8gPSB4aHIoX3RoaXMudXJsXyxcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIF90aGlzLmZvcm1hdF8pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtMb2FkaW5nU3RyYXRlZ3l9XG4gICAgICovXG5cblxuICAgIF90aGlzLnN0cmF0ZWd5XyA9IG9wdGlvbnMuc3RyYXRlZ3kgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuc3RyYXRlZ3kgOiBhbGxTdHJhdGVneTtcbiAgICB2YXIgdXNlU3BhdGlhbEluZGV4ID0gb3B0aW9ucy51c2VTcGF0aWFsSW5kZXggIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudXNlU3BhdGlhbEluZGV4IDogdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtSQnVzaDxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZlYXR1cmVzUnRyZWVfID0gdXNlU3BhdGlhbEluZGV4ID8gbmV3IFJCdXNoKCkgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge1JCdXNoPHtleHRlbnQ6IGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxvYWRlZEV4dGVudHNSdHJlZV8gPSBuZXcgUkJ1c2goKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBBIGxvb2t1cCBvZiBmZWF0dXJlcyBieSBpZCAodGhlIHJldHVybiBmcm9tIGZlYXR1cmUuZ2V0SWQoKSkuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuaWRJbmRleF8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBBIGxvb2t1cCBvZiBmZWF0dXJlcyBieSB1aWQgKHVzaW5nIGdldFVpZChmZWF0dXJlKSkuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudWlkSW5kZXhfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT4+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmVhdHVyZUNoYW5nZUtleXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Q29sbGVjdGlvbjxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8gPSBudWxsO1xuICAgIHZhciBjb2xsZWN0aW9uLCBmZWF0dXJlcztcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmVhdHVyZXMpKSB7XG4gICAgICBmZWF0dXJlcyA9IG9wdGlvbnMuZmVhdHVyZXM7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLmZlYXR1cmVzKSB7XG4gICAgICBjb2xsZWN0aW9uID0gb3B0aW9ucy5mZWF0dXJlcztcbiAgICAgIGZlYXR1cmVzID0gY29sbGVjdGlvbi5nZXRBcnJheSgpO1xuICAgIH1cblxuICAgIGlmICghdXNlU3BhdGlhbEluZGV4ICYmIGNvbGxlY3Rpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29sbGVjdGlvbiA9IG5ldyBDb2xsZWN0aW9uKGZlYXR1cmVzKTtcbiAgICB9XG5cbiAgICBpZiAoZmVhdHVyZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMuYWRkRmVhdHVyZXNJbnRlcm5hbChmZWF0dXJlcyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbGxlY3Rpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMuYmluZEZlYXR1cmVzQ29sbGVjdGlvbl8oY29sbGVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgYSBzaW5nbGUgZmVhdHVyZSB0byB0aGUgc291cmNlLiAgSWYgeW91IHdhbnQgdG8gYWRkIGEgYmF0Y2ggb2YgZmVhdHVyZXNcbiAgICogYXQgb25jZSwgY2FsbCB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2FkZEZlYXR1cmVzICNhZGRGZWF0dXJlcygpfVxuICAgKiBpbnN0ZWFkLiBBIGZlYXR1cmUgd2lsbCBub3QgYmUgYWRkZWQgdG8gdGhlIHNvdXJjZSBpZiBmZWF0dXJlIHdpdGhcbiAgICogdGhlIHNhbWUgaWQgaXMgYWxyZWFkeSB0aGVyZS4gVGhlIHJlYXNvbiBmb3IgdGhpcyBiZWhhdmlvciBpcyB0byBhdm9pZFxuICAgKiBmZWF0dXJlIGR1cGxpY2F0aW9uIHdoZW4gdXNpbmcgYmJveCBvciB0aWxlIGxvYWRpbmcgc3RyYXRlZ2llcy5cbiAgICogTm90ZTogdGhpcyBhbHNvIGFwcGxpZXMgaWYgYW4ge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufSBpcyB1c2VkIGZvciBmZWF0dXJlcyxcbiAgICogbWVhbmluZyB0aGF0IGlmIGEgZmVhdHVyZSB3aXRoIGEgZHVwbGljYXRlIGlkIGlzIGFkZGVkIGluIHRoZSBjb2xsZWN0aW9uLCBpdCB3aWxsXG4gICAqIGJlIHJlbW92ZWQgZnJvbSBpdCByaWdodCBhd2F5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgRmVhdHVyZSB0byBhZGQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmFkZEZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgIHRoaXMuYWRkRmVhdHVyZUludGVybmFsKGZlYXR1cmUpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQWRkIGEgZmVhdHVyZSB3aXRob3V0IGZpcmluZyBhIGBjaGFuZ2VgIGV2ZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgRmVhdHVyZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuYWRkRmVhdHVyZUludGVybmFsID0gZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICB2YXIgZmVhdHVyZUtleSA9IGdldFVpZChmZWF0dXJlKTtcblxuICAgIGlmICghdGhpcy5hZGRUb0luZGV4XyhmZWF0dXJlS2V5LCBmZWF0dXJlKSkge1xuICAgICAgaWYgKHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgICB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8ucmVtb3ZlKGZlYXR1cmUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZXR1cENoYW5nZUV2ZW50c18oZmVhdHVyZUtleSwgZmVhdHVyZSk7XG4gICAgdmFyIGdlb21ldHJ5ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuXG4gICAgaWYgKGdlb21ldHJ5KSB7XG4gICAgICB2YXIgZXh0ZW50ID0gZ2VvbWV0cnkuZ2V0RXh0ZW50KCk7XG5cbiAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8uaW5zZXJ0KGV4dGVudCwgZmVhdHVyZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfW2ZlYXR1cmVLZXldID0gZmVhdHVyZTtcbiAgICB9XG5cbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5BRERGRUFUVVJFLCBmZWF0dXJlKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmVhdHVyZUtleSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBUaGUgZmVhdHVyZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnNldHVwQ2hhbmdlRXZlbnRzXyA9IGZ1bmN0aW9uIChmZWF0dXJlS2V5LCBmZWF0dXJlKSB7XG4gICAgdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c19bZmVhdHVyZUtleV0gPSBbbGlzdGVuKGZlYXR1cmUsIEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMuaGFuZGxlRmVhdHVyZUNoYW5nZV8sIHRoaXMpLCBsaXN0ZW4oZmVhdHVyZSwgT2JqZWN0RXZlbnRUeXBlLlBST1BFUlRZQ0hBTkdFLCB0aGlzLmhhbmRsZUZlYXR1cmVDaGFuZ2VfLCB0aGlzKV07XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmVhdHVyZUtleSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBUaGUgZmVhdHVyZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIGZlYXR1cmUgaXMgXCJ2YWxpZFwiLCBpbiB0aGUgc2Vuc2UgdGhhdCBpdCBpcyBhbHNvIGFcbiAgICogICAgIGNhbmRpZGF0ZSBmb3IgaW5zZXJ0aW9uIGludG8gdGhlIFJ0cmVlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuYWRkVG9JbmRleF8gPSBmdW5jdGlvbiAoZmVhdHVyZUtleSwgZmVhdHVyZSkge1xuICAgIHZhciB2YWxpZCA9IHRydWU7XG4gICAgdmFyIGlkID0gZmVhdHVyZS5nZXRJZCgpO1xuXG4gICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICghKGlkLnRvU3RyaW5nKCkgaW4gdGhpcy5pZEluZGV4XykpIHtcbiAgICAgICAgdGhpcy5pZEluZGV4X1tpZC50b1N0cmluZygpXSA9IGZlYXR1cmU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWxpZCA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh2YWxpZCkge1xuICAgICAgYXNzZXJ0KCEoZmVhdHVyZUtleSBpbiB0aGlzLnVpZEluZGV4XyksIDMwKTsgLy8gVGhlIHBhc3NlZCBgZmVhdHVyZWAgd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhlIHNvdXJjZVxuXG4gICAgICB0aGlzLnVpZEluZGV4X1tmZWF0dXJlS2V5XSA9IGZlYXR1cmU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkO1xuICB9O1xuICAvKipcbiAgICogQWRkIGEgYmF0Y2ggb2YgZmVhdHVyZXMgdG8gdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gZmVhdHVyZXMgRmVhdHVyZXMgdG8gYWRkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5hZGRGZWF0dXJlcyA9IGZ1bmN0aW9uIChmZWF0dXJlcykge1xuICAgIHRoaXMuYWRkRmVhdHVyZXNJbnRlcm5hbChmZWF0dXJlcyk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBBZGQgZmVhdHVyZXMgd2l0aG91dCBmaXJpbmcgYSBgY2hhbmdlYCBldmVudC5cbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gZmVhdHVyZXMgRmVhdHVyZXMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmFkZEZlYXR1cmVzSW50ZXJuYWwgPSBmdW5jdGlvbiAoZmVhdHVyZXMpIHtcbiAgICB2YXIgZXh0ZW50cyA9IFtdO1xuICAgIHZhciBuZXdGZWF0dXJlcyA9IFtdO1xuICAgIHZhciBnZW9tZXRyeUZlYXR1cmVzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoXzEgPSBmZWF0dXJlcy5sZW5ndGg7IGkgPCBsZW5ndGhfMTsgaSsrKSB7XG4gICAgICB2YXIgZmVhdHVyZSA9IGZlYXR1cmVzW2ldO1xuICAgICAgdmFyIGZlYXR1cmVLZXkgPSBnZXRVaWQoZmVhdHVyZSk7XG5cbiAgICAgIGlmICh0aGlzLmFkZFRvSW5kZXhfKGZlYXR1cmVLZXksIGZlYXR1cmUpKSB7XG4gICAgICAgIG5ld0ZlYXR1cmVzLnB1c2goZmVhdHVyZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aF8yID0gbmV3RmVhdHVyZXMubGVuZ3RoOyBpIDwgbGVuZ3RoXzI7IGkrKykge1xuICAgICAgdmFyIGZlYXR1cmUgPSBuZXdGZWF0dXJlc1tpXTtcbiAgICAgIHZhciBmZWF0dXJlS2V5ID0gZ2V0VWlkKGZlYXR1cmUpO1xuICAgICAgdGhpcy5zZXR1cENoYW5nZUV2ZW50c18oZmVhdHVyZUtleSwgZmVhdHVyZSk7XG4gICAgICB2YXIgZ2VvbWV0cnkgPSBmZWF0dXJlLmdldEdlb21ldHJ5KCk7XG5cbiAgICAgIGlmIChnZW9tZXRyeSkge1xuICAgICAgICB2YXIgZXh0ZW50ID0gZ2VvbWV0cnkuZ2V0RXh0ZW50KCk7XG4gICAgICAgIGV4dGVudHMucHVzaChleHRlbnQpO1xuICAgICAgICBnZW9tZXRyeUZlYXR1cmVzLnB1c2goZmVhdHVyZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzX1tmZWF0dXJlS2V5XSA9IGZlYXR1cmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8ubG9hZChleHRlbnRzLCBnZW9tZXRyeUZlYXR1cmVzKTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoXzMgPSBuZXdGZWF0dXJlcy5sZW5ndGg7IGkgPCBsZW5ndGhfMzsgaSsrKSB7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5BRERGRUFUVVJFLCBuZXdGZWF0dXJlc1tpXSkpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IUNvbGxlY3Rpb248aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59IGNvbGxlY3Rpb24gQ29sbGVjdGlvbi5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmJpbmRGZWF0dXJlc0NvbGxlY3Rpb25fID0gZnVuY3Rpb24gKGNvbGxlY3Rpb24pIHtcbiAgICB2YXIgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihWZWN0b3JFdmVudFR5cGUuQURERkVBVFVSRSxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1ZlY3RvclNvdXJjZUV2ZW50PEdlb21ldHJ5Pn0gZXZ0IFRoZSB2ZWN0b3Igc291cmNlIGV2ZW50XG4gICAgICovXG4gICAgZnVuY3Rpb24gKGV2dCkge1xuICAgICAgaWYgKCFtb2RpZnlpbmdDb2xsZWN0aW9uKSB7XG4gICAgICAgIG1vZGlmeWluZ0NvbGxlY3Rpb24gPSB0cnVlO1xuICAgICAgICBjb2xsZWN0aW9uLnB1c2goZXZ0LmZlYXR1cmUpO1xuICAgICAgICBtb2RpZnlpbmdDb2xsZWN0aW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKFZlY3RvckV2ZW50VHlwZS5SRU1PVkVGRUFUVVJFLFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VmVjdG9yU291cmNlRXZlbnQ8R2VvbWV0cnk+fSBldnQgVGhlIHZlY3RvciBzb3VyY2UgZXZlbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoIW1vZGlmeWluZ0NvbGxlY3Rpb24pIHtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IHRydWU7XG4gICAgICAgIGNvbGxlY3Rpb24ucmVtb3ZlKGV2dC5mZWF0dXJlKTtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbGxlY3Rpb24uYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLkFERCxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbkV2ZW50fSBldnQgVGhlIGNvbGxlY3Rpb24gZXZlbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoIW1vZGlmeWluZ0NvbGxlY3Rpb24pIHtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IHRydWU7XG4gICAgICAgIHRoaXMuYWRkRmVhdHVyZShcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSAqL1xuICAgICAgICBldnQuZWxlbWVudCk7XG4gICAgICAgIG1vZGlmeWluZ0NvbGxlY3Rpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LmJpbmQodGhpcykpO1xuICAgIGNvbGxlY3Rpb24uYWRkRXZlbnRMaXN0ZW5lcihDb2xsZWN0aW9uRXZlbnRUeXBlLlJFTU9WRSxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0NvbGxlY3Rpb24uanNcIikuQ29sbGVjdGlvbkV2ZW50fSBldnQgVGhlIGNvbGxlY3Rpb24gZXZlbnRcbiAgICAgKi9cbiAgICBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICBpZiAoIW1vZGlmeWluZ0NvbGxlY3Rpb24pIHtcbiAgICAgICAgbW9kaWZ5aW5nQ29sbGVjdGlvbiA9IHRydWU7XG4gICAgICAgIHRoaXMucmVtb3ZlRmVhdHVyZShcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSAqL1xuICAgICAgICBldnQuZWxlbWVudCk7XG4gICAgICAgIG1vZGlmeWluZ0NvbGxlY3Rpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9LmJpbmQodGhpcykpO1xuICAgIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXyA9IGNvbGxlY3Rpb247XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIGZlYXR1cmVzIGZyb20gdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2Zhc3QgU2tpcCBkaXNwYXRjaGluZyBvZiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3IuVmVjdG9yU291cmNlRXZlbnQjcmVtb3ZlZmVhdHVyZX0gZXZlbnRzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uIChvcHRfZmFzdCkge1xuICAgIGlmIChvcHRfZmFzdCkge1xuICAgICAgZm9yICh2YXIgZmVhdHVyZUlkIGluIHRoaXMuZmVhdHVyZUNoYW5nZUtleXNfKSB7XG4gICAgICAgIHZhciBrZXlzID0gdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c19bZmVhdHVyZUlkXTtcbiAgICAgICAga2V5cy5mb3JFYWNoKHVubGlzdGVuQnlLZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgICB0aGlzLmZlYXR1cmVDaGFuZ2VLZXlzXyA9IHt9O1xuICAgICAgICB0aGlzLmlkSW5kZXhfID0ge307XG4gICAgICAgIHRoaXMudWlkSW5kZXhfID0ge307XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8uZm9yRWFjaCh0aGlzLnJlbW92ZUZlYXR1cmVJbnRlcm5hbC5iaW5kKHRoaXMpKTtcblxuICAgICAgICBmb3IgKHZhciBpZCBpbiB0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzXykge1xuICAgICAgICAgIHRoaXMucmVtb3ZlRmVhdHVyZUludGVybmFsKHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfW2lkXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fKSB7XG4gICAgICB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8uY2xlYXIoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5jbGVhcigpO1xuICAgIH1cblxuICAgIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfID0ge307XG4gICAgdmFyIGNsZWFyRXZlbnQgPSBuZXcgVmVjdG9yU291cmNlRXZlbnQoVmVjdG9yRXZlbnRUeXBlLkNMRUFSKTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQoY2xlYXJFdmVudCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBJdGVyYXRlIHRocm91Z2ggYWxsIGZlYXR1cmVzIG9uIHRoZSBzb3VyY2UsIGNhbGxpbmcgdGhlIHByb3ZpZGVkIGNhbGxiYWNrXG4gICAqIHdpdGggZWFjaCBvbmUuICBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBhbnkgXCJ0cnV0aHlcIiB2YWx1ZSwgaXRlcmF0aW9uIHdpbGxcbiAgICogc3RvcCBhbmQgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lIHZhbHVlLlxuICAgKiBOb3RlOiB0aGlzIGZ1bmN0aW9uIG9ubHkgaXRlcmF0ZSB0aHJvdWdoIHRoZSBmZWF0dXJlIHRoYXQgaGF2ZSBhIGRlZmluZWQgZ2VvbWV0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pik6IFR9IGNhbGxiYWNrIENhbGxlZCB3aXRoIGVhY2ggZmVhdHVyZVxuICAgKiAgICAgb24gdGhlIHNvdXJjZS4gIFJldHVybiBhIHRydXRoeSB2YWx1ZSB0byBzdG9wIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbGFzdCBjYWxsIHRvIHRoZSBjYWxsYmFjay5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmUgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNSdHJlZV8uZm9yRWFjaChjYWxsYmFjayk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8pIHtcbiAgICAgIHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXy5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBJdGVyYXRlIHRocm91Z2ggYWxsIGZlYXR1cmVzIHdob3NlIGdlb21ldHJpZXMgY29udGFpbiB0aGUgcHJvdmlkZWRcbiAgICogY29vcmRpbmF0ZSwgY2FsbGluZyB0aGUgY2FsbGJhY2sgd2l0aCBlYWNoIGZlYXR1cmUuICBJZiB0aGUgY2FsbGJhY2sgcmV0dXJuc1xuICAgKiBhIFwidHJ1dGh5XCIgdmFsdWUsIGl0ZXJhdGlvbiB3aWxsIHN0b3AgYW5kIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiB0aGUgc2FtZVxuICAgKiB2YWx1ZS5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+KTogVH0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggZWFjaCBmZWF0dXJlXG4gICAqICAgICB3aG9zZSBnb2VtZXRyeSBjb250YWlucyB0aGUgcHJvdmlkZWQgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbGFzdCBjYWxsIHRvIHRoZSBjYWxsYmFjay5cbiAgICogQHRlbXBsYXRlIFRcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlRGlyZWN0ID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGV4dGVudCA9IFtjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdLCBjb29yZGluYXRlWzBdLCBjb29yZGluYXRlWzFdXTtcbiAgICByZXR1cm4gdGhpcy5mb3JFYWNoRmVhdHVyZUluRXh0ZW50KGV4dGVudCwgZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2V0R2VvbWV0cnkoKTtcblxuICAgICAgaWYgKGdlb21ldHJ5LmludGVyc2VjdHNDb29yZGluYXRlKGNvb3JkaW5hdGUpKSB7XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhmZWF0dXJlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIC8qKlxuICAgKiBJdGVyYXRlIHRocm91Z2ggYWxsIGZlYXR1cmVzIHdob3NlIGJvdW5kaW5nIGJveCBpbnRlcnNlY3RzIHRoZSBwcm92aWRlZFxuICAgKiBleHRlbnQgKG5vdGUgdGhhdCB0aGUgZmVhdHVyZSdzIGdlb21ldHJ5IG1heSBub3QgaW50ZXJzZWN0IHRoZSBleHRlbnQpLFxuICAgKiBjYWxsaW5nIHRoZSBjYWxsYmFjayB3aXRoIGVhY2ggZmVhdHVyZS4gIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgXCJ0cnV0aHlcIlxuICAgKiB2YWx1ZSwgaXRlcmF0aW9uIHdpbGwgc3RvcCBhbmQgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lIHZhbHVlLlxuICAgKlxuICAgKiBJZiB5b3UgYXJlIGludGVyZXN0ZWQgaW4gZmVhdHVyZXMgd2hvc2UgZ2VvbWV0cnkgaW50ZXJzZWN0cyBhbiBleHRlbnQsIGNhbGxcbiAgICogdGhlIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZm9yRWFjaEZlYXR1cmVJbnRlcnNlY3RpbmdFeHRlbnQgI2ZvckVhY2hGZWF0dXJlSW50ZXJzZWN0aW5nRXh0ZW50KCl9IG1ldGhvZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBXaGVuIGB1c2VTcGF0aWFsSW5kZXhgIGlzIHNldCB0byBmYWxzZSwgdGhpcyBtZXRob2Qgd2lsbCBsb29wIHRocm91Z2ggYWxsXG4gICAqIGZlYXR1cmVzLCBlcXVpdmFsZW50IHRvIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZm9yRWFjaEZlYXR1cmUgI2ZvckVhY2hGZWF0dXJlKCl9LlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pik6IFR9IGNhbGxiYWNrIENhbGxlZCB3aXRoIGVhY2ggZmVhdHVyZVxuICAgKiAgICAgd2hvc2UgYm91bmRpbmcgYm94IGludGVyc2VjdHMgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbGFzdCBjYWxsIHRvIHRoZSBjYWxsYmFjay5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVJbkV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgIHJldHVybiB0aGlzLmZlYXR1cmVzUnRyZWVfLmZvckVhY2hJbkV4dGVudChleHRlbnQsIGNhbGxiYWNrKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmVhdHVyZXNDb2xsZWN0aW9uXykge1xuICAgICAgdGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fLmZvckVhY2goY2FsbGJhY2spO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgdGhyb3VnaCBhbGwgZmVhdHVyZXMgd2hvc2UgZ2VvbWV0cnkgaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgZXh0ZW50LFxuICAgKiBjYWxsaW5nIHRoZSBjYWxsYmFjayB3aXRoIGVhY2ggZmVhdHVyZS4gIElmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgXCJ0cnV0aHlcIlxuICAgKiB2YWx1ZSwgaXRlcmF0aW9uIHdpbGwgc3RvcCBhbmQgdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIHRoZSBzYW1lIHZhbHVlLlxuICAgKlxuICAgKiBJZiB5b3Ugb25seSB3YW50IHRvIHRlc3QgZm9yIGJvdW5kaW5nIGJveCBpbnRlcnNlY3Rpb24sIGNhbGwgdGhlXG4gICAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn5WZWN0b3JTb3VyY2UjZm9yRWFjaEZlYXR1cmVJbkV4dGVudCAjZm9yRWFjaEZlYXR1cmVJbkV4dGVudCgpfSBtZXRob2QgaW5zdGVhZC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4pOiBUfSBjYWxsYmFjayBDYWxsZWQgd2l0aCBlYWNoIGZlYXR1cmVcbiAgICogICAgIHdob3NlIGdlb21ldHJ5IGludGVyc2VjdHMgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgbGFzdCBjYWxsIHRvIHRoZSBjYWxsYmFjay5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZm9yRWFjaEZlYXR1cmVJbnRlcnNlY3RpbmdFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50LCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLmZvckVhY2hGZWF0dXJlSW5FeHRlbnQoZXh0ZW50LFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAqIEByZXR1cm4ge1R8dW5kZWZpbmVkfSBUaGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGxhc3QgY2FsbCB0byB0aGUgY2FsbGJhY2suXG4gICAgICovXG4gICAgZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2V0R2VvbWV0cnkoKTtcblxuICAgICAgaWYgKGdlb21ldHJ5LmludGVyc2VjdHNFeHRlbnQoZXh0ZW50KSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gY2FsbGJhY2soZmVhdHVyZSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZXMgY29sbGVjdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhpcyBzb3VyY2UuIFdpbGwgYmUgYG51bGxgXG4gICAqIHVubGVzcyB0aGUgc291cmNlIHdhcyBjb25maWd1cmVkIHdpdGggYHVzZVNwYXRpYWxJbmRleGAgc2V0IHRvIGBmYWxzZWAsIG9yXG4gICAqIHdpdGggYW4ge0BsaW5rIG1vZHVsZTpvbC9Db2xsZWN0aW9ufSBhcyBgZmVhdHVyZXNgLlxuICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9uPGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT4+fSBUaGUgY29sbGVjdGlvbiBvZiBmZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0RmVhdHVyZXNDb2xsZWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYWxsIGZlYXR1cmVzIG9uIHRoZSBzb3VyY2UgaW4gcmFuZG9tIG9yZGVyLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldEZlYXR1cmVzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBmZWF0dXJlcztcblxuICAgIGlmICh0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8pIHtcbiAgICAgIGZlYXR1cmVzID0gdGhpcy5mZWF0dXJlc0NvbGxlY3Rpb25fLmdldEFycmF5KCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICBmZWF0dXJlcyA9IHRoaXMuZmVhdHVyZXNSdHJlZV8uZ2V0QWxsKCk7XG5cbiAgICAgIGlmICghaXNFbXB0eSh0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzXykpIHtcbiAgICAgICAgZXh0ZW5kKGZlYXR1cmVzLCBnZXRWYWx1ZXModGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc18pKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gKi9cbiAgICAgIGZlYXR1cmVzXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhbGwgZmVhdHVyZXMgd2hvc2UgZ2VvbWV0cnkgaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pj59IEZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRGZWF0dXJlc0F0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlKSB7XG4gICAgdmFyIGZlYXR1cmVzID0gW107XG4gICAgdGhpcy5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZURpcmVjdChjb29yZGluYXRlLCBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgICAgZmVhdHVyZXMucHVzaChmZWF0dXJlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZmVhdHVyZXM7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYWxsIGZlYXR1cmVzIHdob3NlIGJvdW5kaW5nIGJveCBpbnRlcnNlY3RzIHRoZSBwcm92aWRlZCBleHRlbnQuICBOb3RlIHRoYXQgdGhpcyByZXR1cm5zIGFuIGFycmF5IG9mXG4gICAqIGFsbCBmZWF0dXJlcyBpbnRlcnNlY3RpbmcgdGhlIGdpdmVuIGV4dGVudCBpbiByYW5kb20gb3JkZXIgKHNvIGl0IG1heSBpbmNsdWRlXG4gICAqIGZlYXR1cmVzIHdob3NlIGdlb21ldHJpZXMgZG8gbm90IGludGVyc2VjdCB0aGUgZXh0ZW50KS5cbiAgICpcbiAgICogV2hlbiBgdXNlU3BhdGlhbEluZGV4YCBpcyBzZXQgdG8gZmFsc2UsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGFsbFxuICAgKiBmZWF0dXJlcy5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+Pn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldEZlYXR1cmVzSW5FeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgaWYgKHRoaXMuZmVhdHVyZXNSdHJlZV8pIHtcbiAgICAgIHJldHVybiB0aGlzLmZlYXR1cmVzUnRyZWVfLmdldEluRXh0ZW50KGV4dGVudCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8pIHtcbiAgICAgIHJldHVybiB0aGlzLmZlYXR1cmVzQ29sbGVjdGlvbl8uZ2V0QXJyYXkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY2xvc2VzdCBmZWF0dXJlIHRvIHRoZSBwcm92aWRlZCBjb29yZGluYXRlLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBub3QgYXZhaWxhYmxlIHdoZW4gdGhlIHNvdXJjZSBpcyBjb25maWd1cmVkIHdpdGhcbiAgICogYHVzZVNwYXRpYWxJbmRleGAgc2V0IHRvIGBmYWxzZWAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pik6Ym9vbGVhbj19IG9wdF9maWx0ZXIgRmVhdHVyZSBmaWx0ZXIgZnVuY3Rpb24uXG4gICAqICAgICBUaGUgZmlsdGVyIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSBvbmUgYXJndW1lbnQsIHRoZSB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmUgZmVhdHVyZX1cbiAgICogICAgIGFuZCBpdCBzaG91bGQgcmV0dXJuIGEgYm9vbGVhbiB2YWx1ZS4gQnkgZGVmYXVsdCwgbm8gZmlsdGVyaW5nIGlzIG1hZGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IENsb3Nlc3QgZmVhdHVyZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0Q2xvc2VzdEZlYXR1cmVUb0Nvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSwgb3B0X2ZpbHRlcikge1xuICAgIC8vIEZpbmQgdGhlIGNsb3Nlc3QgZmVhdHVyZSB1c2luZyBicmFuY2ggYW5kIGJvdW5kLiAgV2Ugc3RhcnQgc2VhcmNoaW5nIGFuXG4gICAgLy8gaW5maW5pdGUgZXh0ZW50LCBhbmQgZmluZCB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgZmlyc3QgZmVhdHVyZSBmb3VuZC4gIFRoaXNcbiAgICAvLyBiZWNvbWVzIHRoZSBjbG9zZXN0IGZlYXR1cmUuICBXZSB0aGVuIGNvbXB1dGUgYSBzbWFsbGVyIGV4dGVudCB3aGljaCBhbnlcbiAgICAvLyBjbG9zZXIgZmVhdHVyZSBtdXN0IGludGVyc2VjdC4gIFdlIGNvbnRpbnVlIHNlYXJjaGluZyB3aXRoIHRoaXMgc21hbGxlclxuICAgIC8vIGV4dGVudCwgdHJ5aW5nIHRvIGZpbmQgYSBjbG9zZXIgZmVhdHVyZS4gIEV2ZXJ5IHRpbWUgd2UgZmluZCBhIGNsb3NlclxuICAgIC8vIGZlYXR1cmUsIHdlIHVwZGF0ZSB0aGUgZXh0ZW50IGJlaW5nIHNlYXJjaGVkIHNvIHRoYXQgYW55IGV2ZW4gY2xvc2VyXG4gICAgLy8gZmVhdHVyZSBtdXN0IGludGVyc2VjdCBpdC4gIFdlIGNvbnRpbnVlIHVudGlsIHdlIHJ1biBvdXQgb2YgZmVhdHVyZXMuXG4gICAgdmFyIHggPSBjb29yZGluYXRlWzBdO1xuICAgIHZhciB5ID0gY29vcmRpbmF0ZVsxXTtcbiAgICB2YXIgY2xvc2VzdEZlYXR1cmUgPSBudWxsO1xuICAgIHZhciBjbG9zZXN0UG9pbnQgPSBbTmFOLCBOYU5dO1xuICAgIHZhciBtaW5TcXVhcmVkRGlzdGFuY2UgPSBJbmZpbml0eTtcbiAgICB2YXIgZXh0ZW50ID0gWy1JbmZpbml0eSwgLUluZmluaXR5LCBJbmZpbml0eSwgSW5maW5pdHldO1xuICAgIHZhciBmaWx0ZXIgPSBvcHRfZmlsdGVyID8gb3B0X2ZpbHRlciA6IFRSVUU7XG4gICAgdGhpcy5mZWF0dXJlc1J0cmVlXy5mb3JFYWNoSW5FeHRlbnQoZXh0ZW50LFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgICBpZiAoZmlsdGVyKGZlYXR1cmUpKSB7XG4gICAgICAgIHZhciBnZW9tZXRyeSA9IGZlYXR1cmUuZ2V0R2VvbWV0cnkoKTtcbiAgICAgICAgdmFyIHByZXZpb3VzTWluU3F1YXJlZERpc3RhbmNlID0gbWluU3F1YXJlZERpc3RhbmNlO1xuICAgICAgICBtaW5TcXVhcmVkRGlzdGFuY2UgPSBnZW9tZXRyeS5jbG9zZXN0UG9pbnRYWSh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSk7XG5cbiAgICAgICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IHByZXZpb3VzTWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICAgICAgY2xvc2VzdEZlYXR1cmUgPSBmZWF0dXJlOyAvLyBUaGlzIGlzIHNuZWFreS4gIFJlZHVjZSB0aGUgZXh0ZW50IHRoYXQgaXQgaXMgY3VycmVudGx5IGJlaW5nXG4gICAgICAgICAgLy8gc2VhcmNoZWQgd2hpbGUgdGhlIFItVHJlZSB0cmF2ZXJzYWwgdXNpbmcgdGhpcyBzYW1lIGV4dGVudCBvYmplY3RcbiAgICAgICAgICAvLyBpcyBzdGlsbCBpbiBwcm9ncmVzcy4gIFRoaXMgaXMgc2FmZSBiZWNhdXNlIHRoZSBuZXcgZXh0ZW50IGlzXG4gICAgICAgICAgLy8gc3RyaWN0bHkgY29udGFpbmVkIGJ5IHRoZSBvbGQgZXh0ZW50LlxuXG4gICAgICAgICAgdmFyIG1pbkRpc3RhbmNlID0gTWF0aC5zcXJ0KG1pblNxdWFyZWREaXN0YW5jZSk7XG4gICAgICAgICAgZXh0ZW50WzBdID0geCAtIG1pbkRpc3RhbmNlO1xuICAgICAgICAgIGV4dGVudFsxXSA9IHkgLSBtaW5EaXN0YW5jZTtcbiAgICAgICAgICBleHRlbnRbMl0gPSB4ICsgbWluRGlzdGFuY2U7XG4gICAgICAgICAgZXh0ZW50WzNdID0geSArIG1pbkRpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNsb3Nlc3RGZWF0dXJlO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgb2YgdGhlIGZlYXR1cmVzIGN1cnJlbnRseSBpbiB0aGUgc291cmNlLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBpcyBub3QgYXZhaWxhYmxlIHdoZW4gdGhlIHNvdXJjZSBpcyBjb25maWd1cmVkIHdpdGhcbiAgICogYHVzZVNwYXRpYWxJbmRleGAgc2V0IHRvIGBmYWxzZWAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LiBJZiBwcm92aWRlZCwgbm8gbmV3IGV4dGVudFxuICAgKiAgICAgd2lsbCBiZSBjcmVhdGVkLiBJbnN0ZWFkLCB0aGF0IGV4dGVudCdzIGNvb3JkaW5hdGVzIHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0RXh0ZW50ID0gZnVuY3Rpb24gKG9wdF9leHRlbnQpIHtcbiAgICByZXR1cm4gdGhpcy5mZWF0dXJlc1J0cmVlXy5nZXRFeHRlbnQob3B0X2V4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSBmZWF0dXJlIGJ5IGl0cyBpZGVudGlmaWVyICh0aGUgdmFsdWUgcmV0dXJuZWQgYnkgZmVhdHVyZS5nZXRJZCgpKS5cbiAgICogTm90ZSB0aGF0IHRoZSBpbmRleCB0cmVhdHMgc3RyaW5nIGFuZCBudW1lcmljIGlkZW50aWZpZXJzIGFzIHRoZSBzYW1lLiAgU29cbiAgICogYHNvdXJjZS5nZXRGZWF0dXJlQnlJZCgyKWAgd2lsbCByZXR1cm4gYSBmZWF0dXJlIHdpdGggaWQgYCcyJ2Agb3IgYDJgLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IGlkIEZlYXR1cmUgaWRlbnRpZmllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gVGhlIGZlYXR1cmUgKG9yIGBudWxsYCBpZiBub3QgZm91bmQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRGZWF0dXJlQnlJZCA9IGZ1bmN0aW9uIChpZCkge1xuICAgIHZhciBmZWF0dXJlID0gdGhpcy5pZEluZGV4X1tpZC50b1N0cmluZygpXTtcbiAgICByZXR1cm4gZmVhdHVyZSAhPT0gdW5kZWZpbmVkID8gZmVhdHVyZSA6IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgYSBmZWF0dXJlIGJ5IGl0cyBpbnRlcm5hbCB1bmlxdWUgaWRlbnRpZmllciAodXNpbmcgYGdldFVpZGApLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdWlkIEZlYXR1cmUgaWRlbnRpZmllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0PEdlb21ldHJ5Pn0gVGhlIGZlYXR1cmUgKG9yIGBudWxsYCBpZiBub3QgZm91bmQpLlxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0RmVhdHVyZUJ5VWlkID0gZnVuY3Rpb24gKHVpZCkge1xuICAgIHZhciBmZWF0dXJlID0gdGhpcy51aWRJbmRleF9bdWlkXTtcbiAgICByZXR1cm4gZmVhdHVyZSAhPT0gdW5kZWZpbmVkID8gZmVhdHVyZSA6IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZvcm1hdCBhc3NvY2lhdGVkIHdpdGggdGhpcyBzb3VyY2UuXG4gICAqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBUaGUgZmVhdHVyZSBmb3JtYXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLmdldEZvcm1hdCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtYXRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNvdXJjZSBjYW4gaGF2ZSBvdmVybGFwcGluZyBnZW9tZXRyaWVzLlxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuZ2V0T3ZlcmxhcHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub3ZlcmxhcHNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB1cmwgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc291cmNlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd8aW1wb3J0KFwiLi4vZmVhdHVyZWxvYWRlci5qc1wiKS5GZWF0dXJlVXJsRnVuY3Rpb258dW5kZWZpbmVkfSBUaGUgdXJsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5nZXRVcmwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudXJsXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IEV2ZW50LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUuaGFuZGxlRmVhdHVyZUNoYW5nZV8gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgZmVhdHVyZSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSAqL1xuICAgIGV2ZW50LnRhcmdldDtcbiAgICB2YXIgZmVhdHVyZUtleSA9IGdldFVpZChmZWF0dXJlKTtcbiAgICB2YXIgZ2VvbWV0cnkgPSBmZWF0dXJlLmdldEdlb21ldHJ5KCk7XG5cbiAgICBpZiAoIWdlb21ldHJ5KSB7XG4gICAgICBpZiAoIShmZWF0dXJlS2V5IGluIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKSkge1xuICAgICAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8ucmVtb3ZlKGZlYXR1cmUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc19bZmVhdHVyZUtleV0gPSBmZWF0dXJlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZXh0ZW50ID0gZ2VvbWV0cnkuZ2V0RXh0ZW50KCk7XG5cbiAgICAgIGlmIChmZWF0dXJlS2V5IGluIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm51bGxHZW9tZXRyeUZlYXR1cmVzX1tmZWF0dXJlS2V5XTtcblxuICAgICAgICBpZiAodGhpcy5mZWF0dXJlc1J0cmVlXykge1xuICAgICAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8uaW5zZXJ0KGV4dGVudCwgZmVhdHVyZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgICAgdGhpcy5mZWF0dXJlc1J0cmVlXy51cGRhdGUoZXh0ZW50LCBmZWF0dXJlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBpZCA9IGZlYXR1cmUuZ2V0SWQoKTtcblxuICAgIGlmIChpZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgc2lkID0gaWQudG9TdHJpbmcoKTtcblxuICAgICAgaWYgKHRoaXMuaWRJbmRleF9bc2lkXSAhPT0gZmVhdHVyZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUZyb21JZEluZGV4XyhmZWF0dXJlKTtcbiAgICAgICAgdGhpcy5pZEluZGV4X1tzaWRdID0gZmVhdHVyZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZW1vdmVGcm9tSWRJbmRleF8oZmVhdHVyZSk7XG4gICAgICB0aGlzLnVpZEluZGV4X1tmZWF0dXJlS2V5XSA9IGZlYXR1cmU7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgdGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBWZWN0b3JTb3VyY2VFdmVudChWZWN0b3JFdmVudFR5cGUuQ0hBTkdFRkVBVFVSRSwgZmVhdHVyZSkpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBmZWF0dXJlIGlzIGNvbnRhaW5lZCB3aXRoaW4gdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEhhcyBmZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5oYXNGZWF0dXJlID0gZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICB2YXIgaWQgPSBmZWF0dXJlLmdldElkKCk7XG5cbiAgICBpZiAoaWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGlkIGluIHRoaXMuaWRJbmRleF87XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBnZXRVaWQoZmVhdHVyZSkgaW4gdGhpcy51aWRJbmRleF87XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gSXMgZW1wdHkuXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVzUnRyZWVfLmlzRW1wdHkoKSAmJiBpc0VtcHR5KHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIFZlY3RvclNvdXJjZS5wcm90b3R5cGUubG9hZEZlYXR1cmVzID0gZnVuY3Rpb24gKGV4dGVudCwgcmVzb2x1dGlvbiwgcHJvamVjdGlvbikge1xuICAgIHZhciBsb2FkZWRFeHRlbnRzUnRyZWUgPSB0aGlzLmxvYWRlZEV4dGVudHNSdHJlZV87XG4gICAgdmFyIGV4dGVudHNUb0xvYWQgPSB0aGlzLnN0cmF0ZWd5XyhleHRlbnQsIHJlc29sdXRpb24pO1xuICAgIHRoaXMubG9hZGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiBfbG9vcF8xKGksIGlpKSB7XG4gICAgICB2YXIgZXh0ZW50VG9Mb2FkID0gZXh0ZW50c1RvTG9hZFtpXTtcbiAgICAgIHZhciBhbHJlYWR5TG9hZGVkID0gbG9hZGVkRXh0ZW50c1J0cmVlLmZvckVhY2hJbkV4dGVudChleHRlbnRUb0xvYWQsXG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7e2V4dGVudDogaW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH19IG9iamVjdCBPYmplY3QuXG4gICAgICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucy5cbiAgICAgICAqL1xuICAgICAgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgICAgICByZXR1cm4gY29udGFpbnNFeHRlbnQob2JqZWN0LmV4dGVudCwgZXh0ZW50VG9Mb2FkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIWFscmVhZHlMb2FkZWQpIHtcbiAgICAgICAgdGhpc18xLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5GRUFUVVJFU0xPQURTVEFSVCkpO1xuICAgICAgICB0aGlzXzEubG9hZGVyXy5jYWxsKHRoaXNfMSwgZXh0ZW50VG9Mb2FkLCByZXNvbHV0aW9uLCBwcm9qZWN0aW9uLCBmdW5jdGlvbiAoZmVhdHVyZXMpIHtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5GRUFUVVJFU0xPQURFTkQsIHVuZGVmaW5lZCwgZmVhdHVyZXMpKTtcbiAgICAgICAgfS5iaW5kKHRoaXNfMSksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5GRUFUVVJFU0xPQURFUlJPUikpO1xuICAgICAgICB9LmJpbmQodGhpc18xKSk7XG4gICAgICAgIGxvYWRlZEV4dGVudHNSdHJlZS5pbnNlcnQoZXh0ZW50VG9Mb2FkLCB7XG4gICAgICAgICAgZXh0ZW50OiBleHRlbnRUb0xvYWQuc2xpY2UoKVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpc18xLmxvYWRpbmcgPSB0aGlzXzEubG9hZGVyXyAhPT0gVk9JRDtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHRoaXNfMSA9IHRoaXM7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBleHRlbnRzVG9Mb2FkLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIF9sb29wXzEoaSwgaWkpO1xuICAgIH1cbiAgfTtcblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jbGVhcih0cnVlKTtcbiAgICB0aGlzLmxvYWRlZEV4dGVudHNSdHJlZV8uY2xlYXIoKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUucmVmcmVzaC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGFuIGV4dGVudCBmcm9tIHRoZSBsaXN0IG9mIGxvYWRlZCBleHRlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnJlbW92ZUxvYWRlZEV4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICB2YXIgbG9hZGVkRXh0ZW50c1J0cmVlID0gdGhpcy5sb2FkZWRFeHRlbnRzUnRyZWVfO1xuICAgIHZhciBvYmo7XG4gICAgbG9hZGVkRXh0ZW50c1J0cmVlLmZvckVhY2hJbkV4dGVudChleHRlbnQsIGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgIGlmIChlcXVhbHMob2JqZWN0LmV4dGVudCwgZXh0ZW50KSkge1xuICAgICAgICBvYmogPSBvYmplY3Q7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKG9iaikge1xuICAgICAgbG9hZGVkRXh0ZW50c1J0cmVlLnJlbW92ZShvYmopO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhIHNpbmdsZSBmZWF0dXJlIGZyb20gdGhlIHNvdXJjZS4gIElmIHlvdSB3YW50IHRvIHJlbW92ZSBhbGwgZmVhdHVyZXNcbiAgICogYXQgb25jZSwgdXNlIHRoZSB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3J+VmVjdG9yU291cmNlI2NsZWFyICNjbGVhcigpfSBtZXRob2RcbiAgICogaW5zdGVhZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIEZlYXR1cmUgdG8gcmVtb3ZlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5yZW1vdmVGZWF0dXJlID0gZnVuY3Rpb24gKGZlYXR1cmUpIHtcbiAgICB2YXIgZmVhdHVyZUtleSA9IGdldFVpZChmZWF0dXJlKTtcblxuICAgIGlmIChmZWF0dXJlS2V5IGluIHRoaXMubnVsbEdlb21ldHJ5RmVhdHVyZXNfKSB7XG4gICAgICBkZWxldGUgdGhpcy5udWxsR2VvbWV0cnlGZWF0dXJlc19bZmVhdHVyZUtleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmZlYXR1cmVzUnRyZWVfKSB7XG4gICAgICAgIHRoaXMuZmVhdHVyZXNSdHJlZV8ucmVtb3ZlKGZlYXR1cmUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucmVtb3ZlRmVhdHVyZUludGVybmFsKGZlYXR1cmUpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogUmVtb3ZlIGZlYXR1cmUgd2l0aG91dCBmaXJpbmcgYSBgY2hhbmdlYCBldmVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ8R2VvbWV0cnk+fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBWZWN0b3JTb3VyY2UucHJvdG90eXBlLnJlbW92ZUZlYXR1cmVJbnRlcm5hbCA9IGZ1bmN0aW9uIChmZWF0dXJlKSB7XG4gICAgdmFyIGZlYXR1cmVLZXkgPSBnZXRVaWQoZmVhdHVyZSk7XG4gICAgdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c19bZmVhdHVyZUtleV0uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICBkZWxldGUgdGhpcy5mZWF0dXJlQ2hhbmdlS2V5c19bZmVhdHVyZUtleV07XG4gICAgdmFyIGlkID0gZmVhdHVyZS5nZXRJZCgpO1xuXG4gICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmlkSW5kZXhfW2lkLnRvU3RyaW5nKCldO1xuICAgIH1cblxuICAgIGRlbGV0ZSB0aGlzLnVpZEluZGV4X1tmZWF0dXJlS2V5XTtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnQobmV3IFZlY3RvclNvdXJjZUV2ZW50KFZlY3RvckV2ZW50VHlwZS5SRU1PVkVGRUFUVVJFLCBmZWF0dXJlKSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgYSBmZWF0dXJlIGZyb20gdGhlIGlkIGluZGV4LiAgQ2FsbGVkIGludGVybmFsbHkgd2hlbiB0aGUgZmVhdHVyZSBpZFxuICAgKiBtYXkgaGF2ZSBjaGFuZ2VkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdDxHZW9tZXRyeT59IGZlYXR1cmUgVGhlIGZlYXR1cmUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFJlbW92ZWQgdGhlIGZlYXR1cmUgZnJvbSB0aGUgaW5kZXguXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5yZW1vdmVGcm9tSWRJbmRleF8gPSBmdW5jdGlvbiAoZmVhdHVyZSkge1xuICAgIHZhciByZW1vdmVkID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpZCBpbiB0aGlzLmlkSW5kZXhfKSB7XG4gICAgICBpZiAodGhpcy5pZEluZGV4X1tpZF0gPT09IGZlYXR1cmUpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuaWRJbmRleF9baWRdO1xuICAgICAgICByZW1vdmVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlbW92ZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG5ldyBsb2FkZXIgb2YgdGhlIHNvdXJjZS4gVGhlIG5leHQgcmVuZGVyIGN5Y2xlIHdpbGwgdXNlIHRoZVxuICAgKiBuZXcgbG9hZGVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZUxvYWRlcn0gbG9hZGVyIFRoZSBsb2FkZXIgdG8gc2V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5zZXRMb2FkZXIgPSBmdW5jdGlvbiAobG9hZGVyKSB7XG4gICAgdGhpcy5sb2FkZXJfID0gbG9hZGVyO1xuICB9O1xuICAvKipcbiAgICogUG9pbnRzIHRoZSBzb3VyY2UgdG8gYSBuZXcgdXJsLiBUaGUgbmV4dCByZW5kZXIgY3ljbGUgd2lsbCB1c2UgdGhlIG5ldyB1cmwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfGltcG9ydChcIi4uL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZVVybEZ1bmN0aW9ufSB1cmwgVXJsLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yU291cmNlLnByb3RvdHlwZS5zZXRVcmwgPSBmdW5jdGlvbiAodXJsKSB7XG4gICAgYXNzZXJ0KHRoaXMuZm9ybWF0XywgNyk7IC8vIGBmb3JtYXRgIG11c3QgYmUgc2V0IHdoZW4gYHVybGAgaXMgc2V0XG5cbiAgICB0aGlzLnNldExvYWRlcih4aHIodXJsLCB0aGlzLmZvcm1hdF8pKTtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yU291cmNlO1xufShTb3VyY2UpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JTb3VyY2U7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3N0eWxlL1RleHRcbiAqL1xuaW1wb3J0IEZpbGwgZnJvbSAnLi9GaWxsLmpzJztcbmltcG9ydCBUZXh0UGxhY2VtZW50IGZyb20gJy4vVGV4dFBsYWNlbWVudC5qcyc7XG5pbXBvcnQgeyB0b1NpemUgfSBmcm9tICcuLi9zaXplLmpzJztcbi8qKlxuICogVGhlIGRlZmF1bHQgZmlsbCBjb2xvciB0byB1c2UgaWYgbm8gZmlsbCB3YXMgc2V0IGF0IGNvbnN0cnVjdGlvbiB0aW1lOyBhXG4gKiBibGFja2lzaCBgIzMzM2AuXG4gKlxuICogQGNvbnN0IHtzdHJpbmd9XG4gKi9cblxudmFyIERFRkFVTFRfRklMTF9DT0xPUiA9ICcjMzMzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtmb250XSBGb250IHN0eWxlIGFzIENTUyAnZm9udCcgdmFsdWUsIHNlZTpcbiAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9DYW52YXNSZW5kZXJpbmdDb250ZXh0MkQvZm9udC4gRGVmYXVsdCBpcyAnMTBweCBzYW5zLXNlcmlmJ1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhBbmdsZT1NYXRoLlBJLzRdIFdoZW4gYHBsYWNlbWVudGAgaXMgc2V0IHRvIGAnbGluZSdgLCBhbGxvdyBhIG1heGltdW0gYW5nbGUgYmV0d2VlbiBhZGphY2VudCBjaGFyYWN0ZXJzLlxuICogVGhlIGV4cGVjdGVkIHZhbHVlIGlzIGluIHJhZGlhbnMsIGFuZCB0aGUgZGVmYXVsdCBpcyA0NcKwIChgTWF0aC5QSSAvIDRgKS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbb2Zmc2V0WD0wXSBIb3Jpem9udGFsIHRleHQgb2Zmc2V0IGluIHBpeGVscy4gQSBwb3NpdGl2ZSB3aWxsIHNoaWZ0IHRoZSB0ZXh0IHJpZ2h0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtvZmZzZXRZPTBdIFZlcnRpY2FsIHRleHQgb2Zmc2V0IGluIHBpeGVscy4gQSBwb3NpdGl2ZSB3aWxsIHNoaWZ0IHRoZSB0ZXh0IGRvd24uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvdmVyZmxvdz1mYWxzZV0gRm9yIHBvbHlnb24gbGFiZWxzIG9yIHdoZW4gYHBsYWNlbWVudGAgaXMgc2V0IHRvIGAnbGluZSdgLCBhbGxvdyB0ZXh0IHRvIGV4Y2VlZFxuICogdGhlIHdpZHRoIG9mIHRoZSBwb2x5Z29uIGF0IHRoZSBsYWJlbCBwb3NpdGlvbiBvciB0aGUgbGVuZ3RoIG9mIHRoZSBwYXRoIHRoYXQgaXQgZm9sbG93cy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9UZXh0UGxhY2VtZW50LmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBbcGxhY2VtZW50PSdwb2ludCddIFRleHQgcGxhY2VtZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBbc2NhbGVdIFNjYWxlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbcm90YXRlV2l0aFZpZXc9ZmFsc2VdIFdoZXRoZXIgdG8gcm90YXRlIHRoZSB0ZXh0IHdpdGggdGhlIHZpZXcuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JvdGF0aW9uPTBdIFJvdGF0aW9uIGluIHJhZGlhbnMgKHBvc2l0aXZlIHJvdGF0aW9uIGNsb2Nrd2lzZSkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3RleHRdIFRleHQgY29udGVudC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdGV4dEFsaWduXSBUZXh0IGFsaWdubWVudC4gUG9zc2libGUgdmFsdWVzOiAnbGVmdCcsICdyaWdodCcsICdjZW50ZXInLCAnZW5kJyBvciAnc3RhcnQnLlxuICogRGVmYXVsdCBpcyAnY2VudGVyJyBmb3IgYHBsYWNlbWVudDogJ3BvaW50J2AuIEZvciBgcGxhY2VtZW50OiAnbGluZSdgLCB0aGUgZGVmYXVsdCBpcyB0byBsZXQgdGhlIHJlbmRlcmVyIGNob29zZSBhXG4gKiBwbGFjZW1lbnQgd2hlcmUgYG1heEFuZ2xlYCBpcyBub3QgZXhjZWVkZWQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3RleHRCYXNlbGluZT0nbWlkZGxlJ10gVGV4dCBiYXNlIGxpbmUuIFBvc3NpYmxlIHZhbHVlczogJ2JvdHRvbScsICd0b3AnLCAnbWlkZGxlJywgJ2FscGhhYmV0aWMnLFxuICogJ2hhbmdpbmcnLCAnaWRlb2dyYXBoaWMnLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gW2ZpbGxdIEZpbGwgc3R5bGUuIElmIG5vbmUgaXMgcHJvdmlkZWQsIHdlJ2xsIHVzZSBhIGRhcmsgZmlsbC1zdHlsZSAoIzMzMykuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IFtzdHJva2VdIFN0cm9rZSBzdHlsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IFtiYWNrZ3JvdW5kRmlsbF0gRmlsbCBzdHlsZSBmb3IgdGhlIHRleHQgYmFja2dyb3VuZCB3aGVuIGBwbGFjZW1lbnRgIGlzXG4gKiBgJ3BvaW50J2AuIERlZmF1bHQgaXMgbm8gZmlsbC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gW2JhY2tncm91bmRTdHJva2VdIFN0cm9rZSBzdHlsZSBmb3IgdGhlIHRleHQgYmFja2dyb3VuZCAgd2hlbiBgcGxhY2VtZW50YFxuICogaXMgYCdwb2ludCdgLiBEZWZhdWx0IGlzIG5vIHN0cm9rZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW3BhZGRpbmc9WzAsIDAsIDAsIDBdXSBQYWRkaW5nIGluIHBpeGVscyBhcm91bmQgdGhlIHRleHQgZm9yIGRlY2x1dHRlcmluZyBhbmQgYmFja2dyb3VuZC4gVGhlIG9yZGVyIG9mXG4gKiB2YWx1ZXMgaW4gdGhlIGFycmF5IGlzIGBbdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XWAuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBTZXQgdGV4dCBzdHlsZSBmb3IgdmVjdG9yIGZlYXR1cmVzLlxuICogQGFwaVxuICovXG5cbnZhciBUZXh0ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gICAqL1xuICBmdW5jdGlvbiBUZXh0KG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5mb250XyA9IG9wdGlvbnMuZm9udDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5yb3RhdGlvbl8gPSBvcHRpb25zLnJvdGF0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW58dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5yb3RhdGVXaXRoVmlld18gPSBvcHRpb25zLnJvdGF0ZVdpdGhWaWV3O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5zY2FsZV8gPSBvcHRpb25zLnNjYWxlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIHRoaXMuc2NhbGVBcnJheV8gPSB0b1NpemUob3B0aW9ucy5zY2FsZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zY2FsZSA6IDEpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLnRleHRfID0gb3B0aW9ucy50ZXh0O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLnRleHRBbGlnbl8gPSBvcHRpb25zLnRleHRBbGlnbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy50ZXh0QmFzZWxpbmVfID0gb3B0aW9ucy50ZXh0QmFzZWxpbmU7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICB0aGlzLmZpbGxfID0gb3B0aW9ucy5maWxsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmZpbGwgOiBuZXcgRmlsbCh7XG4gICAgICBjb2xvcjogREVGQVVMVF9GSUxMX0NPTE9SXG4gICAgfSk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5tYXhBbmdsZV8gPSBvcHRpb25zLm1heEFuZ2xlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heEFuZ2xlIDogTWF0aC5QSSAvIDQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9UZXh0UGxhY2VtZW50LmpzXCIpLmRlZmF1bHR8c3RyaW5nfVxuICAgICAqL1xuXG4gICAgdGhpcy5wbGFjZW1lbnRfID0gb3B0aW9ucy5wbGFjZW1lbnQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGxhY2VtZW50IDogVGV4dFBsYWNlbWVudC5QT0lOVDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgdGhpcy5vdmVyZmxvd18gPSAhIW9wdGlvbnMub3ZlcmZsb3c7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuc3Ryb2tlXyA9IG9wdGlvbnMuc3Ryb2tlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnN0cm9rZSA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5vZmZzZXRYXyA9IG9wdGlvbnMub2Zmc2V0WCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vZmZzZXRYIDogMDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm9mZnNldFlfID0gb3B0aW9ucy5vZmZzZXRZICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm9mZnNldFkgOiAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vRmlsbC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgdGhpcy5iYWNrZ3JvdW5kRmlsbF8gPSBvcHRpb25zLmJhY2tncm91bmRGaWxsID8gb3B0aW9ucy5iYWNrZ3JvdW5kRmlsbCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuYmFja2dyb3VuZFN0cm9rZV8gPSBvcHRpb25zLmJhY2tncm91bmRTdHJva2UgPyBvcHRpb25zLmJhY2tncm91bmRTdHJva2UgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLnBhZGRpbmdfID0gb3B0aW9ucy5wYWRkaW5nID09PSB1bmRlZmluZWQgPyBudWxsIDogb3B0aW9ucy5wYWRkaW5nO1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZXMgdGhlIHN0eWxlLlxuICAgKiBAcmV0dXJuIHtUZXh0fSBUaGUgY2xvbmVkIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNjYWxlID0gdGhpcy5nZXRTY2FsZSgpO1xuICAgIHJldHVybiBuZXcgVGV4dCh7XG4gICAgICBmb250OiB0aGlzLmdldEZvbnQoKSxcbiAgICAgIHBsYWNlbWVudDogdGhpcy5nZXRQbGFjZW1lbnQoKSxcbiAgICAgIG1heEFuZ2xlOiB0aGlzLmdldE1heEFuZ2xlKCksXG4gICAgICBvdmVyZmxvdzogdGhpcy5nZXRPdmVyZmxvdygpLFxuICAgICAgcm90YXRpb246IHRoaXMuZ2V0Um90YXRpb24oKSxcbiAgICAgIHJvdGF0ZVdpdGhWaWV3OiB0aGlzLmdldFJvdGF0ZVdpdGhWaWV3KCksXG4gICAgICBzY2FsZTogQXJyYXkuaXNBcnJheShzY2FsZSkgPyBzY2FsZS5zbGljZSgpIDogc2NhbGUsXG4gICAgICB0ZXh0OiB0aGlzLmdldFRleHQoKSxcbiAgICAgIHRleHRBbGlnbjogdGhpcy5nZXRUZXh0QWxpZ24oKSxcbiAgICAgIHRleHRCYXNlbGluZTogdGhpcy5nZXRUZXh0QmFzZWxpbmUoKSxcbiAgICAgIGZpbGw6IHRoaXMuZ2V0RmlsbCgpID8gdGhpcy5nZXRGaWxsKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIHN0cm9rZTogdGhpcy5nZXRTdHJva2UoKSA/IHRoaXMuZ2V0U3Ryb2tlKCkuY2xvbmUoKSA6IHVuZGVmaW5lZCxcbiAgICAgIG9mZnNldFg6IHRoaXMuZ2V0T2Zmc2V0WCgpLFxuICAgICAgb2Zmc2V0WTogdGhpcy5nZXRPZmZzZXRZKCksXG4gICAgICBiYWNrZ3JvdW5kRmlsbDogdGhpcy5nZXRCYWNrZ3JvdW5kRmlsbCgpID8gdGhpcy5nZXRCYWNrZ3JvdW5kRmlsbCgpLmNsb25lKCkgOiB1bmRlZmluZWQsXG4gICAgICBiYWNrZ3JvdW5kU3Ryb2tlOiB0aGlzLmdldEJhY2tncm91bmRTdHJva2UoKSA/IHRoaXMuZ2V0QmFja2dyb3VuZFN0cm9rZSgpLmNsb25lKCkgOiB1bmRlZmluZWQsXG4gICAgICBwYWRkaW5nOiB0aGlzLmdldFBhZGRpbmcoKVxuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBgb3ZlcmZsb3dgIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IExldCB0ZXh0IG92ZXJmbG93IHRoZSBsZW5ndGggb2YgdGhlIHBhdGggdGhleSBmb2xsb3cuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRPdmVyZmxvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vdmVyZmxvd187XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZvbnQgbmFtZS5cbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gRm9udC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldEZvbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9udF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1heGltdW0gYW5nbGUgYmV0d2VlbiBhZGphY2VudCBjaGFyYWN0ZXJzLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIGluIHJhZGlhbnMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRNYXhBbmdsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXhBbmdsZV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGxhYmVsIHBsYWNlbWVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9UZXh0UGxhY2VtZW50LmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBUZXh0IHBsYWNlbWVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldFBsYWNlbWVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5wbGFjZW1lbnRfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSB4LW9mZnNldCBmb3IgdGhlIHRleHQuXG4gICAqIEByZXR1cm4ge251bWJlcn0gSG9yaXpvbnRhbCB0ZXh0IG9mZnNldC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldE9mZnNldFggPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub2Zmc2V0WF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHktb2Zmc2V0IGZvciB0aGUgdGV4dC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBWZXJ0aWNhbCB0ZXh0IG9mZnNldC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldE9mZnNldFkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub2Zmc2V0WV87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZpbGwgc3R5bGUgZm9yIHRoZSB0ZXh0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gRmlsbCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldEZpbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsbF87XG4gIH07XG4gIC8qKlxuICAgKiBEZXRlcm1pbmUgd2hldGhlciB0aGUgdGV4dCByb3RhdGVzIHdpdGggdGhlIG1hcC5cbiAgICogQHJldHVybiB7Ym9vbGVhbnx1bmRlZmluZWR9IFJvdGF0ZSB3aXRoIG1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldFJvdGF0ZVdpdGhWaWV3ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnJvdGF0ZVdpdGhWaWV3XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGV4dCByb3RhdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gUm90YXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRSb3RhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yb3RhdGlvbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRleHQgc2NhbGUuXG4gICAqIEByZXR1cm4ge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV8dW5kZWZpbmVkfSBTY2FsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldFNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnNjYWxlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgc3ltYm9saXplciBzY2FsZSBhcnJheS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBTY2FsZSBhcnJheS5cbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRTY2FsZUFycmF5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnNjYWxlQXJyYXlfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBzdHJva2Ugc3R5bGUgZm9yIHRoZSB0ZXh0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1N0cm9rZS5qc1wiKS5kZWZhdWx0fSBTdHJva2Ugc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRTdHJva2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3Ryb2tlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGV4dCB0byBiZSByZW5kZXJlZC5cbiAgICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGV4dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLmdldFRleHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGV4dF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRleHQgYWxpZ25tZW50LlxuICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUZXh0IGFsaWduLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuZ2V0VGV4dEFsaWduID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRleHRBbGlnbl87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRleHQgYmFzZWxpbmUuXG4gICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IFRleHQgYmFzZWxpbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRUZXh0QmFzZWxpbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGV4dEJhc2VsaW5lXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgYmFja2dyb3VuZCBmaWxsIHN0eWxlIGZvciB0aGUgdGV4dC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IEZpbGwgc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRCYWNrZ3JvdW5kRmlsbCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5iYWNrZ3JvdW5kRmlsbF87XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGJhY2tncm91bmQgc3Ryb2tlIHN0eWxlIGZvciB0aGUgdGV4dC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9TdHJva2UuanNcIikuZGVmYXVsdH0gU3Ryb2tlIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuZ2V0QmFja2dyb3VuZFN0cm9rZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5iYWNrZ3JvdW5kU3Ryb2tlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgcGFkZGluZyBmb3IgdGhlIHRleHQuXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFBhZGRpbmcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5nZXRQYWRkaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnBhZGRpbmdfO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBgb3ZlcmZsb3dgIHByb3BlcnR5LlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IG92ZXJmbG93IExldCB0ZXh0IG92ZXJmbG93IHRoZSBwYXRoIHRoYXQgaXQgZm9sbG93cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldE92ZXJmbG93ID0gZnVuY3Rpb24gKG92ZXJmbG93KSB7XG4gICAgdGhpcy5vdmVyZmxvd18gPSBvdmVyZmxvdztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZm9udC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSBmb250IEZvbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRGb250ID0gZnVuY3Rpb24gKGZvbnQpIHtcbiAgICB0aGlzLmZvbnRfID0gZm9udDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbWF4aW11bSBhbmdsZSBiZXR3ZWVuIGFkamFjZW50IGNoYXJhY3RlcnMuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhBbmdsZSBBbmdsZSBpbiByYWRpYW5zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuc2V0TWF4QW5nbGUgPSBmdW5jdGlvbiAobWF4QW5nbGUpIHtcbiAgICB0aGlzLm1heEFuZ2xlXyA9IG1heEFuZ2xlO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB4IG9mZnNldC5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFggSG9yaXpvbnRhbCB0ZXh0IG9mZnNldC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldE9mZnNldFggPSBmdW5jdGlvbiAob2Zmc2V0WCkge1xuICAgIHRoaXMub2Zmc2V0WF8gPSBvZmZzZXRYO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB5IG9mZnNldC5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFkgVmVydGljYWwgdGV4dCBvZmZzZXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRPZmZzZXRZID0gZnVuY3Rpb24gKG9mZnNldFkpIHtcbiAgICB0aGlzLm9mZnNldFlfID0gb2Zmc2V0WTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdGV4dCBwbGFjZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UZXh0UGxhY2VtZW50LmpzXCIpLmRlZmF1bHR8c3RyaW5nfSBwbGFjZW1lbnQgUGxhY2VtZW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuc2V0UGxhY2VtZW50ID0gZnVuY3Rpb24gKHBsYWNlbWVudCkge1xuICAgIHRoaXMucGxhY2VtZW50XyA9IHBsYWNlbWVudDtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB3aGV0aGVyIHRvIHJvdGF0ZSB0aGUgdGV4dCB3aXRoIHRoZSB2aWV3LlxuICAgKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHJvdGF0ZVdpdGhWaWV3IFJvdGF0ZSB3aXRoIG1hcC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldFJvdGF0ZVdpdGhWaWV3ID0gZnVuY3Rpb24gKHJvdGF0ZVdpdGhWaWV3KSB7XG4gICAgdGhpcy5yb3RhdGVXaXRoVmlld18gPSByb3RhdGVXaXRoVmlldztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgZmlsbC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZpbGwuanNcIikuZGVmYXVsdH0gZmlsbCBGaWxsIHN0eWxlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuc2V0RmlsbCA9IGZ1bmN0aW9uIChmaWxsKSB7XG4gICAgdGhpcy5maWxsXyA9IGZpbGw7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHJvdGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcnx1bmRlZmluZWR9IHJvdGF0aW9uIFJvdGF0aW9uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGV4dC5wcm90b3R5cGUuc2V0Um90YXRpb24gPSBmdW5jdGlvbiAocm90YXRpb24pIHtcbiAgICB0aGlzLnJvdGF0aW9uXyA9IHJvdGF0aW9uO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzY2FsZS5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfHVuZGVmaW5lZH0gc2NhbGUgU2NhbGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRTY2FsZSA9IGZ1bmN0aW9uIChzY2FsZSkge1xuICAgIHRoaXMuc2NhbGVfID0gc2NhbGU7XG4gICAgdGhpcy5zY2FsZUFycmF5XyA9IHRvU2l6ZShzY2FsZSAhPT0gdW5kZWZpbmVkID8gc2NhbGUgOiAxKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgc3Ryb2tlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IHN0cm9rZSBTdHJva2Ugc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRTdHJva2UgPSBmdW5jdGlvbiAoc3Ryb2tlKSB7XG4gICAgdGhpcy5zdHJva2VfID0gc3Ryb2tlO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB0ZXh0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHRleHQgVGV4dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xuICAgIHRoaXMudGV4dF8gPSB0ZXh0O1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSB0ZXh0IGFsaWdubWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd8dW5kZWZpbmVkfSB0ZXh0QWxpZ24gVGV4dCBhbGlnbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldFRleHRBbGlnbiA9IGZ1bmN0aW9uICh0ZXh0QWxpZ24pIHtcbiAgICB0aGlzLnRleHRBbGlnbl8gPSB0ZXh0QWxpZ247XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHRleHQgYmFzZWxpbmUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gdGV4dEJhc2VsaW5lIFRleHQgYmFzZWxpbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRUZXh0QmFzZWxpbmUgPSBmdW5jdGlvbiAodGV4dEJhc2VsaW5lKSB7XG4gICAgdGhpcy50ZXh0QmFzZWxpbmVfID0gdGV4dEJhc2VsaW5lO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBiYWNrZ3JvdW5kIGZpbGwuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GaWxsLmpzXCIpLmRlZmF1bHR9IGZpbGwgRmlsbCBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRleHQucHJvdG90eXBlLnNldEJhY2tncm91bmRGaWxsID0gZnVuY3Rpb24gKGZpbGwpIHtcbiAgICB0aGlzLmJhY2tncm91bmRGaWxsXyA9IGZpbGw7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGJhY2tncm91bmQgc3Ryb2tlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vU3Ryb2tlLmpzXCIpLmRlZmF1bHR9IHN0cm9rZSBTdHJva2Ugc3R5bGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRCYWNrZ3JvdW5kU3Ryb2tlID0gZnVuY3Rpb24gKHN0cm9rZSkge1xuICAgIHRoaXMuYmFja2dyb3VuZFN0cm9rZV8gPSBzdHJva2U7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhZGRpbmcgKGBbdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XWApLlxuICAgKlxuICAgKiBAcGFyYW0geyFBcnJheTxudW1iZXI+fSBwYWRkaW5nIFBhZGRpbmcuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUZXh0LnByb3RvdHlwZS5zZXRQYWRkaW5nID0gZnVuY3Rpb24gKHBhZGRpbmcpIHtcbiAgICB0aGlzLnBhZGRpbmdfID0gcGFkZGluZztcbiAgfTtcblxuICByZXR1cm4gVGV4dDtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgVGV4dDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9mbGF0L2ludGVycG9sYXRlXG4gKi9cbmltcG9ydCB7IGJpbmFyeVNlYXJjaCB9IGZyb20gJy4uLy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGxlcnAgfSBmcm9tICcuLi8uLi9tYXRoLmpzJztcbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcmFjdGlvbiBGcmFjdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9kZXN0IERlc3RpbmF0aW9uLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERlc3RpbmF0aW9uIGRpbWVuc2lvbiAoZGVmYXVsdCBpcyBgMmApXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBEZXN0aW5hdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJwb2xhdGVQb2ludChmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kLCBzdHJpZGUsIGZyYWN0aW9uLCBvcHRfZGVzdCwgb3B0X2RpbWVuc2lvbikge1xuICB2YXIgbywgdDtcbiAgdmFyIG4gPSAoZW5kIC0gb2Zmc2V0KSAvIHN0cmlkZTtcblxuICBpZiAobiA9PT0gMSkge1xuICAgIG8gPSBvZmZzZXQ7XG4gIH0gZWxzZSBpZiAobiA9PT0gMikge1xuICAgIG8gPSBvZmZzZXQ7XG4gICAgdCA9IGZyYWN0aW9uO1xuICB9IGVsc2UgaWYgKG4gIT09IDApIHtcbiAgICB2YXIgeDEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0XTtcbiAgICB2YXIgeTEgPSBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV07XG4gICAgdmFyIGxlbmd0aF8xID0gMDtcbiAgICB2YXIgY3VtdWxhdGl2ZUxlbmd0aHMgPSBbMF07XG5cbiAgICBmb3IgKHZhciBpID0gb2Zmc2V0ICsgc3RyaWRlOyBpIDwgZW5kOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmFyIHgyID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdmFyIHkyID0gZmxhdENvb3JkaW5hdGVzW2kgKyAxXTtcbiAgICAgIGxlbmd0aF8xICs9IE1hdGguc3FydCgoeDIgLSB4MSkgKiAoeDIgLSB4MSkgKyAoeTIgLSB5MSkgKiAoeTIgLSB5MSkpO1xuICAgICAgY3VtdWxhdGl2ZUxlbmd0aHMucHVzaChsZW5ndGhfMSk7XG4gICAgICB4MSA9IHgyO1xuICAgICAgeTEgPSB5MjtcbiAgICB9XG5cbiAgICB2YXIgdGFyZ2V0ID0gZnJhY3Rpb24gKiBsZW5ndGhfMTtcbiAgICB2YXIgaW5kZXggPSBiaW5hcnlTZWFyY2goY3VtdWxhdGl2ZUxlbmd0aHMsIHRhcmdldCk7XG5cbiAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICB0ID0gKHRhcmdldCAtIGN1bXVsYXRpdmVMZW5ndGhzWy1pbmRleCAtIDJdKSAvIChjdW11bGF0aXZlTGVuZ3Roc1staW5kZXggLSAxXSAtIGN1bXVsYXRpdmVMZW5ndGhzWy1pbmRleCAtIDJdKTtcbiAgICAgIG8gPSBvZmZzZXQgKyAoLWluZGV4IC0gMikgKiBzdHJpZGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG8gPSBvZmZzZXQgKyBpbmRleCAqIHN0cmlkZTtcbiAgICB9XG4gIH1cblxuICB2YXIgZGltZW5zaW9uID0gb3B0X2RpbWVuc2lvbiA+IDEgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgdmFyIGRlc3QgPSBvcHRfZGVzdCA/IG9wdF9kZXN0IDogbmV3IEFycmF5KGRpbWVuc2lvbik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBkaW1lbnNpb247ICsraSkge1xuICAgIGRlc3RbaV0gPSBvID09PSB1bmRlZmluZWQgPyBOYU4gOiB0ID09PSB1bmRlZmluZWQgPyBmbGF0Q29vcmRpbmF0ZXNbbyArIGldIDogbGVycChmbGF0Q29vcmRpbmF0ZXNbbyArIGldLCBmbGF0Q29vcmRpbmF0ZXNbbyArIHN0cmlkZSArIGldLCB0KTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kIEVuZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGxpbmVTdHJpbmdDb29yZGluYXRlQXRNKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbSwgZXh0cmFwb2xhdGUpIHtcbiAgaWYgKGVuZCA9PSBvZmZzZXQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChtIDwgZmxhdENvb3JkaW5hdGVzW29mZnNldCArIHN0cmlkZSAtIDFdKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgc3RyaWRlKTtcbiAgICAgIGNvb3JkaW5hdGVbc3RyaWRlIC0gMV0gPSBtO1xuICAgICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSBlbHNlIGlmIChmbGF0Q29vcmRpbmF0ZXNbZW5kIC0gMV0gPCBtKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKGVuZCAtIHN0cmlkZSwgZW5kKTtcbiAgICAgIGNvb3JkaW5hdGVbc3RyaWRlIC0gMV0gPSBtO1xuICAgICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfSAvLyBGSVhNRSB1c2UgTygxKSBzZWFyY2hcblxuXG4gIGlmIChtID09IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGUgLSAxXSkge1xuICAgIHJldHVybiBmbGF0Q29vcmRpbmF0ZXMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBzdHJpZGUpO1xuICB9XG5cbiAgdmFyIGxvID0gb2Zmc2V0IC8gc3RyaWRlO1xuICB2YXIgaGkgPSBlbmQgLyBzdHJpZGU7XG5cbiAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICB2YXIgbWlkID0gbG8gKyBoaSA+PiAxO1xuXG4gICAgaWYgKG0gPCBmbGF0Q29vcmRpbmF0ZXNbKG1pZCArIDEpICogc3RyaWRlIC0gMV0pIHtcbiAgICAgIGhpID0gbWlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBsbyA9IG1pZCArIDE7XG4gICAgfVxuICB9XG5cbiAgdmFyIG0wID0gZmxhdENvb3JkaW5hdGVzW2xvICogc3RyaWRlIC0gMV07XG5cbiAgaWYgKG0gPT0gbTApIHtcbiAgICByZXR1cm4gZmxhdENvb3JkaW5hdGVzLnNsaWNlKChsbyAtIDEpICogc3RyaWRlLCAobG8gLSAxKSAqIHN0cmlkZSArIHN0cmlkZSk7XG4gIH1cblxuICB2YXIgbTEgPSBmbGF0Q29vcmRpbmF0ZXNbKGxvICsgMSkgKiBzdHJpZGUgLSAxXTtcbiAgdmFyIHQgPSAobSAtIG0wKSAvIChtMSAtIG0wKTtcbiAgY29vcmRpbmF0ZSA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaWRlIC0gMTsgKytpKSB7XG4gICAgY29vcmRpbmF0ZS5wdXNoKGxlcnAoZmxhdENvb3JkaW5hdGVzWyhsbyAtIDEpICogc3RyaWRlICsgaV0sIGZsYXRDb29yZGluYXRlc1tsbyAqIHN0cmlkZSArIGldLCB0KSk7XG4gIH1cblxuICBjb29yZGluYXRlLnB1c2gobSk7XG4gIHJldHVybiBjb29yZGluYXRlO1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgRW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGludGVycG9sYXRlIEludGVycG9sYXRlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lU3RyaW5nc0Nvb3JkaW5hdGVBdE0oZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHMsIHN0cmlkZSwgbSwgZXh0cmFwb2xhdGUsIGludGVycG9sYXRlKSB7XG4gIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgIHJldHVybiBsaW5lU3RyaW5nQ29vcmRpbmF0ZUF0TShmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1tlbmRzLmxlbmd0aCAtIDFdLCBzdHJpZGUsIG0sIGV4dHJhcG9sYXRlKTtcbiAgfVxuXG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChtIDwgZmxhdENvb3JkaW5hdGVzW3N0cmlkZSAtIDFdKSB7XG4gICAgaWYgKGV4dHJhcG9sYXRlKSB7XG4gICAgICBjb29yZGluYXRlID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKDAsIHN0cmlkZSk7XG4gICAgICBjb29yZGluYXRlW3N0cmlkZSAtIDFdID0gbTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBpZiAoZmxhdENvb3JkaW5hdGVzW2ZsYXRDb29yZGluYXRlcy5sZW5ndGggLSAxXSA8IG0pIHtcbiAgICBpZiAoZXh0cmFwb2xhdGUpIHtcbiAgICAgIGNvb3JkaW5hdGUgPSBmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoZmxhdENvb3JkaW5hdGVzLmxlbmd0aCAtIHN0cmlkZSk7XG4gICAgICBjb29yZGluYXRlW3N0cmlkZSAtIDFdID0gbTtcbiAgICAgIHJldHVybiBjb29yZGluYXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kID0gZW5kc1tpXTtcblxuICAgIGlmIChvZmZzZXQgPT0gZW5kKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAobSA8IGZsYXRDb29yZGluYXRlc1tvZmZzZXQgKyBzdHJpZGUgLSAxXSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSBlbHNlIGlmIChtIDw9IGZsYXRDb29yZGluYXRlc1tlbmQgLSAxXSkge1xuICAgICAgcmV0dXJuIGxpbmVTdHJpbmdDb29yZGluYXRlQXRNKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgbSwgZmFsc2UpO1xuICAgIH1cblxuICAgIG9mZnNldCA9IGVuZDtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL2ZsYXQvY2VudGVyXG4gKi9cbmltcG9ydCB7IGNyZWF0ZUVtcHR5LCBjcmVhdGVPclVwZGF0ZUZyb21GbGF0Q29vcmRpbmF0ZXMgfSBmcm9tICcuLi8uLi9leHRlbnQuanMnO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCBPZmZzZXQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzcyBFbmRzcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdHJpZGUgU3RyaWRlLlxuICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gRmxhdCBjZW50ZXJzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJSaW5nc3MoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZHNzLCBzdHJpZGUpIHtcbiAgdmFyIGZsYXRDZW50ZXJzID0gW107XG4gIHZhciBleHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHNzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICB2YXIgZW5kcyA9IGVuZHNzW2ldO1xuICAgIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcyhmbGF0Q29vcmRpbmF0ZXMsIG9mZnNldCwgZW5kc1swXSwgc3RyaWRlKTtcbiAgICBmbGF0Q2VudGVycy5wdXNoKChleHRlbnRbMF0gKyBleHRlbnRbMl0pIC8gMiwgKGV4dGVudFsxXSArIGV4dGVudFszXSkgLyAyKTtcbiAgICBvZmZzZXQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gIH1cblxuICByZXR1cm4gZmxhdENlbnRlcnM7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlci9GZWF0dXJlXG4gKi9cbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IHsgY29tcG9zZSBhcyBjb21wb3NlVHJhbnNmb3JtLCBjcmVhdGUgYXMgY3JlYXRlVHJhbnNmb3JtIH0gZnJvbSAnLi4vdHJhbnNmb3JtLmpzJztcbmltcG9ydCB7IGNyZWF0ZU9yVXBkYXRlRnJvbUNvb3JkaW5hdGUsIGNyZWF0ZU9yVXBkYXRlRnJvbUZsYXRDb29yZGluYXRlcywgZ2V0Q2VudGVyLCBnZXRIZWlnaHQgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgZ2V0SW50ZXJpb3JQb2ludE9mQXJyYXksIGdldEludGVyaW9yUG9pbnRzT2ZNdWx0aUFycmF5IH0gZnJvbSAnLi4vZ2VvbS9mbGF0L2ludGVyaW9ycG9pbnQuanMnO1xuaW1wb3J0IHsgZ2V0IGFzIGdldFByb2plY3Rpb24gfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IGludGVycG9sYXRlUG9pbnQgfSBmcm9tICcuLi9nZW9tL2ZsYXQvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZ3NzIGFzIGxpbmVhclJpbmdzc0NlbnRlciB9IGZyb20gJy4uL2dlb20vZmxhdC9jZW50ZXIuanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtMkQgfSBmcm9tICcuLi9nZW9tL2ZsYXQvdHJhbnNmb3JtLmpzJztcbi8qKlxuICogQHR5cGUge2ltcG9ydChcIi4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gKi9cblxudmFyIHRtcFRyYW5zZm9ybSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xuLyoqXG4gKiBMaWdodHdlaWdodCwgcmVhZC1vbmx5LCB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmV+RmVhdHVyZX0gYW5kIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9HZW9tZXRyeX5HZW9tZXRyeX0gbGlrZVxuICogc3RydWN0dXJlLCBvcHRpbWl6ZWQgZm9yIHZlY3RvciB0aWxlIHJlbmRlcmluZyBhbmQgc3R5bGluZy4gR2VvbWV0cnkgYWNjZXNzXG4gKiB0aHJvdWdoIHRoZSBBUEkgaXMgbGltaXRlZCB0byBnZXR0aW5nIHRoZSB0eXBlIGFuZCBleHRlbnQgb2YgdGhlIGdlb21ldHJ5LlxuICovXG5cbnZhciBSZW5kZXJGZWF0dXJlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gdHlwZSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBGbGF0IGNvb3JkaW5hdGVzLiBUaGVzZSBhbHdheXMgbmVlZFxuICAgKiAgICAgdG8gYmUgcmlnaHQtaGFuZGVkIGZvciBwb2x5Z29ucy5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fEFycmF5PEFycmF5PG51bWJlcj4+fSBlbmRzIEVuZHMgb3IgRW5kc3MuXG4gICAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgKj59IHByb3BlcnRpZXMgUHJvcGVydGllcy5cbiAgICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZH0gaWQgRmVhdHVyZSBpZC5cbiAgICovXG4gIGZ1bmN0aW9uIFJlbmRlckZlYXR1cmUodHlwZSwgZmxhdENvb3JkaW5hdGVzLCBlbmRzLCBwcm9wZXJ0aWVzLCBpZCkge1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR8dW5kZWZpbmVkfVxuICAgICAqL1xuICAgIHRoaXMuZXh0ZW50XztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIHRoaXMuaWRfID0gaWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMudHlwZV8gPSB0eXBlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICB0aGlzLmZsYXRDb29yZGluYXRlc18gPSBmbGF0Q29vcmRpbmF0ZXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKi9cblxuICAgIHRoaXMuZmxhdE1pZHBvaW50c18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj58QXJyYXk8QXJyYXk8bnVtYmVyPj59XG4gICAgICovXG5cbiAgICB0aGlzLmVuZHNfID0gZW5kcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCAqPn1cbiAgICAgKi9cblxuICAgIHRoaXMucHJvcGVydGllc18gPSBwcm9wZXJ0aWVzO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgYSBmZWF0dXJlIHByb3BlcnR5IGJ5IGl0cyBrZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5XG4gICAqIEByZXR1cm4geyp9IFZhbHVlIGZvciB0aGUgcmVxdWVzdGVkIGtleS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzX1trZXldO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgb2YgdGhpcyBmZWF0dXJlJ3MgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEV4dGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuZXh0ZW50Xykge1xuICAgICAgdGhpcy5leHRlbnRfID0gdGhpcy50eXBlXyA9PT0gR2VvbWV0cnlUeXBlLlBPSU5UID8gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZSh0aGlzLmZsYXRDb29yZGluYXRlc18pIDogY3JlYXRlT3JVcGRhdGVGcm9tRmxhdENvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzXywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXNfLmxlbmd0aCwgMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZXh0ZW50XztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgaW50ZXJpb3IgcG9pbnRzLlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEZsYXRJbnRlcmlvclBvaW50ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfKSB7XG4gICAgICB2YXIgZmxhdENlbnRlciA9IGdldENlbnRlcih0aGlzLmdldEV4dGVudCgpKTtcbiAgICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXyA9IGdldEludGVyaW9yUG9pbnRPZkFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzXywgMCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIHRoaXMuZW5kc18sIDIsIGZsYXRDZW50ZXIsIDApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRJbnRlcmlvclBvaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IGludGVyaW9yIHBvaW50cy5cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRGbGF0SW50ZXJpb3JQb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmZsYXRJbnRlcmlvclBvaW50c18pIHtcbiAgICAgIHZhciBmbGF0Q2VudGVycyA9IGxpbmVhclJpbmdzc0NlbnRlcih0aGlzLmZsYXRDb29yZGluYXRlc18sIDAsXG4gICAgICAvKiogQHR5cGUge0FycmF5PEFycmF5PG51bWJlcj4+fSAqL1xuICAgICAgdGhpcy5lbmRzXywgMik7XG4gICAgICB0aGlzLmZsYXRJbnRlcmlvclBvaW50c18gPSBnZXRJbnRlcmlvclBvaW50c09mTXVsdGlBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlc18sIDAsXG4gICAgICAvKiogQHR5cGUge0FycmF5PEFycmF5PG51bWJlcj4+fSAqL1xuICAgICAgdGhpcy5lbmRzXywgMiwgZmxhdENlbnRlcnMpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRJbnRlcmlvclBvaW50c187XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IG1pZHBvaW50LlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuZmxhdE1pZHBvaW50c18pIHtcbiAgICAgIHRoaXMuZmxhdE1pZHBvaW50c18gPSBpbnRlcnBvbGF0ZVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzXywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXNfLmxlbmd0aCwgMiwgMC41KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mbGF0TWlkcG9pbnRzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgbWlkcG9pbnRzLlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmZsYXRNaWRwb2ludHNfKSB7XG4gICAgICB0aGlzLmZsYXRNaWRwb2ludHNfID0gW107XG4gICAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXNfO1xuICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICB2YXIgZW5kcyA9XG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICB0aGlzLmVuZHNfO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIGVuZCA9IGVuZHNbaV07XG4gICAgICAgIHZhciBtaWRwb2ludCA9IGludGVycG9sYXRlUG9pbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgMiwgMC41KTtcbiAgICAgICAgZXh0ZW5kKHRoaXMuZmxhdE1pZHBvaW50c18sIG1pZHBvaW50KTtcbiAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZsYXRNaWRwb2ludHNfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBmZWF0dXJlIGlkZW50aWZpZXIuICBUaGlzIGlzIGEgc3RhYmxlIGlkZW50aWZpZXIgZm9yIHRoZSBmZWF0dXJlIGFuZFxuICAgKiBpcyBzZXQgd2hlbiByZWFkaW5nIGRhdGEgZnJvbSBhIHJlbW90ZSBzb3VyY2UuXG4gICAqIEByZXR1cm4ge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfSBJZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldElkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmlkXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmxhdENvb3JkaW5hdGVzXztcbiAgfTtcbiAgLyoqXG4gICAqIEZvciBBUEkgY29tcGF0aWJpbGl0eSB3aXRoIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX5GZWF0dXJlfSwgdGhpcyBtZXRob2QgaXMgdXNlZnVsIHdoZW5cbiAgICogZGV0ZXJtaW5pbmcgdGhlIGdlb21ldHJ5IHR5cGUgaW4gc3R5bGUgZnVuY3Rpb24gKHNlZSB7QGxpbmsgI2dldFR5cGV9KS5cbiAgICogQHJldHVybiB7UmVuZGVyRmVhdHVyZX0gRmVhdHVyZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEdlb21ldHJ5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge1JlbmRlckZlYXR1cmV9IFNpbXBsaWZpZWQgZ2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5ID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIHRyYW5zZm9ybWVkIGFuZCBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gW29wdF90cmFuc2Zvcm1dIE9wdGlvbmFsIHRyYW5zZm9ybSBmdW5jdGlvbi5cbiAgICogQHJldHVybiB7UmVuZGVyRmVhdHVyZX0gU2ltcGxpZmllZCBnZW9tZXRyeS5cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5zaW1wbGlmeVRyYW5zZm9ybWVkID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UsIG9wdF90cmFuc2Zvcm0pIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZSBwcm9wZXJ0aWVzLlxuICAgKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLCAqPn0gRmVhdHVyZSBwcm9wZXJ0aWVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0UHJvcGVydGllcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gU3RyaWRlLlxuICAgKi9cblxuXG4gIFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldFN0cmlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gMjtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge3VuZGVmaW5lZH1cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRTdHlsZUZ1bmN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBmZWF0dXJlJ3MgZ2VvbWV0cnkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnlUeXBlLmpzXCIpLmRlZmF1bHR9IEdlb21ldHJ5IHR5cGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnR5cGVfO1xuICB9O1xuICAvKipcbiAgICogVHJhbnNmb3JtIGdlb21ldHJ5IGNvb3JkaW5hdGVzIGZyb20gdGlsZSBwaXhlbCBzcGFjZSB0byBwcm9qZWN0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gcHJvamVjdGlvbiBUaGUgZGF0YSBwcm9qZWN0aW9uXG4gICAqL1xuXG5cbiAgUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICBwcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICB2YXIgcGl4ZWxFeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICAgIHZhciBwcm9qZWN0ZWRFeHRlbnQgPSBwcm9qZWN0aW9uLmdldFdvcmxkRXh0ZW50KCk7XG5cbiAgICBpZiAocGl4ZWxFeHRlbnQgJiYgcHJvamVjdGVkRXh0ZW50KSB7XG4gICAgICB2YXIgc2NhbGUgPSBnZXRIZWlnaHQocHJvamVjdGVkRXh0ZW50KSAvIGdldEhlaWdodChwaXhlbEV4dGVudCk7XG4gICAgICBjb21wb3NlVHJhbnNmb3JtKHRtcFRyYW5zZm9ybSwgcHJvamVjdGVkRXh0ZW50WzBdLCBwcm9qZWN0ZWRFeHRlbnRbM10sIHNjYWxlLCAtc2NhbGUsIDAsIDAsIDApO1xuICAgICAgdHJhbnNmb3JtMkQodGhpcy5mbGF0Q29vcmRpbmF0ZXNfLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlc18ubGVuZ3RoLCAyLCB0bXBUcmFuc2Zvcm0sIHRoaXMuZmxhdENvb3JkaW5hdGVzXyk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPnxBcnJheTxBcnJheTxudW1iZXI+Pn0gRW5kcyBvciBlbmRzcy5cbiAgICovXG5cblxuICBSZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRFbmRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNfO1xuICB9O1xuXG4gIHJldHVybiBSZW5kZXJGZWF0dXJlO1xufSgpO1xuXG5SZW5kZXJGZWF0dXJlLnByb3RvdHlwZS5nZXRFbmRzcyA9IFJlbmRlckZlYXR1cmUucHJvdG90eXBlLmdldEVuZHM7XG4vKipcbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgY29vcmRpbmF0ZXMuXG4gKi9cblxuUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0RmxhdENvb3JkaW5hdGVzID0gUmVuZGVyRmVhdHVyZS5wcm90b3R5cGUuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXM7XG5leHBvcnQgZGVmYXVsdCBSZW5kZXJGZWF0dXJlOyIsImltcG9ydCB7IGxpc3RlbiB9IGZyb20gJ29sL2V2ZW50cyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJ29sL2V2ZW50cy9FdmVudFR5cGUnO1xuaW1wb3J0IHsgbGFiZWxDYWNoZSB9IGZyb20gJ29sL3JlbmRlci9jYW52YXMnO1xuLyoqXG4gKiBQb2x5ZmlsbCBmb3IgT2JqZWN0LmFzc2lnbigpLiAgQXNzaWducyBlbnVtZXJhYmxlIGFuZCBvd24gcHJvcGVydGllcyBmcm9tXG4gKiBvbmUgb3IgbW9yZSBzb3VyY2Ugb2JqZWN0cyB0byBhIHRhcmdldCBvYmplY3QuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2Fzc2lnbi5cbiAqXG4gKiBAcGFyYW0geyFPYmplY3R9IHRhcmdldCBUaGUgdGFyZ2V0IG9iamVjdC5cbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSB2YXJfc291cmNlcyBUaGUgc291cmNlIG9iamVjdChzKS5cbiAqIEByZXR1cm4geyFPYmplY3R9IFRoZSBtb2RpZmllZCB0YXJnZXQgb2JqZWN0LlxuICovXG5cbmV4cG9ydCB2YXIgYXNzaWduID0gdHlwZW9mIE9iamVjdC5hc3NpZ24gPT09ICdmdW5jdGlvbicgPyBPYmplY3QuYXNzaWduIDogZnVuY3Rpb24gKHRhcmdldCwgdmFyX3NvdXJjZXMpIHtcbiAgaWYgKHRhcmdldCA9PT0gdW5kZWZpbmVkIHx8IHRhcmdldCA9PT0gbnVsbCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHVuZGVmaW5lZCBvciBudWxsIHRvIG9iamVjdCcpO1xuICB9XG5cbiAgdmFyIG91dHB1dCA9IE9iamVjdCh0YXJnZXQpO1xuXG4gIGZvciAodmFyIGkgPSAxLCBpaSA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGlmIChzb3VyY2UgIT09IHVuZGVmaW5lZCAmJiBzb3VyY2UgIT09IG51bGwpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKHNvdXJjZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgb3V0cHV0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuZXhwb3J0IGZ1bmN0aW9uIGRlZzJyYWQoZGVncmVlcykge1xuICByZXR1cm4gZGVncmVlcyAqIE1hdGguUEkgLyAxODA7XG59XG5leHBvcnQgdmFyIGRlZmF1bHRSZXNvbHV0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHJlc29sdXRpb25zID0gW107XG5cbiAgZm9yICh2YXIgcmVzID0gNzgyNzEuNTE2OTY0MDIwNDg7IHJlc29sdXRpb25zLmxlbmd0aCA8PSAyNDsgcmVzIC89IDIpIHtcbiAgICByZXNvbHV0aW9ucy5wdXNoKHJlcyk7XG4gIH1cblxuICByZXR1cm4gcmVzb2x1dGlvbnM7XG59KCk7XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCBXaWR0aCBvZiB0aGUgY2FudmFzLlxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCBIZWlnaHQgb2YgdGhlIGNhbnZhcy5cbiAqIEByZXR1cm4ge0hUTUxDYW52YXNFbGVtZW50fSBDYW52YXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNhbnZhcyh3aWR0aCwgaGVpZ2h0KSB7XG4gIGlmICh0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGUgIT09ICd1bmRlZmluZWQnICYmIHNlbGYgaW5zdGFuY2VvZiBXb3JrZXJHbG9iYWxTY29wZSAmJiB0eXBlb2YgT2Zmc2NyZWVuQ2FudmFzICE9PSAndW5kZWZpbmVkJykge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHs/fSAqL1xuICAgICAgbmV3IE9mZnNjcmVlbkNhbnZhcyh3aWR0aCwgaGVpZ2h0KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgcmV0dXJuIGNhbnZhcztcbiAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFpvb21Gb3JSZXNvbHV0aW9uKHJlc29sdXRpb24sIHJlc29sdXRpb25zKSB7XG4gIHZhciBpID0gMDtcbiAgdmFyIGlpID0gcmVzb2x1dGlvbnMubGVuZ3RoO1xuXG4gIGZvciAoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBjYW5kaWRhdGUgPSByZXNvbHV0aW9uc1tpXTtcblxuICAgIGlmIChjYW5kaWRhdGUgPCByZXNvbHV0aW9uICYmIGkgKyAxIDwgaWkpIHtcbiAgICAgIHZhciB6b29tRmFjdG9yID0gcmVzb2x1dGlvbnNbaV0gLyByZXNvbHV0aW9uc1tpICsgMV07XG4gICAgICByZXR1cm4gaSArIE1hdGgubG9nKHJlc29sdXRpb25zW2ldIC8gcmVzb2x1dGlvbikgLyBNYXRoLmxvZyh6b29tRmFjdG9yKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaWkgLSAxO1xufVxudmFyIGhhaXJTcGFjZVBvb2wgPSBBcnJheSgyNTYpLmpvaW4oXCJcXHUyMDBBXCIpO1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TGV0dGVyU3BhY2luZyh0ZXh0LCBsZXR0ZXJTcGFjaW5nKSB7XG4gIGlmIChsZXR0ZXJTcGFjaW5nID49IDAuMDUpIHtcbiAgICB2YXIgdGV4dFdpdGhMZXR0ZXJTcGFjaW5nID0gJyc7XG4gICAgdmFyIGxpbmVzID0gdGV4dC5zcGxpdCgnXFxuJyk7XG4gICAgdmFyIGpvaW5TcGFjZVN0cmluZyA9IGhhaXJTcGFjZVBvb2wuc2xpY2UoMCwgTWF0aC5yb3VuZChsZXR0ZXJTcGFjaW5nIC8gMC4xKSk7XG5cbiAgICBmb3IgKHZhciBsID0gMCwgbGwgPSBsaW5lcy5sZW5ndGg7IGwgPCBsbDsgKytsKSB7XG4gICAgICBpZiAobCA+IDApIHtcbiAgICAgICAgdGV4dFdpdGhMZXR0ZXJTcGFjaW5nICs9ICdcXG4nO1xuICAgICAgfVxuXG4gICAgICB0ZXh0V2l0aExldHRlclNwYWNpbmcgKz0gbGluZXNbbF0uc3BsaXQoJycpLmpvaW4oam9pblNwYWNlU3RyaW5nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGV4dFdpdGhMZXR0ZXJTcGFjaW5nO1xuICB9XG5cbiAgcmV0dXJuIHRleHQ7XG59XG52YXIgbWVhc3VyZUNvbnRleHQ7XG5cbmZ1bmN0aW9uIGdldE1lYXN1cmVDb250ZXh0KCkge1xuICBpZiAoIW1lYXN1cmVDb250ZXh0KSB7XG4gICAgbWVhc3VyZUNvbnRleHQgPSBjcmVhdGVDYW52YXMoMSwgMSkuZ2V0Q29udGV4dCgnMmQnKTtcbiAgfVxuXG4gIHJldHVybiBtZWFzdXJlQ29udGV4dDtcbn1cblxuZnVuY3Rpb24gbWVhc3VyZVRleHQodGV4dCwgbGV0dGVyU3BhY2luZykge1xuICByZXR1cm4gZ2V0TWVhc3VyZUNvbnRleHQoKS5tZWFzdXJlVGV4dCh0ZXh0KS53aWR0aCArICh0ZXh0Lmxlbmd0aCAtIDEpICogbGV0dGVyU3BhY2luZztcbn1cblxudmFyIG1lYXN1cmVDYWNoZSA9IHt9O1xuXG5pZiAobGFiZWxDYWNoZSkge1xuICAvLyBPbmx5IGF2YWlsYWJsZSB3aGVuIHVzaW5nIEVTIG1vZHVsZXNcbiAgbGlzdGVuKGxhYmVsQ2FjaGUsIEV2ZW50VHlwZS5DTEVBUiwgZnVuY3Rpb24gKCkge1xuICAgIG1lYXN1cmVDYWNoZSA9IHt9O1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBUZXh0KHRleHQsIGZvbnQsIGVtLCBsZXR0ZXJTcGFjaW5nKSB7XG4gIGlmICh0ZXh0LmluZGV4T2YoJ1xcbicpICE9PSAtMSkge1xuICAgIHZhciBoYXJkTGluZXMgPSB0ZXh0LnNwbGl0KCdcXG4nKTtcbiAgICB2YXIgbGluZXMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGhhcmRMaW5lcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBsaW5lcy5wdXNoKHdyYXBUZXh0KGhhcmRMaW5lc1tpXSwgZm9udCwgZW0sIGxldHRlclNwYWNpbmcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG4gIH1cblxuICB2YXIga2V5ID0gZW0gKyAnLCcgKyBmb250ICsgJywnICsgdGV4dCArICcsJyArIGxldHRlclNwYWNpbmc7XG4gIHZhciB3cmFwcGVkVGV4dCA9IG1lYXN1cmVDYWNoZVtrZXldO1xuXG4gIGlmICghd3JhcHBlZFRleHQpIHtcbiAgICB2YXIgd29yZHMgPSB0ZXh0LnNwbGl0KCcgJyk7XG5cbiAgICBpZiAod29yZHMubGVuZ3RoID4gMSkge1xuICAgICAgdmFyIGN0eCA9IGdldE1lYXN1cmVDb250ZXh0KCk7XG4gICAgICBjdHguZm9udCA9IGZvbnQ7XG4gICAgICB2YXIgb25lRW0gPSBjdHgubWVhc3VyZVRleHQoJ00nKS53aWR0aDtcbiAgICAgIHZhciBtYXhXaWR0aCA9IG9uZUVtICogZW07XG4gICAgICB2YXIgbGluZSA9ICcnO1xuICAgICAgdmFyIGxpbmVzID0gW107IC8vIFBhc3MgMSAtIHdyYXAgbGluZXMgdG8gbm90IGV4Y2VlZCBtYXhXaWR0aFxuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSB3b3Jkcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIHZhciB3b3JkID0gd29yZHNbaV07XG4gICAgICAgIHZhciB0ZXN0TGluZSA9IGxpbmUgKyAobGluZSA/ICcgJyA6ICcnKSArIHdvcmQ7XG5cbiAgICAgICAgaWYgKG1lYXN1cmVUZXh0KHRlc3RMaW5lLCBsZXR0ZXJTcGFjaW5nKSA8PSBtYXhXaWR0aCkge1xuICAgICAgICAgIGxpbmUgPSB0ZXN0TGluZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAobGluZSkge1xuICAgICAgICAgICAgbGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBsaW5lID0gd29yZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAobGluZSkge1xuICAgICAgICBsaW5lcy5wdXNoKGxpbmUpO1xuICAgICAgfSAvLyBQYXNzIDIgLSBhZGQgbGluZXMgd2l0aCBhIHdpZHRoIG9mIGxlc3MgdGhhbiAzMCUgb2YgbWF4V2lkdGggdG8gdGhlIHByZXZpb3VzIG9yIG5leHQgbGluZVxuXG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxpbmVzLmxlbmd0aDsgaSA8IGlpICYmIGlpID4gMTsgKytpKSB7XG4gICAgICAgIHZhciBsaW5lXzEgPSBsaW5lc1tpXTtcblxuICAgICAgICBpZiAobWVhc3VyZVRleHQobGluZV8xLCBsZXR0ZXJTcGFjaW5nKSA8IG1heFdpZHRoICogMC4zNSkge1xuICAgICAgICAgIHZhciBwcmV2V2lkdGggPSBpID4gMCA/IG1lYXN1cmVUZXh0KGxpbmVzW2kgLSAxXSwgbGV0dGVyU3BhY2luZykgOiBJbmZpbml0eTtcbiAgICAgICAgICB2YXIgbmV4dFdpZHRoID0gaSA8IGlpIC0gMSA/IG1lYXN1cmVUZXh0KGxpbmVzW2kgKyAxXSwgbGV0dGVyU3BhY2luZykgOiBJbmZpbml0eTtcbiAgICAgICAgICBsaW5lcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgaWkgLT0gMTtcblxuICAgICAgICAgIGlmIChwcmV2V2lkdGggPCBuZXh0V2lkdGgpIHtcbiAgICAgICAgICAgIGxpbmVzW2kgLSAxXSArPSAnICcgKyBsaW5lXzE7XG4gICAgICAgICAgICBpIC09IDE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxpbmVzW2ldID0gbGluZV8xICsgJyAnICsgbGluZXNbaV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IC8vIFBhc3MgMyAtIHRyeSB0byBmaWxsIDgwJSBvZiBtYXhXaWR0aCBmb3IgZWFjaCBsaW5lXG5cblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gbGluZXMubGVuZ3RoIC0gMTsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIGxpbmVfMiA9IGxpbmVzW2ldO1xuICAgICAgICB2YXIgbmV4dCA9IGxpbmVzW2kgKyAxXTtcblxuICAgICAgICBpZiAobWVhc3VyZVRleHQobGluZV8yLCBsZXR0ZXJTcGFjaW5nKSA+IG1heFdpZHRoICogMC43ICYmIG1lYXN1cmVUZXh0KG5leHQsIGxldHRlclNwYWNpbmcpIDwgbWF4V2lkdGggKiAwLjYpIHtcbiAgICAgICAgICB2YXIgbGluZVdvcmRzID0gbGluZV8yLnNwbGl0KCcgJyk7XG4gICAgICAgICAgdmFyIGxhc3RXb3JkID0gbGluZVdvcmRzLnBvcCgpO1xuXG4gICAgICAgICAgaWYgKG1lYXN1cmVUZXh0KGxhc3RXb3JkLCBsZXR0ZXJTcGFjaW5nKSA8IG1heFdpZHRoICogMC4yKSB7XG4gICAgICAgICAgICBsaW5lc1tpXSA9IGxpbmVXb3Jkcy5qb2luKCcgJyk7XG4gICAgICAgICAgICBsaW5lc1tpICsgMV0gPSBsYXN0V29yZCArICcgJyArIG5leHQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWkgLT0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB3cmFwcGVkVGV4dCA9IGxpbmVzLmpvaW4oJ1xcbicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3cmFwcGVkVGV4dCA9IHRleHQ7XG4gICAgfVxuXG4gICAgd3JhcHBlZFRleHQgPSBhcHBseUxldHRlclNwYWNpbmcod3JhcHBlZFRleHQsIGxldHRlclNwYWNpbmcpO1xuICAgIG1lYXN1cmVDYWNoZVtrZXldID0gd3JhcHBlZFRleHQ7XG4gIH1cblxuICByZXR1cm4gd3JhcHBlZFRleHQ7XG59IiwiLypcbm9sLW1hcGJveC1zdHlsZSAtIFVzZSBNYXBib3ggU3R5bGUgb2JqZWN0cyB3aXRoIE9wZW5MYXllcnNcbkNvcHlyaWdodCAyMDE2LXByZXNlbnQgb2wtbWFwYm94LXN0eWxlIGNvbnRyaWJ1dG9yc1xuTGljZW5zZTogaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29wZW5sYXllcnMvb2wtbWFwYm94LXN0eWxlL21hc3Rlci9MSUNFTlNFXG4qL1xuaW1wb3J0IFN0eWxlIGZyb20gJ29sL3N0eWxlL1N0eWxlJztcbmltcG9ydCBGaWxsIGZyb20gJ29sL3N0eWxlL0ZpbGwnO1xuaW1wb3J0IFN0cm9rZSBmcm9tICdvbC9zdHlsZS9TdHJva2UnO1xuaW1wb3J0IEljb24gZnJvbSAnb2wvc3R5bGUvSWNvbic7XG5pbXBvcnQgVGV4dCBmcm9tICdvbC9zdHlsZS9UZXh0JztcbmltcG9ydCBDaXJjbGUgZnJvbSAnb2wvc3R5bGUvQ2lyY2xlJztcbmltcG9ydCBSZW5kZXJGZWF0dXJlIGZyb20gJ29sL3JlbmRlci9GZWF0dXJlJztcbmltcG9ydCB7IGRlcmVmTGF5ZXJzIH0gZnJvbSAnQG1hcGJveC9tYXBib3gtZ2wtc3R5bGUtc3BlYyc7XG5pbXBvcnQgeyBleHByZXNzaW9uLCBDb2xvciwgZnVuY3Rpb24gYXMgZm4sIGxhdGVzdCBhcyBzcGVjLCBmZWF0dXJlRmlsdGVyIGFzIGNyZWF0ZUZpbHRlciB9IGZyb20gJ0BtYXBib3gvbWFwYm94LWdsLXN0eWxlLXNwZWMnO1xuaW1wb3J0IG1iMmNzcyBmcm9tICdtYXBib3gtdG8tY3NzLWZvbnQnO1xuaW1wb3J0IHsgZGVnMnJhZCwgZGVmYXVsdFJlc29sdXRpb25zLCBnZXRab29tRm9yUmVzb2x1dGlvbiwgd3JhcFRleHQsIGFwcGx5TGV0dGVyU3BhY2luZywgY3JlYXRlQ2FudmFzIH0gZnJvbSAnLi91dGlsJztcbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydChcIm9sL2xheWVyL1ZlY3RvclwiKS5kZWZhdWx0fSBWZWN0b3JMYXllclxuICogQHR5cGVkZWYge2ltcG9ydChcIm9sL2xheWVyL1ZlY3RvclRpbGVcIikuZGVmYXVsdH0gVmVjdG9yVGlsZUxheWVyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwib2wvc3R5bGUvU3R5bGVcIikuU3R5bGVGdW5jdGlvbn0gU3R5bGVGdW5jdGlvblxuICovXG5cbnZhciBpc0Z1bmN0aW9uID0gZm4uaXNGdW5jdGlvbjtcbnZhciBjb252ZXJ0RnVuY3Rpb24gPSBmbi5jb252ZXJ0RnVuY3Rpb247XG52YXIgaXNFeHByZXNzaW9uID0gZXhwcmVzc2lvbi5pc0V4cHJlc3Npb247XG52YXIgY3JlYXRlUHJvcGVydHlFeHByZXNzaW9uID0gZXhwcmVzc2lvbi5jcmVhdGVQcm9wZXJ0eUV4cHJlc3Npb247XG52YXIgdHlwZXMgPSB7XG4gICdQb2ludCc6IDEsXG4gICdNdWx0aVBvaW50JzogMSxcbiAgJ0xpbmVTdHJpbmcnOiAyLFxuICAnTXVsdGlMaW5lU3RyaW5nJzogMixcbiAgJ1BvbHlnb24nOiAzLFxuICAnTXVsdGlQb2x5Z29uJzogM1xufTtcbnZhciBhbmNob3IgPSB7XG4gICdjZW50ZXInOiBbMC41LCAwLjVdLFxuICAnbGVmdCc6IFswLCAwLjVdLFxuICAncmlnaHQnOiBbMSwgMC41XSxcbiAgJ3RvcCc6IFswLjUsIDBdLFxuICAnYm90dG9tJzogWzAuNSwgMV0sXG4gICd0b3AtbGVmdCc6IFswLCAwXSxcbiAgJ3RvcC1yaWdodCc6IFsxLCAwXSxcbiAgJ2JvdHRvbS1sZWZ0JzogWzAsIDFdLFxuICAnYm90dG9tLXJpZ2h0JzogWzEsIDFdXG59O1xuXG52YXIgZXhwcmVzc2lvbkRhdGEgPSBmdW5jdGlvbiBleHByZXNzaW9uRGF0YShyYXdFeHByZXNzaW9uLCBwcm9wZXJ0eVNwZWMpIHtcbiAgdmFyIGNvbXBpbGVkRXhwcmVzc2lvbiA9IGNyZWF0ZVByb3BlcnR5RXhwcmVzc2lvbihyYXdFeHByZXNzaW9uLCBwcm9wZXJ0eVNwZWMpO1xuXG4gIGlmIChjb21waWxlZEV4cHJlc3Npb24ucmVzdWx0ID09PSAnZXJyb3InKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGNvbXBpbGVkRXhwcmVzc2lvbi52YWx1ZS5tYXAoZnVuY3Rpb24gKGVycikge1xuICAgICAgcmV0dXJuIGVyci5rZXkgKyBcIjogXCIgKyBlcnIubWVzc2FnZTtcbiAgICB9KS5qb2luKCcsICcpKTtcbiAgfVxuXG4gIHJldHVybiBjb21waWxlZEV4cHJlc3Npb24udmFsdWU7XG59O1xuXG52YXIgZW1wdHlPYmogPSB7fTtcbnZhciB6b29tT2JqID0ge1xuICB6b29tOiAwXG59O1xuLyoqIEBwcml2YXRlICovXG5cbnZhciBmdW5jdGlvbkNhY2hlID0ge307XG52YXIgcmVuZGVyRmVhdHVyZUNvb3JkaW5hdGVzLCByZW5kZXJGZWF0dXJlO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGxheWVyIEdsIG9iamVjdCBsYXllci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYXlvdXRPclBhaW50ICdsYXlvdXQnIG9yICdwYWludCcuXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHkgRmVhdHVyZSBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFpvb20uXG4gKiBAcGFyYW0ge09iamVjdH0gZmVhdHVyZSBHbCBmZWF0dXJlLlxuICogQHJldHVybiB7P30gVmFsdWUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlKGxheWVyLCBsYXlvdXRPclBhaW50LCBwcm9wZXJ0eSwgem9vbSwgZmVhdHVyZSkge1xuICB2YXIgbGF5ZXJJZCA9IGxheWVyLmlkO1xuXG4gIGlmICghZnVuY3Rpb25DYWNoZVtsYXllcklkXSkge1xuICAgIGZ1bmN0aW9uQ2FjaGVbbGF5ZXJJZF0gPSB7fTtcbiAgfVxuXG4gIHZhciBmdW5jdGlvbnMgPSBmdW5jdGlvbkNhY2hlW2xheWVySWRdO1xuXG4gIGlmICghZnVuY3Rpb25zW3Byb3BlcnR5XSkge1xuICAgIHZhciB2YWx1ZV8xID0gKGxheWVyW2xheW91dE9yUGFpbnRdIHx8IGVtcHR5T2JqKVtwcm9wZXJ0eV07XG4gICAgdmFyIHByb3BlcnR5U3BlYyA9IHNwZWNbbGF5b3V0T3JQYWludCArIFwiX1wiICsgbGF5ZXIudHlwZV1bcHJvcGVydHldO1xuXG4gICAgaWYgKHZhbHVlXzEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFsdWVfMSA9IHByb3BlcnR5U3BlYy5kZWZhdWx0O1xuICAgIH1cblxuICAgIHZhciBpc0V4cHIgPSBpc0V4cHJlc3Npb24odmFsdWVfMSk7XG5cbiAgICBpZiAoIWlzRXhwciAmJiBpc0Z1bmN0aW9uKHZhbHVlXzEpKSB7XG4gICAgICB2YWx1ZV8xID0gY29udmVydEZ1bmN0aW9uKHZhbHVlXzEsIHByb3BlcnR5U3BlYyk7XG4gICAgICBpc0V4cHIgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpc0V4cHIpIHtcbiAgICAgIHZhciBjb21waWxlZEV4cHJlc3Npb24gPSBleHByZXNzaW9uRGF0YSh2YWx1ZV8xLCBwcm9wZXJ0eVNwZWMpO1xuICAgICAgZnVuY3Rpb25zW3Byb3BlcnR5XSA9IGNvbXBpbGVkRXhwcmVzc2lvbi5ldmFsdWF0ZS5iaW5kKGNvbXBpbGVkRXhwcmVzc2lvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwcm9wZXJ0eVNwZWMudHlwZSA9PSAnY29sb3InKSB7XG4gICAgICAgIHZhbHVlXzEgPSBDb2xvci5wYXJzZSh2YWx1ZV8xKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb25zW3Byb3BlcnR5XSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlXzE7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHpvb21PYmouem9vbSA9IHpvb207XG4gIHJldHVybiBmdW5jdGlvbnNbcHJvcGVydHldKHpvb21PYmosIGZlYXR1cmUpO1xufVxuLyoqIEBwcml2YXRlICovXG5cbnZhciBmaWx0ZXJDYWNoZSA9IHt9O1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGxheWVySWQgTGF5ZXIgaWQuXG4gKiBAcGFyYW0gez99IGZpbHRlciBGaWx0ZXIuXG4gKiBAcGFyYW0ge09iamVjdH0gZmVhdHVyZSBGZWF0dXJlLlxuICogQHBhcmFtIHtudW1iZXJ9IHpvb20gWm9vbS5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IEZpbHRlciByZXN1bHQuXG4gKi9cblxuZnVuY3Rpb24gZXZhbHVhdGVGaWx0ZXIobGF5ZXJJZCwgZmlsdGVyLCBmZWF0dXJlLCB6b29tKSB7XG4gIGlmICghKGxheWVySWQgaW4gZmlsdGVyQ2FjaGUpKSB7XG4gICAgZmlsdGVyQ2FjaGVbbGF5ZXJJZF0gPSBjcmVhdGVGaWx0ZXIoZmlsdGVyKS5maWx0ZXI7XG4gIH1cblxuICB6b29tT2JqLnpvb20gPSB6b29tO1xuICByZXR1cm4gZmlsdGVyQ2FjaGVbbGF5ZXJJZF0oem9vbU9iaiwgZmVhdHVyZSk7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gez99IGNvbG9yIENvbG9yLlxuICogQHBhcmFtIHtudW1iZXJ9IG9wYWNpdHkgT3BhY2l0eS5cbiAqIEByZXR1cm4ge3N0cmluZ30gQ29sb3IuXG4gKi9cblxuXG5mdW5jdGlvbiBjb2xvcldpdGhPcGFjaXR5KGNvbG9yLCBvcGFjaXR5KSB7XG4gIGlmIChjb2xvcikge1xuICAgIGlmIChjb2xvci5hID09PSAwIHx8IG9wYWNpdHkgPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdmFyIGEgPSBjb2xvci5hO1xuICAgIG9wYWNpdHkgPSBvcGFjaXR5ID09PSB1bmRlZmluZWQgPyAxIDogb3BhY2l0eTtcbiAgICByZXR1cm4gJ3JnYmEoJyArIE1hdGgucm91bmQoY29sb3IuciAqIDI1NSAvIGEpICsgJywnICsgTWF0aC5yb3VuZChjb2xvci5nICogMjU1IC8gYSkgKyAnLCcgKyBNYXRoLnJvdW5kKGNvbG9yLmIgKiAyNTUgLyBhKSArICcsJyArIGEgKiBvcGFjaXR5ICsgJyknO1xuICB9XG5cbiAgcmV0dXJuIGNvbG9yO1xufVxuXG52YXIgdGVtcGxhdGVSZWdFeCA9IC9eKFteXSopXFx7KC4qKVxcfShbXl0qKSQvO1xuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgVGV4dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wZXJ0aWVzIFByb3BlcnRpZXMuXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRleHQuXG4gKi9cblxuZnVuY3Rpb24gZnJvbVRlbXBsYXRlKHRleHQsIHByb3BlcnRpZXMpIHtcbiAgdmFyIHBhcnRzO1xuXG4gIGRvIHtcbiAgICBwYXJ0cyA9IHRleHQubWF0Y2godGVtcGxhdGVSZWdFeCk7XG5cbiAgICBpZiAocGFydHMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IHByb3BlcnRpZXNbcGFydHNbMl1dIHx8ICcnO1xuICAgICAgdGV4dCA9IHBhcnRzWzFdICsgdmFsdWUgKyBwYXJ0c1szXTtcbiAgICB9XG4gIH0gd2hpbGUgKHBhcnRzKTtcblxuICByZXR1cm4gdGV4dDtcbn1cblxudmFyIHJlY29yZExheWVyID0gZmFsc2U7XG4vKipcbiAqIGBgYGpzXG4gKiBpbXBvcnQge3JlY29yZFN0eWxlTGF5ZXJ9IGZyb20gJ29sLW1hcGJveC1zdHlsZS9kaXN0L3N0eWxlZnVuY3Rpb24nO1xuICogYGBgXG4gKiBUdXJucyByZWNvcmRpbmcgb2YgdGhlIE1hcGJveCBTdHlsZSdzIGBsYXllcmAgb24gYW5kIG9mZi4gV2hlbiB0dXJuZWQgb24sXG4gKiB0aGUgbGF5ZXIgdGhhdCBhIHJlbmRlcmVkIGZlYXR1cmUgYmVsb25ncyB0byB3aWxsIGJlIHNldCBhcyB0aGUgZmVhdHVyZSdzXG4gKiBgbWFwYm94LWxheWVyYCBwcm9wZXJ0eS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlY29yZD1mYWxzZV0gUmVjb3JkaW5nIG9mIHRoZSBzdHlsZSBsYXllciBpcyBvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkU3R5bGVMYXllcihyZWNvcmQpIHtcbiAgcmVjb3JkTGF5ZXIgPSByZWNvcmQ7XG59XG4vKipcbiAqIGBgYGpzXG4gKiBpbXBvcnQgc3R5bGVmdW5jdGlvbiBmcm9tICdvbC1tYXBib3gtc3R5bGUvZGlzdC9zdHlsZWZ1bmN0aW9uJztcbiAqIGBgYFxuICogQ3JlYXRlcyBhIHN0eWxlIGZ1bmN0aW9uIGZyb20gdGhlIGBnbFN0eWxlYCBvYmplY3QgZm9yIGFsbCBsYXllcnMgdGhhdCB1c2VcbiAqIHRoZSBzcGVjaWZpZWQgYHNvdXJjZWAsIHdoaWNoIG5lZWRzIHRvIGJlIGEgYFwidHlwZVwiOiBcInZlY3RvclwiYCBvclxuICogYFwidHlwZVwiOiBcImdlb2pzb25cImAgc291cmNlIGFuZCBhcHBsaWVzIGl0IHRvIHRoZSBzcGVjaWZpZWQgT3BlbkxheWVycyBsYXllci5cbiAqXG4gKiBUd28gYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHdpbGwgYmUgc2V0IG9uIHRoZSBwcm92aWRlZCBsYXllcjpcbiAqXG4gKiAgKiBgbWFwYm94LXNvdXJjZWA6IFRoZSBgaWRgIG9mIHRoZSBNYXBib3ggU3R5bGUgZG9jdW1lbnQncyBzb3VyY2UgdGhhdCB0aGVcbiAqICAgIE9wZW5MYXllcnMgbGF5ZXIgd2FzIGNyZWF0ZWQgZnJvbS4gVXN1YWxseSBgYXBwbHkoKWAgY3JlYXRlcyBvbmVcbiAqICAgIE9wZW5MYXllcnMgbGF5ZXIgcGVyIE1hcGJveCBTdHlsZSBzb3VyY2UsIHVubGVzcyB0aGUgbGF5ZXIgc3RhY2sgaGFzXG4gKiAgICBsYXllcnMgZnJvbSBkaWZmZXJlbnQgc291cmNlcyBpbiBiZXR3ZWVuLlxuICogICogYG1hcGJveC1sYXllcnNgOiBUaGUgYGlkYHMgb2YgdGhlIE1hcGJveCBTdHlsZSBkb2N1bWVudCdzIGxheWVycyB0aGF0IGFyZVxuICogICAgaW5jbHVkZWQgaW4gdGhlIE9wZW5MYXllcnMgbGF5ZXIuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBhbHNvIHdvcmtzIGluIGEgd2ViIHdvcmtlci4gSW4gd29ya2VyIG1vZGUsIHRoZSBtYWluIHRocmVhZCBuZWVkc1xuICogdG8gbGlzdGVuIHRvIG1lc3NhZ2VzIGZyb20gdGhlIHdvcmtlciBhbmQgcmVzcG9uZCB3aXRoIGFub3RoZXIgbWVzc2FnZSB0byBtYWtlXG4gKiBzdXJlIHRoYXQgc3ByaXRlIGltYWdlIGxvYWRpbmcgd29ya3M6XG4gKlxuICogYGBganNcbiAqICB3b3JrZXIuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGV2ZW50ID0+IHtcbiAqICAgaWYgKGV2ZW50LmRhdGEuYWN0aW9uID09PSAnbG9hZEltYWdlJykge1xuICogICAgIGNvbnN0IGltYWdlID0gbmV3IEltYWdlKCk7XG4gKiAgICAgaW1hZ2UuY3Jvc3NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAqICAgICBpbWFnZS5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgZnVuY3Rpb24oKSB7XG4gKiAgICAgICBjcmVhdGVJbWFnZUJpdG1hcChpbWFnZSwgMCwgMCwgaW1hZ2Uud2lkdGgsIGltYWdlLmhlaWdodCkudGhlbihpbWFnZUJpdG1hcCA9PiB7XG4gKiAgICAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7XG4gKiAgICAgICAgICAgYWN0aW9uOiAnaW1hZ2VMb2FkZWQnLFxuICogICAgICAgICAgIGltYWdlOiBpbWFnZUJpdG1hcCxcbiAqICAgICAgICAgICBzcmM6IGV2ZW50LmRhdGEuc3JjXG4gKiAgICAgICAgIH0sIFtpbWFnZUJpdG1hcF0pO1xuICogICAgICAgfSk7XG4gKiAgICAgfSk7XG4gKiAgICAgaW1hZ2Uuc3JjID0gZXZlbnQuZGF0YS5zcmM7XG4gKiAgIH1cbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtWZWN0b3JMYXllcnxWZWN0b3JUaWxlTGF5ZXJ9IG9sTGF5ZXIgT3BlbkxheWVycyBsYXllciB0b1xuICogYXBwbHkgdGhlIHN0eWxlIHRvLiBJbiBhZGRpdGlvbiB0byB0aGUgc3R5bGUsIHRoZSBsYXllciB3aWxsIGdldCB0d29cbiAqIHByb3BlcnRpZXM6IGBtYXBib3gtc291cmNlYCB3aWxsIGJlIHRoZSBgaWRgIG9mIHRoZSBgZ2xTdHlsZWAncyBzb3VyY2UgdXNlZFxuICogZm9yIHRoZSBsYXllciwgYW5kIGBtYXBib3gtbGF5ZXJzYCB3aWxsIGJlIGFuIGFycmF5IG9mIHRoZSBgaWRgcyBvZiB0aGVcbiAqIGBnbFN0eWxlYCdzIGxheWVycy5cbiAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdH0gZ2xTdHlsZSBNYXBib3ggU3R5bGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gc291cmNlIGBzb3VyY2VgIGtleSBvciBhbiBhcnJheSBvZiBsYXllciBgaWRgc1xuICogZnJvbSB0aGUgTWFwYm94IFN0eWxlIG9iamVjdC4gV2hlbiBhIGBzb3VyY2VgIGtleSBpcyBwcm92aWRlZCwgYWxsIGxheWVycyBmb3JcbiAqIHRoZSBzcGVjaWZpZWQgc291cmNlIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIHN0eWxlIGZ1bmN0aW9uLiBXaGVuIGxheWVyIGBpZGBzXG4gKiBhcmUgcHJvdmlkZWQsIHRoZXkgbXVzdCBiZSBmcm9tIGxheWVycyB0aGF0IHVzZSB0aGUgc2FtZSBzb3VyY2UuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IFtyZXNvbHV0aW9ucz1bNzgyNzEuNTE2OTY0MDIwNDgsIDM5MTM1Ljc1ODQ4MjAxMDI0LFxuICAgMTk1NjcuODc5MjQxMDA1MTIsIDk3ODMuOTM5NjIwNTAyNTYsIDQ4OTEuOTY5ODEwMjUxMjgsIDI0NDUuOTg0OTA1MTI1NjQsXG4gICAxMjIyLjk5MjQ1MjU2MjgyLCA2MTEuNDk2MjI2MjgxNDEsIDMwNS43NDgxMTMxNDA3MDUsIDE1Mi44NzQwNTY1NzAzNTI1LFxuICAgNzYuNDM3MDI4Mjg1MTc2MjUsIDM4LjIxODUxNDE0MjU4ODEzLCAxOS4xMDkyNTcwNzEyOTQwNjMsIDkuNTU0NjI4NTM1NjQ3MDMyLFxuICAgNC43NzczMTQyNjc4MjM1MTYsIDIuMzg4NjU3MTMzOTExNzU4LCAxLjE5NDMyODU2Njk1NTg3OSwgMC41OTcxNjQyODM0Nzc5Mzk1LFxuICAgMC4yOTg1ODIxNDE3Mzg5Njk3NCwgMC4xNDkyOTEwNzA4Njk0ODQ4NywgMC4wNzQ2NDU1MzU0MzQ3NDI0NF1dXG4gKiBSZXNvbHV0aW9ucyBmb3IgbWFwcGluZyByZXNvbHV0aW9uIHRvIHpvb20gbGV2ZWwuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Nwcml0ZURhdGE9dW5kZWZpbmVkXSBTcHJpdGUgZGF0YSBmcm9tIHRoZSB1cmwgc3BlY2lmaWVkIGluXG4gKiB0aGUgTWFwYm94IFN0eWxlIG9iamVjdCdzIGBzcHJpdGVgIHByb3BlcnR5LiBPbmx5IHJlcXVpcmVkIGlmIGEgYHNwcml0ZWBcbiAqIHByb3BlcnR5IGlzIHNwZWNpZmllZCBpbiB0aGUgTWFwYm94IFN0eWxlIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3ByaXRlSW1hZ2VVcmw9dW5kZWZpbmVkXSBTcHJpdGUgaW1hZ2UgdXJsIGZvciB0aGUgc3ByaXRlXG4gKiBzcGVjaWZpZWQgaW4gdGhlIE1hcGJveCBTdHlsZSBvYmplY3QncyBgc3ByaXRlYCBwcm9wZXJ0eS4gT25seSByZXF1aXJlZCBpZiBhXG4gKiBgc3ByaXRlYCBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQgaW4gdGhlIE1hcGJveCBTdHlsZSBvYmplY3QuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKEFycmF5PHN0cmluZz4pOkFycmF5PHN0cmluZz59IFtnZXRGb250cz11bmRlZmluZWRdIEZ1bmN0aW9uIHRoYXRcbiAqIHJlY2VpdmVzIGEgZm9udCBzdGFjayBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm5zIGEgKG1vZGlmaWVkKSBmb250IHN0YWNrIHRoYXRcbiAqIGlzIGF2YWlsYWJsZS4gRm9udCBuYW1lcyBhcmUgdGhlIG5hbWVzIHVzZWQgaW4gdGhlIE1hcGJveCBTdHlsZSBvYmplY3QuIElmXG4gKiBub3QgcHJvdmlkZWQsIHRoZSBmb250IHN0YWNrIHdpbGwgYmUgdXNlZCBhcy1pcy4gVGhpcyBmdW5jdGlvbiBjYW4gYWxzbyBiZVxuICogdXNlZCBmb3IgbG9hZGluZyB3ZWIgZm9udHMuXG4gKiBAcmV0dXJuIHtTdHlsZUZ1bmN0aW9ufSBTdHlsZSBmdW5jdGlvbiBmb3IgdXNlIGluXG4gKiBgb2wubGF5ZXIuVmVjdG9yYCBvciBgb2wubGF5ZXIuVmVjdG9yVGlsZWAuXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKG9sTGF5ZXIsIGdsU3R5bGUsIHNvdXJjZSwgcmVzb2x1dGlvbnMsIHNwcml0ZURhdGEsIHNwcml0ZUltYWdlVXJsLCBnZXRGb250cykge1xuICBpZiAocmVzb2x1dGlvbnMgPT09IHZvaWQgMCkge1xuICAgIHJlc29sdXRpb25zID0gZGVmYXVsdFJlc29sdXRpb25zO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBnbFN0eWxlID09ICdzdHJpbmcnKSB7XG4gICAgZ2xTdHlsZSA9IEpTT04ucGFyc2UoZ2xTdHlsZSk7XG4gIH1cblxuICBpZiAoZ2xTdHlsZS52ZXJzaW9uICE9IDgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2dsU3R5bGUgdmVyc2lvbiA4IHJlcXVpcmVkLicpO1xuICB9XG5cbiAgdmFyIHNwcml0ZUltYWdlLCBzcHJpdGVJbWdTaXplO1xuXG4gIGlmIChzcHJpdGVJbWFnZVVybCkge1xuICAgIGlmICh0eXBlb2YgSW1hZ2UgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgaW1nXzEgPSBuZXcgSW1hZ2UoKTtcbiAgICAgIGltZ18xLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG5cbiAgICAgIGltZ18xLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc3ByaXRlSW1hZ2UgPSBpbWdfMTtcbiAgICAgICAgc3ByaXRlSW1nU2l6ZSA9IFtpbWdfMS53aWR0aCwgaW1nXzEuaGVpZ2h0XTtcbiAgICAgICAgb2xMYXllci5jaGFuZ2VkKCk7XG4gICAgICAgIGltZ18xLm9ubG9hZCA9IG51bGw7XG4gICAgICB9O1xuXG4gICAgICBpbWdfMS5zcmMgPSBzcHJpdGVJbWFnZVVybDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlKSB7XG4gICAgICAvL2VzbGludC1kaXNhYmxlLWxpbmVcbiAgICAgIHZhciB3b3JrZXIgPVxuICAgICAgLyoqIEB0eXBlIHsqfSAqL1xuICAgICAgc2VsZjsgLy8gTWFpbiB0aHJlYWQgbmVlZHMgdG8gaGFuZGxlICdsb2FkSW1hZ2UnIGFuZCBkaXNwYXRjaCAnaW1hZ2VMb2FkZWQnXG5cbiAgICAgIHdvcmtlci5wb3N0TWVzc2FnZSh7XG4gICAgICAgIGFjdGlvbjogJ2xvYWRJbWFnZScsXG4gICAgICAgIHNyYzogc3ByaXRlSW1hZ2VVcmxcbiAgICAgIH0pO1xuICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC5kYXRhLmFjdGlvbiA9PT0gJ2ltYWdlTG9hZGVkJyAmJiBldmVudC5kYXRhLnNyYyA9PT0gc3ByaXRlSW1hZ2VVcmwpIHtcbiAgICAgICAgICBzcHJpdGVJbWFnZSA9IGV2ZW50LmRhdGEuaW1hZ2U7XG4gICAgICAgICAgc3ByaXRlSW1nU2l6ZSA9IFtzcHJpdGVJbWFnZS53aWR0aCwgc3ByaXRlSW1hZ2UuaGVpZ2h0XTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGFsbExheWVycyA9IGRlcmVmTGF5ZXJzKGdsU3R5bGUubGF5ZXJzKTtcbiAgdmFyIGxheWVyc0J5U291cmNlTGF5ZXIgPSB7fTtcbiAgdmFyIG1hcGJveExheWVycyA9IFtdO1xuICB2YXIgbWFwYm94U291cmNlO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGFsbExheWVycy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGxheWVyID0gYWxsTGF5ZXJzW2ldO1xuICAgIHZhciBsYXllcklkID0gbGF5ZXIuaWQ7XG5cbiAgICBpZiAodHlwZW9mIHNvdXJjZSA9PSAnc3RyaW5nJyAmJiBsYXllci5zb3VyY2UgPT0gc291cmNlIHx8IHNvdXJjZS5pbmRleE9mKGxheWVySWQpICE9PSAtMSkge1xuICAgICAgdmFyIHNvdXJjZUxheWVyID0gbGF5ZXJbJ3NvdXJjZS1sYXllciddO1xuXG4gICAgICBpZiAoIW1hcGJveFNvdXJjZSkge1xuICAgICAgICBtYXBib3hTb3VyY2UgPSBsYXllci5zb3VyY2U7XG4gICAgICAgIHZhciBzb3VyY2VfMSA9IGdsU3R5bGUuc291cmNlc1ttYXBib3hTb3VyY2VdO1xuXG4gICAgICAgIGlmICghc291cmNlXzEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb3VyY2UgXFxcIlwiICsgbWFwYm94U291cmNlICsgXCJcXFwiIGlzIG5vdCBkZWZpbmVkXCIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHR5cGUgPSBzb3VyY2VfMS50eXBlO1xuXG4gICAgICAgIGlmICh0eXBlICE9PSAndmVjdG9yJyAmJiB0eXBlICE9PSAnZ2VvanNvbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb3VyY2UgXFxcIlwiICsgbWFwYm94U291cmNlICsgXCJcXFwiIGlzIG5vdCBvZiB0eXBlIFxcXCJ2ZWN0b3JcXFwiIG9yIFxcXCJnZW9qc29uXFxcIiwgYnV0IFxcXCJcIiArIHR5cGUgKyBcIlxcXCJcIik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIGxheWVycyA9IGxheWVyc0J5U291cmNlTGF5ZXJbc291cmNlTGF5ZXJdO1xuXG4gICAgICBpZiAoIWxheWVycykge1xuICAgICAgICBsYXllcnMgPSBsYXllcnNCeVNvdXJjZUxheWVyW3NvdXJjZUxheWVyXSA9IFtdO1xuICAgICAgfVxuXG4gICAgICBsYXllcnMucHVzaCh7XG4gICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgaW5kZXg6IGlcbiAgICAgIH0pO1xuICAgICAgbWFwYm94TGF5ZXJzLnB1c2gobGF5ZXJJZCk7XG4gICAgfSAvLyBUT0RPIHJldmlzaXQgd2hlbiBkaWZmaW5nIGdldHMgYWRkZWRcblxuXG4gICAgZGVsZXRlIGZ1bmN0aW9uQ2FjaGVbbGF5ZXJJZF07XG4gICAgZGVsZXRlIGZpbHRlckNhY2hlW2xheWVySWRdO1xuICB9XG5cbiAgdmFyIHRleHRIYWxvID0gbmV3IFN0cm9rZSgpO1xuICB2YXIgdGV4dENvbG9yID0gbmV3IEZpbGwoKTtcbiAgdmFyIGljb25JbWFnZUNhY2hlID0ge307XG4gIHZhciBwYXR0ZXJuQ2FjaGUgPSB7fTtcbiAgdmFyIHN0eWxlcyA9IFtdO1xuXG4gIHZhciBzdHlsZUZ1bmN0aW9uID0gZnVuY3Rpb24gc3R5bGVGdW5jdGlvbihmZWF0dXJlLCByZXNvbHV0aW9uKSB7XG4gICAgdmFyIHByb3BlcnRpZXMgPSBmZWF0dXJlLmdldFByb3BlcnRpZXMoKTtcbiAgICB2YXIgbGF5ZXJzID0gbGF5ZXJzQnlTb3VyY2VMYXllcltwcm9wZXJ0aWVzLmxheWVyXTtcblxuICAgIGlmICghbGF5ZXJzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHpvb20gPSByZXNvbHV0aW9ucy5pbmRleE9mKHJlc29sdXRpb24pO1xuXG4gICAgaWYgKHpvb20gPT0gLTEpIHtcbiAgICAgIHpvb20gPSBnZXRab29tRm9yUmVzb2x1dGlvbihyZXNvbHV0aW9uLCByZXNvbHV0aW9ucyk7XG4gICAgfVxuXG4gICAgdmFyIHR5cGUgPSB0eXBlc1tmZWF0dXJlLmdldEdlb21ldHJ5KCkuZ2V0VHlwZSgpXTtcbiAgICB2YXIgZiA9IHtcbiAgICAgIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG4gICAgICB0eXBlOiB0eXBlXG4gICAgfTtcbiAgICB2YXIgc3R5bGVzTGVuZ3RoID0gLTE7XG4gICAgdmFyIGZlYXR1cmVCZWxvbmdzVG9MYXllcjtcblxuICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gX2xvb3BfMShpLCBpaSkge1xuICAgICAgdmFyIGxheWVyRGF0YSA9IGxheWVyc1tpXTtcbiAgICAgIHZhciBsYXllciA9IGxheWVyRGF0YS5sYXllcjtcbiAgICAgIHZhciBsYXllcklkID0gbGF5ZXIuaWQ7XG4gICAgICB2YXIgbGF5b3V0ID0gbGF5ZXIubGF5b3V0IHx8IGVtcHR5T2JqO1xuICAgICAgdmFyIHBhaW50ID0gbGF5ZXIucGFpbnQgfHwgZW1wdHlPYmo7XG5cbiAgICAgIGlmIChsYXlvdXQudmlzaWJpbGl0eSA9PT0gJ25vbmUnIHx8ICdtaW56b29tJyBpbiBsYXllciAmJiB6b29tIDwgbGF5ZXIubWluem9vbSB8fCAnbWF4em9vbScgaW4gbGF5ZXIgJiYgem9vbSA+PSBsYXllci5tYXh6b29tKSB7XG4gICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XG4gICAgICB9XG5cbiAgICAgIHZhciBmaWx0ZXIgPSBsYXllci5maWx0ZXI7XG5cbiAgICAgIGlmICghZmlsdGVyIHx8IGV2YWx1YXRlRmlsdGVyKGxheWVySWQsIGZpbHRlciwgZiwgem9vbSkpIHtcbiAgICAgICAgZmVhdHVyZUJlbG9uZ3NUb0xheWVyID0gbGF5ZXI7XG4gICAgICAgIHZhciBjb2xvciA9IHZvaWQgMCxcbiAgICAgICAgICAgIG9wYWNpdHkgPSB2b2lkIDAsXG4gICAgICAgICAgICBmaWxsID0gdm9pZCAwLFxuICAgICAgICAgICAgc3Ryb2tlID0gdm9pZCAwLFxuICAgICAgICAgICAgc3Ryb2tlQ29sb3IgPSB2b2lkIDAsXG4gICAgICAgICAgICBzdHlsZSA9IHZvaWQgMDtcbiAgICAgICAgdmFyIGluZGV4ID0gbGF5ZXJEYXRhLmluZGV4O1xuXG4gICAgICAgIGlmICh0eXBlID09IDMgJiYgKGxheWVyLnR5cGUgPT0gJ2ZpbGwnIHx8IGxheWVyLnR5cGUgPT0gJ2ZpbGwtZXh0cnVzaW9uJykpIHtcbiAgICAgICAgICBvcGFjaXR5ID0gZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsIGxheWVyLnR5cGUgKyAnLW9wYWNpdHknLCB6b29tLCBmKTtcblxuICAgICAgICAgIGlmIChsYXllci50eXBlICsgJy1wYXR0ZXJuJyBpbiBwYWludCkge1xuICAgICAgICAgICAgdmFyIGZpbGxJY29uID0gZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsIGxheWVyLnR5cGUgKyAnLXBhdHRlcm4nLCB6b29tLCBmKTtcblxuICAgICAgICAgICAgaWYgKGZpbGxJY29uKSB7XG4gICAgICAgICAgICAgIHZhciBpY29uXzEgPSB0eXBlb2YgZmlsbEljb24gPT09ICdzdHJpbmcnID8gZnJvbVRlbXBsYXRlKGZpbGxJY29uLCBwcm9wZXJ0aWVzKSA6IGZpbGxJY29uLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgICAgICAgaWYgKHNwcml0ZUltYWdlICYmIHNwcml0ZURhdGEgJiYgc3ByaXRlRGF0YVtpY29uXzFdKSB7XG4gICAgICAgICAgICAgICAgKytzdHlsZXNMZW5ndGg7XG4gICAgICAgICAgICAgICAgc3R5bGUgPSBzdHlsZXNbc3R5bGVzTGVuZ3RoXTtcblxuICAgICAgICAgICAgICAgIGlmICghc3R5bGUgfHwgIXN0eWxlLmdldEZpbGwoKSB8fCBzdHlsZS5nZXRTdHJva2UoKSB8fCBzdHlsZS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW3N0eWxlc0xlbmd0aF0gPSBuZXcgU3R5bGUoe1xuICAgICAgICAgICAgICAgICAgICBmaWxsOiBuZXcgRmlsbCgpXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmaWxsID0gc3R5bGUuZ2V0RmlsbCgpO1xuICAgICAgICAgICAgICAgIHN0eWxlLnNldFpJbmRleChpbmRleCk7XG4gICAgICAgICAgICAgICAgdmFyIGljb25fY2FjaGVfa2V5ID0gaWNvbl8xICsgJy4nICsgb3BhY2l0eTtcbiAgICAgICAgICAgICAgICB2YXIgcGF0dGVybiA9IHBhdHRlcm5DYWNoZVtpY29uX2NhY2hlX2tleV07XG5cbiAgICAgICAgICAgICAgICBpZiAoIXBhdHRlcm4pIHtcbiAgICAgICAgICAgICAgICAgIHZhciBzcHJpdGVJbWFnZURhdGEgPSBzcHJpdGVEYXRhW2ljb25fMV07XG4gICAgICAgICAgICAgICAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKHNwcml0ZUltYWdlRGF0YS53aWR0aCwgc3ByaXRlSW1hZ2VEYXRhLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICB2YXIgY3R4ID1cbiAgICAgICAgICAgICAgICAgIC8qKiBAdHlwZSB7Q2FudmFzUmVuZGVyaW5nQ29udGV4dDJEfSAqL1xuICAgICAgICAgICAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICAgICAgICBjdHguZ2xvYmFsQWxwaGEgPSBvcGFjaXR5O1xuICAgICAgICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShzcHJpdGVJbWFnZSwgc3ByaXRlSW1hZ2VEYXRhLngsIHNwcml0ZUltYWdlRGF0YS55LCBzcHJpdGVJbWFnZURhdGEud2lkdGgsIHNwcml0ZUltYWdlRGF0YS5oZWlnaHQsIDAsIDAsIHNwcml0ZUltYWdlRGF0YS53aWR0aCwgc3ByaXRlSW1hZ2VEYXRhLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gY3R4LmNyZWF0ZVBhdHRlcm4oY2FudmFzLCAncmVwZWF0Jyk7XG4gICAgICAgICAgICAgICAgICBwYXR0ZXJuQ2FjaGVbaWNvbl9jYWNoZV9rZXldID0gcGF0dGVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmaWxsLnNldENvbG9yKHBhdHRlcm4pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbG9yID0gY29sb3JXaXRoT3BhY2l0eShnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgbGF5ZXIudHlwZSArICctY29sb3InLCB6b29tLCBmKSwgb3BhY2l0eSk7XG5cbiAgICAgICAgICAgIGlmIChjb2xvcikge1xuICAgICAgICAgICAgICBpZiAobGF5ZXIudHlwZSArICctb3V0bGluZS1jb2xvcicgaW4gcGFpbnQpIHtcbiAgICAgICAgICAgICAgICBzdHJva2VDb2xvciA9IGNvbG9yV2l0aE9wYWNpdHkoZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsIGxheWVyLnR5cGUgKyAnLW91dGxpbmUtY29sb3InLCB6b29tLCBmKSwgb3BhY2l0eSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoIXN0cm9rZUNvbG9yKSB7XG4gICAgICAgICAgICAgICAgc3Ryb2tlQ29sb3IgPSBjb2xvcjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICsrc3R5bGVzTGVuZ3RoO1xuICAgICAgICAgICAgICBzdHlsZSA9IHN0eWxlc1tzdHlsZXNMZW5ndGhdO1xuXG4gICAgICAgICAgICAgIGlmICghc3R5bGUgfHwgIShzdHlsZS5nZXRGaWxsKCkgJiYgc3R5bGUuZ2V0U3Ryb2tlKCkpIHx8IHN0eWxlLmdldFRleHQoKSkge1xuICAgICAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW3N0eWxlc0xlbmd0aF0gPSBuZXcgU3R5bGUoe1xuICAgICAgICAgICAgICAgICAgZmlsbDogbmV3IEZpbGwoKSxcbiAgICAgICAgICAgICAgICAgIHN0cm9rZTogbmV3IFN0cm9rZSgpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBmaWxsID0gc3R5bGUuZ2V0RmlsbCgpO1xuICAgICAgICAgICAgICBmaWxsLnNldENvbG9yKGNvbG9yKTtcbiAgICAgICAgICAgICAgc3Ryb2tlID0gc3R5bGUuZ2V0U3Ryb2tlKCk7XG4gICAgICAgICAgICAgIHN0cm9rZS5zZXRDb2xvcihzdHJva2VDb2xvcik7XG4gICAgICAgICAgICAgIHN0cm9rZS5zZXRXaWR0aCgxKTtcbiAgICAgICAgICAgICAgc3R5bGUuc2V0WkluZGV4KGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSAhPSAxICYmIGxheWVyLnR5cGUgPT0gJ2xpbmUnKSB7XG4gICAgICAgICAgY29sb3IgPSAhKCdsaW5lLXBhdHRlcm4nIGluIHBhaW50KSAmJiAnbGluZS1jb2xvcicgaW4gcGFpbnQgPyBjb2xvcldpdGhPcGFjaXR5KGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAnbGluZS1jb2xvcicsIHpvb20sIGYpLCBnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgJ2xpbmUtb3BhY2l0eScsIHpvb20sIGYpKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICB2YXIgd2lkdGhfMSA9IGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAnbGluZS13aWR0aCcsIHpvb20sIGYpO1xuXG4gICAgICAgICAgaWYgKGNvbG9yICYmIHdpZHRoXzEgPiAwKSB7XG4gICAgICAgICAgICArK3N0eWxlc0xlbmd0aDtcbiAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW3N0eWxlc0xlbmd0aF07XG5cbiAgICAgICAgICAgIGlmICghc3R5bGUgfHwgIXN0eWxlLmdldFN0cm9rZSgpIHx8IHN0eWxlLmdldEZpbGwoKSB8fCBzdHlsZS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgc3R5bGUgPSBzdHlsZXNbc3R5bGVzTGVuZ3RoXSA9IG5ldyBTdHlsZSh7XG4gICAgICAgICAgICAgICAgc3Ryb2tlOiBuZXcgU3Ryb2tlKClcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN0cm9rZSA9IHN0eWxlLmdldFN0cm9rZSgpO1xuICAgICAgICAgICAgc3Ryb2tlLnNldExpbmVDYXAoZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnbGluZS1jYXAnLCB6b29tLCBmKSk7XG4gICAgICAgICAgICBzdHJva2Uuc2V0TGluZUpvaW4oZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnbGluZS1qb2luJywgem9vbSwgZikpO1xuICAgICAgICAgICAgc3Ryb2tlLnNldE1pdGVyTGltaXQoZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnbGluZS1taXRlci1saW1pdCcsIHpvb20sIGYpKTtcbiAgICAgICAgICAgIHN0cm9rZS5zZXRDb2xvcihjb2xvcik7XG4gICAgICAgICAgICBzdHJva2Uuc2V0V2lkdGgod2lkdGhfMSk7XG4gICAgICAgICAgICBzdHJva2Uuc2V0TGluZURhc2gocGFpbnRbJ2xpbmUtZGFzaGFycmF5J10gPyBnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgJ2xpbmUtZGFzaGFycmF5Jywgem9vbSwgZikubWFwKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICAgIHJldHVybiB4ICogd2lkdGhfMTtcbiAgICAgICAgICAgIH0pIDogbnVsbCk7XG4gICAgICAgICAgICBzdHlsZS5zZXRaSW5kZXgoaW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYXNJbWFnZSA9IGZhbHNlO1xuICAgICAgICB2YXIgdGV4dCA9IG51bGw7XG4gICAgICAgIHZhciBwbGFjZW1lbnRBbmdsZSA9IDA7XG4gICAgICAgIHZhciBpY29uID0gdm9pZCAwLFxuICAgICAgICAgICAgaWNvbkltZyA9IHZvaWQgMCxcbiAgICAgICAgICAgIHNraXBMYWJlbCA9IHZvaWQgMDtcblxuICAgICAgICBpZiAoKHR5cGUgPT0gMSB8fCB0eXBlID09IDIpICYmICdpY29uLWltYWdlJyBpbiBsYXlvdXQpIHtcbiAgICAgICAgICB2YXIgaWNvbkltYWdlID0gZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnaWNvbi1pbWFnZScsIHpvb20sIGYpO1xuXG4gICAgICAgICAgaWYgKGljb25JbWFnZSkge1xuICAgICAgICAgICAgaWNvbiA9IHR5cGVvZiBpY29uSW1hZ2UgPT09ICdzdHJpbmcnID8gZnJvbVRlbXBsYXRlKGljb25JbWFnZSwgcHJvcGVydGllcykgOiBpY29uSW1hZ2UudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIHZhciBzdHlsZUdlb20gPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGlmIChzcHJpdGVJbWFnZSAmJiBzcHJpdGVEYXRhICYmIHNwcml0ZURhdGFbaWNvbl0pIHtcbiAgICAgICAgICAgICAgdmFyIGljb25Sb3RhdGlvbkFsaWdubWVudCA9IGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ2ljb24tcm90YXRpb24tYWxpZ25tZW50Jywgem9vbSwgZik7XG5cbiAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gMikge1xuICAgICAgICAgICAgICAgIHZhciBnZW9tID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpOyAvLyBvbCBwYWNrYWdlIGFuZCBvbC1kZWJ1Zy5qcyBvbmx5XG5cbiAgICAgICAgICAgICAgICBpZiAoZ2VvbS5nZXRGbGF0TWlkcG9pbnQgfHwgZ2VvbS5nZXRGbGF0TWlkcG9pbnRzKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgZXh0ZW50ID0gZ2VvbS5nZXRFeHRlbnQoKTtcbiAgICAgICAgICAgICAgICAgIHZhciBzaXplID0gTWF0aC5zcXJ0KE1hdGgubWF4KE1hdGgucG93KChleHRlbnRbMl0gLSBleHRlbnRbMF0pIC8gcmVzb2x1dGlvbiwgMiksIE1hdGgucG93KChleHRlbnRbM10gLSBleHRlbnRbMV0pIC8gcmVzb2x1dGlvbiwgMikpKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHNpemUgPiAxNTApIHtcbiAgICAgICAgICAgICAgICAgICAgLy9GSVhNRSBEbyBub3QgaGFyZC1jb2RlIGEgc2l6ZSBvZiAxNTBcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1pZHBvaW50ID0gZ2VvbS5nZXRUeXBlKCkgPT09ICdNdWx0aUxpbmVTdHJpbmcnID8gZ2VvbS5nZXRGbGF0TWlkcG9pbnRzKCkgOiBnZW9tLmdldEZsYXRNaWRwb2ludCgpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVuZGVyRmVhdHVyZSkge1xuICAgICAgICAgICAgICAgICAgICAgIHJlbmRlckZlYXR1cmVDb29yZGluYXRlcyA9IFtOYU4sIE5hTl07XG4gICAgICAgICAgICAgICAgICAgICAgcmVuZGVyRmVhdHVyZSA9IG5ldyBSZW5kZXJGZWF0dXJlKCdQb2ludCcsIHJlbmRlckZlYXR1cmVDb29yZGluYXRlcywgW10sIHt9LCBudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlR2VvbSA9IHJlbmRlckZlYXR1cmU7XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckZlYXR1cmVDb29yZGluYXRlc1swXSA9IG1pZHBvaW50WzBdO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJGZWF0dXJlQ29vcmRpbmF0ZXNbMV0gPSBtaWRwb2ludFsxXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBsYWNlbWVudCA9IGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ3N5bWJvbC1wbGFjZW1lbnQnLCB6b29tLCBmKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VtZW50ID09PSAnbGluZScgJiYgaWNvblJvdGF0aW9uQWxpZ25tZW50ID09PSAnbWFwJykge1xuICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJpZGUgPSBnZW9tLmdldFN0cmlkZSgpO1xuICAgICAgICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlcyA9IGdlb20uZ2V0RmxhdENvb3JkaW5hdGVzKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpXzEgPSAwLCBpaV8xID0gY29vcmRpbmF0ZXMubGVuZ3RoIC0gc3RyaWRlOyBpXzEgPCBpaV8xOyBpXzEgKz0gc3RyaWRlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgeDEgPSBjb29yZGluYXRlc1tpXzFdO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHkxID0gY29vcmRpbmF0ZXNbaV8xICsgMV07XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgeDIgPSBjb29yZGluYXRlc1tpXzEgKyBzdHJpZGVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHkyID0gY29vcmRpbmF0ZXNbaV8xICsgc3RyaWRlICsgMV07XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWluWCA9IE1hdGgubWluKHgxLCB4Mik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWluWSA9IE1hdGgubWluKHkxLCB5Mik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWF4WCA9IE1hdGgubWF4KHgxLCB4Mik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWF4WSA9IE1hdGgubWF4KHkxLCB5Mik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaWRwb2ludFswXSA+PSBtaW5YICYmIG1pZHBvaW50WzBdIDw9IG1heFggJiYgbWlkcG9pbnRbMV0gPj0gbWluWSAmJiBtaWRwb2ludFsxXSA8PSBtYXhZKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudEFuZ2xlID0gTWF0aC5hdGFuMih5MSAtIHkyLCB4MiAtIHgxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHR5cGUgIT09IDIgfHwgc3R5bGVHZW9tKSB7XG4gICAgICAgICAgICAgICAgdmFyIGljb25TaXplID0gZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnaWNvbi1zaXplJywgem9vbSwgZik7XG4gICAgICAgICAgICAgICAgdmFyIGljb25Db2xvciA9IHBhaW50WydpY29uLWNvbG9yJ10gIT09IHVuZGVmaW5lZCA/IGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAnaWNvbi1jb2xvcicsIHpvb20sIGYpIDogbnVsbDtcblxuICAgICAgICAgICAgICAgIGlmICghaWNvbkNvbG9yIHx8IGljb25Db2xvci5hICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgaWNvbl9jYWNoZV9rZXkgPSBpY29uICsgJy4nICsgaWNvblNpemU7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChpY29uQ29sb3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWNvbl9jYWNoZV9rZXkgKz0gJy4nICsgaWNvbkNvbG9yO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICBpY29uSW1nID0gaWNvbkltYWdlQ2FjaGVbaWNvbl9jYWNoZV9rZXldO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoIWljb25JbWcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwcml0ZUltYWdlRGF0YSA9IHNwcml0ZURhdGFbaWNvbl07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGljb25Db2xvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGN1dCBvdXQgdGhlIHNwcml0ZSBhbmQgY29sb3IgaXRcbiAgICAgICAgICAgICAgICAgICAgICB2YXIgY2FudmFzID0gY3JlYXRlQ2FudmFzKHNwcml0ZUltYWdlRGF0YS53aWR0aCwgc3ByaXRlSW1hZ2VEYXRhLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgICAgdmFyIGN0eCA9XG4gICAgICAgICAgICAgICAgICAgICAgLyoqIEB0eXBlIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9ICovXG4gICAgICAgICAgICAgICAgICAgICAgY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgY3R4LmRyYXdJbWFnZShzcHJpdGVJbWFnZSwgc3ByaXRlSW1hZ2VEYXRhLngsIHNwcml0ZUltYWdlRGF0YS55LCBzcHJpdGVJbWFnZURhdGEud2lkdGgsIHNwcml0ZUltYWdlRGF0YS5oZWlnaHQsIDAsIDAsIHNwcml0ZUltYWdlRGF0YS53aWR0aCwgc3ByaXRlSW1hZ2VEYXRhLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBjdHguZ2V0SW1hZ2VEYXRhKDAsIDAsIGNhbnZhcy53aWR0aCwgY2FudmFzLmhlaWdodCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBjID0gMCwgY2MgPSBkYXRhLmRhdGEubGVuZ3RoOyBjIDwgY2M7IGMgKz0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBpY29uQ29sb3IuYTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5kYXRhW2NdID0gaWNvbkNvbG9yLnIgKiAyNTUgLyBhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGFbYyArIDFdID0gaWNvbkNvbG9yLmcgKiAyNTUgLyBhO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGFbYyArIDJdID0gaWNvbkNvbG9yLmIgKiAyNTUgLyBhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGFbYyArIDNdID0gYTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBjdHgucHV0SW1hZ2VEYXRhKGRhdGEsIDAsIDApO1xuICAgICAgICAgICAgICAgICAgICAgIGljb25JbWcgPSBpY29uSW1hZ2VDYWNoZVtpY29uX2NhY2hlX2tleV0gPSBuZXcgSWNvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbWc6IGNhbnZhcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NpemU6IFtjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHRdLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGU6IGljb25TaXplIC8gc3ByaXRlSW1hZ2VEYXRhLnBpeGVsUmF0aW9cbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICBpY29uSW1nID0gaWNvbkltYWdlQ2FjaGVbaWNvbl9jYWNoZV9rZXldID0gbmV3IEljb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgaW1nOiBzcHJpdGVJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGltZ1NpemU6IHNwcml0ZUltZ1NpemUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplOiBbc3ByaXRlSW1hZ2VEYXRhLndpZHRoLCBzcHJpdGVJbWFnZURhdGEuaGVpZ2h0XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogW3Nwcml0ZUltYWdlRGF0YS54LCBzcHJpdGVJbWFnZURhdGEueV0sXG4gICAgICAgICAgICAgICAgICAgICAgICByb3RhdGVXaXRoVmlldzogaWNvblJvdGF0aW9uQWxpZ25tZW50ID09PSAnbWFwJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlOiBpY29uU2l6ZSAvIHNwcml0ZUltYWdlRGF0YS5waXhlbFJhdGlvXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoaWNvbkltZykge1xuICAgICAgICAgICAgICAgICAgKytzdHlsZXNMZW5ndGg7XG4gICAgICAgICAgICAgICAgICBzdHlsZSA9IHN0eWxlc1tzdHlsZXNMZW5ndGhdO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoIXN0eWxlIHx8ICFzdHlsZS5nZXRJbWFnZSgpIHx8IHN0eWxlLmdldEZpbGwoKSB8fCBzdHlsZS5nZXRTdHJva2UoKSkge1xuICAgICAgICAgICAgICAgICAgICBzdHlsZSA9IHN0eWxlc1tzdHlsZXNMZW5ndGhdID0gbmV3IFN0eWxlKCk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIHN0eWxlLnNldEdlb21ldHJ5KHN0eWxlR2VvbSk7XG4gICAgICAgICAgICAgICAgICBpY29uSW1nLnNldFJvdGF0aW9uKHBsYWNlbWVudEFuZ2xlICsgZGVnMnJhZChnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICdpY29uLXJvdGF0ZScsIHpvb20sIGYpKSk7XG4gICAgICAgICAgICAgICAgICBpY29uSW1nLnNldE9wYWNpdHkoZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICdpY29uLW9wYWNpdHknLCB6b29tLCBmKSk7XG4gICAgICAgICAgICAgICAgICBpY29uSW1nLnNldEFuY2hvcihhbmNob3JbZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAnaWNvbi1hbmNob3InLCB6b29tLCBmKV0pO1xuICAgICAgICAgICAgICAgICAgc3R5bGUuc2V0SW1hZ2UoaWNvbkltZyk7XG4gICAgICAgICAgICAgICAgICB0ZXh0ID0gc3R5bGUuZ2V0VGV4dCgpO1xuICAgICAgICAgICAgICAgICAgc3R5bGUuc2V0VGV4dCh1bmRlZmluZWQpO1xuICAgICAgICAgICAgICAgICAgc3R5bGUuc2V0WkluZGV4KGluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGhhc0ltYWdlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHNraXBMYWJlbCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBza2lwTGFiZWwgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGUgPT0gMSAmJiAnY2lyY2xlLXJhZGl1cycgaW4gcGFpbnQpIHtcbiAgICAgICAgICArK3N0eWxlc0xlbmd0aDtcbiAgICAgICAgICBzdHlsZSA9IHN0eWxlc1tzdHlsZXNMZW5ndGhdO1xuXG4gICAgICAgICAgaWYgKCFzdHlsZSB8fCAhc3R5bGUuZ2V0SW1hZ2UoKSB8fCBzdHlsZS5nZXRGaWxsKCkgfHwgc3R5bGUuZ2V0U3Ryb2tlKCkpIHtcbiAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW3N0eWxlc0xlbmd0aF0gPSBuZXcgU3R5bGUoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgY2lyY2xlUmFkaXVzID0gZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICdjaXJjbGUtcmFkaXVzJywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIGNpcmNsZVN0cm9rZUNvbG9yID0gY29sb3JXaXRoT3BhY2l0eShnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgJ2NpcmNsZS1zdHJva2UtY29sb3InLCB6b29tLCBmKSwgZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICdjaXJjbGUtc3Ryb2tlLW9wYWNpdHknLCB6b29tLCBmKSk7XG4gICAgICAgICAgdmFyIGNpcmNsZUNvbG9yID0gY29sb3JXaXRoT3BhY2l0eShnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgJ2NpcmNsZS1jb2xvcicsIHpvb20sIGYpLCBnZXRWYWx1ZShsYXllciwgJ3BhaW50JywgJ2NpcmNsZS1vcGFjaXR5Jywgem9vbSwgZikpO1xuICAgICAgICAgIHZhciBjaXJjbGVTdHJva2VXaWR0aCA9IGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAnY2lyY2xlLXN0cm9rZS13aWR0aCcsIHpvb20sIGYpO1xuICAgICAgICAgIHZhciBjYWNoZV9rZXkgPSBjaXJjbGVSYWRpdXMgKyAnLicgKyBjaXJjbGVTdHJva2VDb2xvciArICcuJyArIGNpcmNsZUNvbG9yICsgJy4nICsgY2lyY2xlU3Ryb2tlV2lkdGg7XG4gICAgICAgICAgaWNvbkltZyA9IGljb25JbWFnZUNhY2hlW2NhY2hlX2tleV07XG5cbiAgICAgICAgICBpZiAoIWljb25JbWcpIHtcbiAgICAgICAgICAgIGljb25JbWcgPSBpY29uSW1hZ2VDYWNoZVtjYWNoZV9rZXldID0gbmV3IENpcmNsZSh7XG4gICAgICAgICAgICAgIHJhZGl1czogY2lyY2xlUmFkaXVzLFxuICAgICAgICAgICAgICBzdHJva2U6IGNpcmNsZVN0cm9rZUNvbG9yICYmIGNpcmNsZVN0cm9rZVdpZHRoID4gMCA/IG5ldyBTdHJva2Uoe1xuICAgICAgICAgICAgICAgIHdpZHRoOiBjaXJjbGVTdHJva2VXaWR0aCxcbiAgICAgICAgICAgICAgICBjb2xvcjogY2lyY2xlU3Ryb2tlQ29sb3JcbiAgICAgICAgICAgICAgfSkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGZpbGw6IGNpcmNsZUNvbG9yID8gbmV3IEZpbGwoe1xuICAgICAgICAgICAgICAgIGNvbG9yOiBjaXJjbGVDb2xvclxuICAgICAgICAgICAgICB9KSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3R5bGUuc2V0SW1hZ2UoaWNvbkltZyk7XG4gICAgICAgICAgdGV4dCA9IHN0eWxlLmdldFRleHQoKTtcbiAgICAgICAgICBzdHlsZS5zZXRUZXh0KHVuZGVmaW5lZCk7XG4gICAgICAgICAgc3R5bGUuc2V0R2VvbWV0cnkodW5kZWZpbmVkKTtcbiAgICAgICAgICBzdHlsZS5zZXRaSW5kZXgoaW5kZXgpO1xuICAgICAgICAgIGhhc0ltYWdlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsYWJlbCA9IHZvaWQgMDtcblxuICAgICAgICBpZiAoJ3RleHQtZmllbGQnIGluIGxheW91dCkge1xuICAgICAgICAgIHZhciB0ZXh0RmllbGQgPSBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICd0ZXh0LWZpZWxkJywgem9vbSwgZikudG9TdHJpbmcoKTtcbiAgICAgICAgICBsYWJlbCA9IGZyb21UZW1wbGF0ZSh0ZXh0RmllbGQsIHByb3BlcnRpZXMpLnRyaW0oKTtcbiAgICAgICAgICBvcGFjaXR5ID0gZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICd0ZXh0LW9wYWNpdHknLCB6b29tLCBmKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsYWJlbCAmJiBvcGFjaXR5ICYmICFza2lwTGFiZWwpIHtcbiAgICAgICAgICBpZiAoIWhhc0ltYWdlKSB7XG4gICAgICAgICAgICArK3N0eWxlc0xlbmd0aDtcbiAgICAgICAgICAgIHN0eWxlID0gc3R5bGVzW3N0eWxlc0xlbmd0aF07XG5cbiAgICAgICAgICAgIGlmICghc3R5bGUgfHwgIXN0eWxlLmdldFRleHQoKSB8fCBzdHlsZS5nZXRGaWxsKCkgfHwgc3R5bGUuZ2V0U3Ryb2tlKCkpIHtcbiAgICAgICAgICAgICAgc3R5bGUgPSBzdHlsZXNbc3R5bGVzTGVuZ3RoXSA9IG5ldyBTdHlsZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzdHlsZS5zZXRJbWFnZSh1bmRlZmluZWQpO1xuICAgICAgICAgICAgc3R5bGUuc2V0R2VvbWV0cnkodW5kZWZpbmVkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXN0eWxlLmdldFRleHQoKSkge1xuICAgICAgICAgICAgc3R5bGUuc2V0VGV4dCh0ZXh0IHx8IG5ldyBUZXh0KHtcbiAgICAgICAgICAgICAgcGFkZGluZzogWzIsIDIsIDIsIDJdXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGV4dCA9IHN0eWxlLmdldFRleHQoKTtcbiAgICAgICAgICB2YXIgdGV4dFNpemUgPSBNYXRoLnJvdW5kKGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ3RleHQtc2l6ZScsIHpvb20sIGYpKTtcbiAgICAgICAgICB2YXIgZm9udEFycmF5ID0gZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAndGV4dC1mb250Jywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIHRleHRMaW5lSGVpZ2h0ID0gZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAndGV4dC1saW5lLWhlaWdodCcsIHpvb20sIGYpO1xuICAgICAgICAgIHZhciBmb250ID0gbWIyY3NzKGdldEZvbnRzID8gZ2V0Rm9udHMoZm9udEFycmF5KSA6IGZvbnRBcnJheSwgdGV4dFNpemUsIHRleHRMaW5lSGVpZ2h0KTtcbiAgICAgICAgICB2YXIgdGV4dFRyYW5zZm9ybSA9IGxheW91dFsndGV4dC10cmFuc2Zvcm0nXTtcblxuICAgICAgICAgIGlmICh0ZXh0VHJhbnNmb3JtID09ICd1cHBlcmNhc2UnKSB7XG4gICAgICAgICAgICBsYWJlbCA9IGxhYmVsLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0ZXh0VHJhbnNmb3JtID09ICdsb3dlcmNhc2UnKSB7XG4gICAgICAgICAgICBsYWJlbCA9IGxhYmVsLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdmFyIG1heFRleHRXaWR0aCA9IGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ3RleHQtbWF4LXdpZHRoJywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIGxldHRlclNwYWNpbmcgPSBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICd0ZXh0LWxldHRlci1zcGFjaW5nJywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIHdyYXBwZWRMYWJlbCA9IHR5cGUgPT0gMiA/IGFwcGx5TGV0dGVyU3BhY2luZyhsYWJlbCwgbGV0dGVyU3BhY2luZykgOiB3cmFwVGV4dChsYWJlbCwgZm9udCwgbWF4VGV4dFdpZHRoLCBsZXR0ZXJTcGFjaW5nKTtcbiAgICAgICAgICB0ZXh0LnNldFRleHQod3JhcHBlZExhYmVsKTtcbiAgICAgICAgICB0ZXh0LnNldEZvbnQoZm9udCk7XG4gICAgICAgICAgdGV4dC5zZXRSb3RhdGlvbihkZWcycmFkKGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ3RleHQtcm90YXRlJywgem9vbSwgZikpKTtcbiAgICAgICAgICB2YXIgdGV4dEFuY2hvciA9IGdldFZhbHVlKGxheWVyLCAnbGF5b3V0JywgJ3RleHQtYW5jaG9yJywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIHBsYWNlbWVudCA9IGhhc0ltYWdlIHx8IHR5cGUgPT0gMSA/ICdwb2ludCcgOiBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICdzeW1ib2wtcGxhY2VtZW50Jywgem9vbSwgZik7XG4gICAgICAgICAgdGV4dC5zZXRQbGFjZW1lbnQocGxhY2VtZW50KTtcbiAgICAgICAgICB2YXIgdGV4dEhhbG9XaWR0aCA9IGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAndGV4dC1oYWxvLXdpZHRoJywgem9vbSwgZik7XG4gICAgICAgICAgdmFyIHRleHRPZmZzZXQgPSBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICd0ZXh0LW9mZnNldCcsIHpvb20sIGYpO1xuICAgICAgICAgIHZhciB0ZXh0VHJhbnNsYXRlID0gZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICd0ZXh0LXRyYW5zbGF0ZScsIHpvb20sIGYpOyAvLyBUZXh0IG9mZnNldCBoYXMgdG8gdGFrZSBoYWxvIHdpZHRoIGFuZCBsaW5lIGhlaWdodCBpbnRvIGFjY291bnRcblxuICAgICAgICAgIHZhciB2T2Zmc2V0ID0gMDtcbiAgICAgICAgICB2YXIgaE9mZnNldCA9IDA7XG5cbiAgICAgICAgICBpZiAocGxhY2VtZW50ID09ICdwb2ludCcpIHtcbiAgICAgICAgICAgIHZhciB0ZXh0QWxpZ24gPSAnY2VudGVyJztcblxuICAgICAgICAgICAgaWYgKHRleHRBbmNob3IuaW5kZXhPZignbGVmdCcpICE9PSAtMSkge1xuICAgICAgICAgICAgICB0ZXh0QWxpZ24gPSAnbGVmdCc7XG4gICAgICAgICAgICAgIGhPZmZzZXQgPSB0ZXh0SGFsb1dpZHRoO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0ZXh0QW5jaG9yLmluZGV4T2YoJ3JpZ2h0JykgIT09IC0xKSB7XG4gICAgICAgICAgICAgIHRleHRBbGlnbiA9ICdyaWdodCc7XG4gICAgICAgICAgICAgIGhPZmZzZXQgPSAtdGV4dEhhbG9XaWR0aDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGV4dC5zZXRUZXh0QWxpZ24odGV4dEFsaWduKTtcbiAgICAgICAgICAgIHZhciB0ZXh0Um90YXRpb25BbGlnbm1lbnQgPSBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICd0ZXh0LXJvdGF0aW9uLWFsaWdubWVudCcsIHpvb20sIGYpO1xuICAgICAgICAgICAgdGV4dC5zZXRSb3RhdGVXaXRoVmlldyh0ZXh0Um90YXRpb25BbGlnbm1lbnQgPT0gJ21hcCcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ZXh0LnNldE1heEFuZ2xlKGRlZzJyYWQoZ2V0VmFsdWUobGF5ZXIsICdsYXlvdXQnLCAndGV4dC1tYXgtYW5nbGUnLCB6b29tLCBmKSkgKiBsYWJlbC5sZW5ndGggLyB3cmFwcGVkTGFiZWwubGVuZ3RoKTtcbiAgICAgICAgICAgIHRleHQuc2V0VGV4dEFsaWduKCk7XG4gICAgICAgICAgICB0ZXh0LnNldFJvdGF0ZVdpdGhWaWV3KGZhbHNlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgdGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XG5cbiAgICAgICAgICBpZiAodGV4dEFuY2hvci5pbmRleE9mKCdib3R0b20nKSA9PSAwKSB7XG4gICAgICAgICAgICB0ZXh0QmFzZWxpbmUgPSAnYm90dG9tJztcbiAgICAgICAgICAgIHZPZmZzZXQgPSAtdGV4dEhhbG9XaWR0aCAtIDAuNSAqICh0ZXh0TGluZUhlaWdodCAtIDEpICogdGV4dFNpemU7XG4gICAgICAgICAgfSBlbHNlIGlmICh0ZXh0QW5jaG9yLmluZGV4T2YoJ3RvcCcpID09IDApIHtcbiAgICAgICAgICAgIHRleHRCYXNlbGluZSA9ICd0b3AnO1xuICAgICAgICAgICAgdk9mZnNldCA9IHRleHRIYWxvV2lkdGggKyAwLjUgKiAodGV4dExpbmVIZWlnaHQgLSAxKSAqIHRleHRTaXplO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRleHQuc2V0VGV4dEJhc2VsaW5lKHRleHRCYXNlbGluZSk7XG4gICAgICAgICAgdGV4dC5zZXRPZmZzZXRYKHRleHRPZmZzZXRbMF0gKiB0ZXh0U2l6ZSArIGhPZmZzZXQgKyB0ZXh0VHJhbnNsYXRlWzBdKTtcbiAgICAgICAgICB0ZXh0LnNldE9mZnNldFkodGV4dE9mZnNldFsxXSAqIHRleHRTaXplICsgdk9mZnNldCArIHRleHRUcmFuc2xhdGVbMV0pO1xuICAgICAgICAgIHRleHRDb2xvci5zZXRDb2xvcihjb2xvcldpdGhPcGFjaXR5KGdldFZhbHVlKGxheWVyLCAncGFpbnQnLCAndGV4dC1jb2xvcicsIHpvb20sIGYpLCBvcGFjaXR5KSk7XG4gICAgICAgICAgdGV4dC5zZXRGaWxsKHRleHRDb2xvcik7XG4gICAgICAgICAgdmFyIGhhbG9Db2xvciA9IGNvbG9yV2l0aE9wYWNpdHkoZ2V0VmFsdWUobGF5ZXIsICdwYWludCcsICd0ZXh0LWhhbG8tY29sb3InLCB6b29tLCBmKSwgb3BhY2l0eSk7XG5cbiAgICAgICAgICBpZiAoaGFsb0NvbG9yKSB7XG4gICAgICAgICAgICB0ZXh0SGFsby5zZXRDb2xvcihoYWxvQ29sb3IpOyAvLyBzcGVjIGhlcmUgOiBodHRwczovL2RvY3MubWFwYm94LmNvbS9tYXBib3gtZ2wtanMvc3R5bGUtc3BlYy8jcGFpbnQtc3ltYm9sLXRleHQtaGFsby13aWR0aFxuICAgICAgICAgICAgLy8gSGFsbyB3aWR0aCBtdXN0IGJlIGRvdWJsZWQgYmVjYXVzZSBpdCBpcyBhcHBsaWVkIGFyb3VuZCB0aGUgY2VudGVyIG9mIHRoZSB0ZXh0IG91dGxpbmVcblxuICAgICAgICAgICAgdGV4dEhhbG9XaWR0aCAqPSAyOyAvLyAxLzQgb2YgdGV4dCBzaXplIChzcGVjKSB4IDJcblxuICAgICAgICAgICAgdmFyIGhhbGZUZXh0U2l6ZSA9IDAuNSAqIHRleHRTaXplO1xuICAgICAgICAgICAgdGV4dEhhbG8uc2V0V2lkdGgodGV4dEhhbG9XaWR0aCA8PSBoYWxmVGV4dFNpemUgPyB0ZXh0SGFsb1dpZHRoIDogaGFsZlRleHRTaXplKTtcbiAgICAgICAgICAgIHRleHQuc2V0U3Ryb2tlKHRleHRIYWxvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGV4dC5zZXRTdHJva2UodW5kZWZpbmVkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgdGV4dFBhZGRpbmcgPSBnZXRWYWx1ZShsYXllciwgJ2xheW91dCcsICd0ZXh0LXBhZGRpbmcnLCB6b29tLCBmKTtcbiAgICAgICAgICB2YXIgcGFkZGluZyA9IHRleHQuZ2V0UGFkZGluZygpO1xuXG4gICAgICAgICAgaWYgKHRleHRQYWRkaW5nICE9PSBwYWRkaW5nWzBdKSB7XG4gICAgICAgICAgICBwYWRkaW5nWzBdID0gcGFkZGluZ1sxXSA9IHBhZGRpbmdbMl0gPSBwYWRkaW5nWzNdID0gdGV4dFBhZGRpbmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3R5bGUuc2V0WkluZGV4KGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllcnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgX2xvb3BfMShpLCBpaSk7XG4gICAgfVxuXG4gICAgaWYgKHN0eWxlc0xlbmd0aCA+IC0xKSB7XG4gICAgICBzdHlsZXMubGVuZ3RoID0gc3R5bGVzTGVuZ3RoICsgMTtcblxuICAgICAgaWYgKHJlY29yZExheWVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZmVhdHVyZS5zZXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAvLyBvbC9GZWF0dXJlXG4gICAgICAgICAgZmVhdHVyZS5zZXQoJ21hcGJveC1sYXllcicsIGZlYXR1cmVCZWxvbmdzVG9MYXllcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gb2wvcmVuZGVyL0ZlYXR1cmVcbiAgICAgICAgICBmZWF0dXJlLmdldFByb3BlcnRpZXMoKVsnbWFwYm94LWxheWVyJ10gPSBmZWF0dXJlQmVsb25nc1RvTGF5ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN0eWxlcztcbiAgICB9XG4gIH07XG5cbiAgb2xMYXllci5zZXRTdHlsZShzdHlsZUZ1bmN0aW9uKTtcbiAgb2xMYXllci5zZXQoJ21hcGJveC1zb3VyY2UnLCBtYXBib3hTb3VyY2UpO1xuICBvbExheWVyLnNldCgnbWFwYm94LWxheWVycycsIG1hcGJveExheWVycyk7XG4gIHJldHVybiBzdHlsZUZ1bmN0aW9uO1xufVxuZXhwb3J0IHsgY29sb3JXaXRoT3BhY2l0eSBhcyBfY29sb3JXaXRoT3BhY2l0eSwgZmlsdGVyQ2FjaGUgYXMgX2ZpbHRlckNhY2hlLCBldmFsdWF0ZUZpbHRlciBhcyBfZXZhbHVhdGVGaWx0ZXIsIGZyb21UZW1wbGF0ZSBhcyBfZnJvbVRlbXBsYXRlLCBnZXRWYWx1ZSBhcyBfZ2V0VmFsdWUsIGZ1bmN0aW9uQ2FjaGUgYXMgX2Z1bmN0aW9uQ2FjaGUgfTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvVGlsZVJhbmdlXG4gKi9cblxuLyoqXG4gKiBBIHJlcHJlc2VudGF0aW9uIG9mIGEgY29udGlndW91cyBibG9jayBvZiB0aWxlcy4gIEEgdGlsZSByYW5nZSBpcyBzcGVjaWZpZWRcbiAqIGJ5IGl0cyBtaW4vbWF4IHRpbGUgY29vcmRpbmF0ZXMgYW5kIGlzIGluY2x1c2l2ZSBvZiBjb29yZGluYXRlcy5cbiAqL1xudmFyIFRpbGVSYW5nZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluWCBNaW5pbXVtIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYIE1heGltdW0gWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblkgTWluaW11bSBZLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4WSBNYXhpbXVtIFkuXG4gICAqL1xuICBmdW5jdGlvbiBUaWxlUmFuZ2UobWluWCwgbWF4WCwgbWluWSwgbWF4WSkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5taW5YID0gbWluWDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5tYXhYID0gbWF4WDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5taW5ZID0gbWluWTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5tYXhZID0gbWF4WTtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zIHRpbGUgY29vcmRpbmF0ZS5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gKHRpbGVDb29yZCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRhaW5zWFkodGlsZUNvb3JkWzFdLCB0aWxlQ29vcmRbMl0pO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtUaWxlUmFuZ2V9IHRpbGVSYW5nZSBUaWxlIHJhbmdlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDb250YWlucy5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmNvbnRhaW5zVGlsZVJhbmdlID0gZnVuY3Rpb24gKHRpbGVSYW5nZSkge1xuICAgIHJldHVybiB0aGlzLm1pblggPD0gdGlsZVJhbmdlLm1pblggJiYgdGlsZVJhbmdlLm1heFggPD0gdGhpcy5tYXhYICYmIHRoaXMubWluWSA8PSB0aWxlUmFuZ2UubWluWSAmJiB0aWxlUmFuZ2UubWF4WSA8PSB0aGlzLm1heFk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zIGNvb3JkaW5hdGUuXG4gICAqL1xuXG5cbiAgVGlsZVJhbmdlLnByb3RvdHlwZS5jb250YWluc1hZID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICByZXR1cm4gdGhpcy5taW5YIDw9IHggJiYgeCA8PSB0aGlzLm1heFggJiYgdGhpcy5taW5ZIDw9IHkgJiYgeSA8PSB0aGlzLm1heFk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RpbGVSYW5nZX0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IEVxdWFscy5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uICh0aWxlUmFuZ2UpIHtcbiAgICByZXR1cm4gdGhpcy5taW5YID09IHRpbGVSYW5nZS5taW5YICYmIHRoaXMubWluWSA9PSB0aWxlUmFuZ2UubWluWSAmJiB0aGlzLm1heFggPT0gdGlsZVJhbmdlLm1heFggJiYgdGhpcy5tYXhZID09IHRpbGVSYW5nZS5tYXhZO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtUaWxlUmFuZ2V9IHRpbGVSYW5nZSBUaWxlIHJhbmdlLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuZXh0ZW5kID0gZnVuY3Rpb24gKHRpbGVSYW5nZSkge1xuICAgIGlmICh0aWxlUmFuZ2UubWluWCA8IHRoaXMubWluWCkge1xuICAgICAgdGhpcy5taW5YID0gdGlsZVJhbmdlLm1pblg7XG4gICAgfVxuXG4gICAgaWYgKHRpbGVSYW5nZS5tYXhYID4gdGhpcy5tYXhYKSB7XG4gICAgICB0aGlzLm1heFggPSB0aWxlUmFuZ2UubWF4WDtcbiAgICB9XG5cbiAgICBpZiAodGlsZVJhbmdlLm1pblkgPCB0aGlzLm1pblkpIHtcbiAgICAgIHRoaXMubWluWSA9IHRpbGVSYW5nZS5taW5ZO1xuICAgIH1cblxuICAgIGlmICh0aWxlUmFuZ2UubWF4WSA+IHRoaXMubWF4WSkge1xuICAgICAgdGhpcy5tYXhZID0gdGlsZVJhbmdlLm1heFk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBIZWlnaHQuXG4gICAqL1xuXG5cbiAgVGlsZVJhbmdlLnByb3RvdHlwZS5nZXRIZWlnaHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubWF4WSAtIHRoaXMubWluWSArIDE7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gU2l6ZS5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmdldFNpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFt0aGlzLmdldFdpZHRoKCksIHRoaXMuZ2V0SGVpZ2h0KCldO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBXaWR0aC5cbiAgICovXG5cblxuICBUaWxlUmFuZ2UucHJvdG90eXBlLmdldFdpZHRoID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1heFggLSB0aGlzLm1pblggKyAxO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtUaWxlUmFuZ2V9IHRpbGVSYW5nZSBUaWxlIHJhbmdlLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBJbnRlcnNlY3RzLlxuICAgKi9cblxuXG4gIFRpbGVSYW5nZS5wcm90b3R5cGUuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uICh0aWxlUmFuZ2UpIHtcbiAgICByZXR1cm4gdGhpcy5taW5YIDw9IHRpbGVSYW5nZS5tYXhYICYmIHRoaXMubWF4WCA+PSB0aWxlUmFuZ2UubWluWCAmJiB0aGlzLm1pblkgPD0gdGlsZVJhbmdlLm1heFkgJiYgdGhpcy5tYXhZID49IHRpbGVSYW5nZS5taW5ZO1xuICB9O1xuXG4gIHJldHVybiBUaWxlUmFuZ2U7XG59KCk7XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5YIE1pbmltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYIE1heGltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5ZIE1pbmltdW0gWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhZIE1heGltdW0gWS5cbiAqIEBwYXJhbSB7VGlsZVJhbmdlPX0gdGlsZVJhbmdlIFRpbGVSYW5nZS5cbiAqIEByZXR1cm4ge1RpbGVSYW5nZX0gVGlsZSByYW5nZS5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZShtaW5YLCBtYXhYLCBtaW5ZLCBtYXhZLCB0aWxlUmFuZ2UpIHtcbiAgaWYgKHRpbGVSYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdGlsZVJhbmdlLm1pblggPSBtaW5YO1xuICAgIHRpbGVSYW5nZS5tYXhYID0gbWF4WDtcbiAgICB0aWxlUmFuZ2UubWluWSA9IG1pblk7XG4gICAgdGlsZVJhbmdlLm1heFkgPSBtYXhZO1xuICAgIHJldHVybiB0aWxlUmFuZ2U7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBUaWxlUmFuZ2UobWluWCwgbWF4WCwgbWluWSwgbWF4WSk7XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IFRpbGVSYW5nZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvdGlsZWNvb3JkXG4gKi9cblxuLyoqXG4gKiBBbiBhcnJheSBvZiB0aHJlZSBudW1iZXJzIHJlcHJlc2VudGluZyB0aGUgbG9jYXRpb24gb2YgYSB0aWxlIGluIGEgdGlsZVxuICogZ3JpZC4gVGhlIG9yZGVyIGlzIGB6YCAoem9vbSBsZXZlbCksIGB4YCAoY29sdW1uKSwgYW5kIGB5YCAocm93KS5cbiAqIEB0eXBlZGVmIHtBcnJheTxudW1iZXI+fSBUaWxlQ29vcmRcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7VGlsZUNvb3JkPX0gb3B0X3RpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtUaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlKHosIHgsIHksIG9wdF90aWxlQ29vcmQpIHtcbiAgaWYgKG9wdF90aWxlQ29vcmQgIT09IHVuZGVmaW5lZCkge1xuICAgIG9wdF90aWxlQ29vcmRbMF0gPSB6O1xuICAgIG9wdF90aWxlQ29vcmRbMV0gPSB4O1xuICAgIG9wdF90aWxlQ29vcmRbMl0gPSB5O1xuICAgIHJldHVybiBvcHRfdGlsZUNvb3JkO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbeiwgeCwgeV07XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHogWi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7c3RyaW5nfSBLZXkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEtleVpYWSh6LCB4LCB5KSB7XG4gIHJldHVybiB6ICsgJy8nICsgeCArICcvJyArIHk7XG59XG4vKipcbiAqIEdldCB0aGUga2V5IGZvciBhIHRpbGUgY29vcmQuXG4gKiBAcGFyYW0ge1RpbGVDb29yZH0gdGlsZUNvb3JkIFRoZSB0aWxlIGNvb3JkLlxuICogQHJldHVybiB7c3RyaW5nfSBLZXkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEtleSh0aWxlQ29vcmQpIHtcbiAgcmV0dXJuIGdldEtleVpYWSh0aWxlQ29vcmRbMF0sIHRpbGVDb29yZFsxXSwgdGlsZUNvb3JkWzJdKTtcbn1cbi8qKlxuICogR2V0IGEgdGlsZSBjb29yZCBnaXZlbiBhIGtleS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHRpbGUgY29vcmQga2V5LlxuICogQHJldHVybiB7VGlsZUNvb3JkfSBUaGUgdGlsZSBjb29yZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbUtleShrZXkpIHtcbiAgcmV0dXJuIGtleS5zcGxpdCgnLycpLm1hcChOdW1iZXIpO1xufVxuLyoqXG4gKiBAcGFyYW0ge1RpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEhhc2guXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc2godGlsZUNvb3JkKSB7XG4gIHJldHVybiAodGlsZUNvb3JkWzFdIDw8IHRpbGVDb29yZFswXSkgKyB0aWxlQ29vcmRbMl07XG59XG4vKipcbiAqIEBwYXJhbSB7VGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICogQHBhcmFtIHshaW1wb3J0KFwiLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0aWxlR3JpZCBUaWxlIGdyaWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaWxlIGNvb3JkaW5hdGUgaXMgd2l0aGluIGV4dGVudCBhbmQgem9vbSBsZXZlbCByYW5nZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gd2l0aGluRXh0ZW50QW5kWih0aWxlQ29vcmQsIHRpbGVHcmlkKSB7XG4gIHZhciB6ID0gdGlsZUNvb3JkWzBdO1xuICB2YXIgeCA9IHRpbGVDb29yZFsxXTtcbiAgdmFyIHkgPSB0aWxlQ29vcmRbMl07XG5cbiAgaWYgKHRpbGVHcmlkLmdldE1pblpvb20oKSA+IHogfHwgeiA+IHRpbGVHcmlkLmdldE1heFpvb20oKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciB0aWxlUmFuZ2UgPSB0aWxlR3JpZC5nZXRGdWxsVGlsZVJhbmdlKHopO1xuXG4gIGlmICghdGlsZVJhbmdlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRpbGVSYW5nZS5jb250YWluc1hZKHgsIHkpO1xuICB9XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3RpbGVncmlkL1RpbGVHcmlkXG4gKi9cbmltcG9ydCBUaWxlUmFuZ2UsIHsgY3JlYXRlT3JVcGRhdGUgYXMgY3JlYXRlT3JVcGRhdGVUaWxlUmFuZ2UgfSBmcm9tICcuLi9UaWxlUmFuZ2UuanMnO1xuaW1wb3J0IHsgREVGQVVMVF9USUxFX1NJWkUgfSBmcm9tICcuL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi4vbWF0aC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVPclVwZGF0ZSwgZ2V0VG9wTGVmdCB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVPclVwZGF0ZSBhcyBjcmVhdGVPclVwZGF0ZVRpbGVDb29yZCB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBpc1NvcnRlZCwgbGluZWFyRmluZE5lYXJlc3QgfSBmcm9tICcuLi9hcnJheS5qcyc7XG5pbXBvcnQgeyB0b1NpemUgfSBmcm9tICcuLi9zaXplLmpzJztcbi8qKlxuICogQHByaXZhdGVcbiAqIEB0eXBlIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfVxuICovXG5cbnZhciB0bXBUaWxlQ29vcmQgPSBbMCwgMCwgMF07XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gRXh0ZW50IGZvciB0aGUgdGlsZSBncmlkLiBObyB0aWxlcyBvdXRzaWRlIHRoaXNcbiAqIGV4dGVudCB3aWxsIGJlIHJlcXVlc3RlZCBieSB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9UaWxlfSBzb3VyY2VzLiBXaGVuIG5vIGBvcmlnaW5gIG9yXG4gKiBgb3JpZ2luc2AgYXJlIGNvbmZpZ3VyZWQsIHRoZSBgb3JpZ2luYCB3aWxsIGJlIHNldCB0byB0aGUgdG9wLWxlZnQgY29ybmVyIG9mIHRoZSBleHRlbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb209MF0gTWluaW11bSB6b29tLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFtvcmlnaW5dIFRoZSB0aWxlIGdyaWQgb3JpZ2luLCBpLmUuIHdoZXJlIHRoZSBgeGBcbiAqIGFuZCBgeWAgYXhlcyBtZWV0IChgW3osIDAsIDBdYCkuIFRpbGUgY29vcmRpbmF0ZXMgaW5jcmVhc2UgbGVmdCB0byByaWdodCBhbmQgZG93bndhcmRzLiBJZiBub3RcbiAqIHNwZWNpZmllZCwgYGV4dGVudGAgb3IgYG9yaWdpbnNgIG11c3QgYmUgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IFtvcmlnaW5zXSBUaWxlIGdyaWQgb3JpZ2lucywgaS5lLiB3aGVyZVxuICogdGhlIGB4YCBhbmQgYHlgIGF4ZXMgbWVldCAoYFt6LCAwLCAwXWApLCBmb3IgZWFjaCB6b29tIGxldmVsLiBJZiBnaXZlbiwgdGhlIGFycmF5IGxlbmd0aFxuICogc2hvdWxkIG1hdGNoIHRoZSBsZW5ndGggb2YgdGhlIGByZXNvbHV0aW9uc2AgYXJyYXksIGkuZS4gZWFjaCByZXNvbHV0aW9uIGNhbiBoYXZlIGEgZGlmZmVyZW50XG4gKiBvcmlnaW4uIFRpbGUgY29vcmRpbmF0ZXMgaW5jcmVhc2UgbGVmdCB0byByaWdodCBhbmQgZG93bndhcmRzLiBJZiBub3Qgc3BlY2lmaWVkLCBgZXh0ZW50YCBvclxuICogYG9yaWdpbmAgbXVzdCBiZSBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7IUFycmF5PG51bWJlcj59IHJlc29sdXRpb25zIFJlc29sdXRpb25zLiBUaGUgYXJyYXkgaW5kZXggb2YgZWFjaCByZXNvbHV0aW9uIG5lZWRzXG4gKiB0byBtYXRjaCB0aGUgem9vbSBsZXZlbC4gVGhpcyBtZWFucyB0aGF0IGV2ZW4gaWYgYSBgbWluWm9vbWAgaXMgY29uZmlndXJlZCwgdGhlIHJlc29sdXRpb25zXG4gKiBhcnJheSB3aWxsIGhhdmUgYSBsZW5ndGggb2YgYG1heFpvb20gKyAxYC5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplPn0gW3NpemVzXSBOdW1iZXIgb2YgdGlsZSByb3dzIGFuZCBjb2x1bW5zXG4gKiBvZiB0aGUgZ3JpZCBmb3IgZWFjaCB6b29tIGxldmVsLiBJZiBzcGVjaWZpZWQgdGhlIHZhbHVlc1xuICogZGVmaW5lIGVhY2ggem9vbSBsZXZlbCdzIGV4dGVudCB0b2dldGhlciB3aXRoIHRoZSBgb3JpZ2luYCBvciBgb3JpZ2luc2AuXG4gKiBBIGdyaWQgYGV4dGVudGAgY2FuIGJlIGNvbmZpZ3VyZWQgaW4gYWRkaXRpb24sIGFuZCB3aWxsIGZ1cnRoZXIgbGltaXQgdGhlIGV4dGVudFxuICogZm9yIHdoaWNoIHRpbGUgcmVxdWVzdHMgYXJlIG1hZGUgYnkgc291cmNlcy4gSWYgdGhlIGJvdHRvbS1sZWZ0IGNvcm5lciBvZlxuICogYW4gZXh0ZW50IGlzIHVzZWQgYXMgYG9yaWdpbmAgb3IgYG9yaWdpbnNgLCB0aGVuIHRoZSBgeWAgdmFsdWUgbXVzdCBiZVxuICogbmVnYXRpdmUgYmVjYXVzZSBPcGVuTGF5ZXJzIHRpbGUgY29vcmRpbmF0ZXMgdXNlIHRoZSB0b3AgbGVmdCBhcyB0aGUgb3JpZ2luLlxuICogQHByb3BlcnR5IHtudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfSBbdGlsZVNpemVdIFRpbGUgc2l6ZS5cbiAqIERlZmF1bHQgaXMgYFsyNTYsIDI1Nl1gLlxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemU+fSBbdGlsZVNpemVzXSBUaWxlIHNpemVzLiBJZiBnaXZlbiwgdGhlIGFycmF5IGxlbmd0aFxuICogc2hvdWxkIG1hdGNoIHRoZSBsZW5ndGggb2YgdGhlIGByZXNvbHV0aW9uc2AgYXJyYXksIGkuZS4gZWFjaCByZXNvbHV0aW9uIGNhbiBoYXZlIGEgZGlmZmVyZW50XG4gKiB0aWxlIHNpemUuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBCYXNlIGNsYXNzIGZvciBzZXR0aW5nIHRoZSBncmlkIHBhdHRlcm4gZm9yIHNvdXJjZXMgYWNjZXNzaW5nIHRpbGVkLWltYWdlXG4gKiBzZXJ2ZXJzLlxuICogQGFwaVxuICovXG5cbnZhciBUaWxlR3JpZCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgVGlsZSBncmlkIG9wdGlvbnMuXG4gICAqL1xuICBmdW5jdGlvbiBUaWxlR3JpZChvcHRpb25zKSB7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5taW5ab29tID0gb3B0aW9ucy5taW5ab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1pblpvb20gOiAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgdGhpcy5yZXNvbHV0aW9uc18gPSBvcHRpb25zLnJlc29sdXRpb25zO1xuICAgIGFzc2VydChpc1NvcnRlZCh0aGlzLnJlc29sdXRpb25zXywgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBiIC0gYTtcbiAgICB9LCB0cnVlKSwgMTcpOyAvLyBgcmVzb2x1dGlvbnNgIG11c3QgYmUgc29ydGVkIGluIGRlc2NlbmRpbmcgb3JkZXJcbiAgICAvLyBjaGVjayBpZiB3ZSd2ZSBnb3QgYSBjb25zaXN0ZW50IHpvb20gZmFjdG9yIGFuZCBvcmlnaW5cblxuICAgIHZhciB6b29tRmFjdG9yO1xuXG4gICAgaWYgKCFvcHRpb25zLm9yaWdpbnMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aCAtIDE7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGlmICghem9vbUZhY3Rvcikge1xuICAgICAgICAgIHpvb21GYWN0b3IgPSB0aGlzLnJlc29sdXRpb25zX1tpXSAvIHRoaXMucmVzb2x1dGlvbnNfW2kgKyAxXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAodGhpcy5yZXNvbHV0aW9uc19baV0gLyB0aGlzLnJlc29sdXRpb25zX1tpICsgMV0gIT09IHpvb21GYWN0b3IpIHtcbiAgICAgICAgICAgIHpvb21GYWN0b3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuXG4gICAgdGhpcy56b29tRmFjdG9yXyA9IHpvb21GYWN0b3I7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICB0aGlzLm1heFpvb20gPSB0aGlzLnJlc29sdXRpb25zXy5sZW5ndGggLSAxO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuICAgIHRoaXMub3JpZ2luXyA9IG9wdGlvbnMub3JpZ2luICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm9yaWdpbiA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn1cbiAgICAgKi9cblxuICAgIHRoaXMub3JpZ2luc18gPSBudWxsO1xuXG4gICAgaWYgKG9wdGlvbnMub3JpZ2lucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm9yaWdpbnNfID0gb3B0aW9ucy5vcmlnaW5zO1xuICAgICAgYXNzZXJ0KHRoaXMub3JpZ2luc18ubGVuZ3RoID09IHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aCwgMjApOyAvLyBOdW1iZXIgb2YgYG9yaWdpbnNgIGFuZCBgcmVzb2x1dGlvbnNgIG11c3QgYmUgZXF1YWxcbiAgICB9XG5cbiAgICB2YXIgZXh0ZW50ID0gb3B0aW9ucy5leHRlbnQ7XG5cbiAgICBpZiAoZXh0ZW50ICE9PSB1bmRlZmluZWQgJiYgIXRoaXMub3JpZ2luXyAmJiAhdGhpcy5vcmlnaW5zXykge1xuICAgICAgdGhpcy5vcmlnaW5fID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICAgIH1cblxuICAgIGFzc2VydCghdGhpcy5vcmlnaW5fICYmIHRoaXMub3JpZ2luc18gfHwgdGhpcy5vcmlnaW5fICYmICF0aGlzLm9yaWdpbnNfLCAxOCk7IC8vIEVpdGhlciBgb3JpZ2luYCBvciBgb3JpZ2luc2AgbXVzdCBiZSBjb25maWd1cmVkLCBuZXZlciBib3RoXG5cbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXJ8aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplPn1cbiAgICAgKi9cblxuICAgIHRoaXMudGlsZVNpemVzXyA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy50aWxlU2l6ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy50aWxlU2l6ZXNfID0gb3B0aW9ucy50aWxlU2l6ZXM7XG4gICAgICBhc3NlcnQodGhpcy50aWxlU2l6ZXNfLmxlbmd0aCA9PSB0aGlzLnJlc29sdXRpb25zXy5sZW5ndGgsIDE5KTsgLy8gTnVtYmVyIG9mIGB0aWxlU2l6ZXNgIGFuZCBgcmVzb2x1dGlvbnNgIG11c3QgYmUgZXF1YWxcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuXG4gICAgdGhpcy50aWxlU2l6ZV8gPSBvcHRpb25zLnRpbGVTaXplICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpbGVTaXplIDogIXRoaXMudGlsZVNpemVzXyA/IERFRkFVTFRfVElMRV9TSVpFIDogbnVsbDtcbiAgICBhc3NlcnQoIXRoaXMudGlsZVNpemVfICYmIHRoaXMudGlsZVNpemVzXyB8fCB0aGlzLnRpbGVTaXplXyAmJiAhdGhpcy50aWxlU2l6ZXNfLCAyMik7IC8vIEVpdGhlciBgdGlsZVNpemVgIG9yIGB0aWxlU2l6ZXNgIG11c3QgYmUgY29uZmlndXJlZCwgbmV2ZXIgYm90aFxuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIHRoaXMuZXh0ZW50XyA9IGV4dGVudCAhPT0gdW5kZWZpbmVkID8gZXh0ZW50IDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdD59XG4gICAgICovXG5cbiAgICB0aGlzLmZ1bGxUaWxlUmFuZ2VzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2l6ZS5qc1wiKS5TaXplfVxuICAgICAqL1xuXG4gICAgdGhpcy50bXBTaXplXyA9IFswLCAwXTtcblxuICAgIGlmIChvcHRpb25zLnNpemVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZnVsbFRpbGVSYW5nZXNfID0gb3B0aW9ucy5zaXplcy5tYXAoZnVuY3Rpb24gKHNpemUsIHopIHtcbiAgICAgICAgdmFyIHRpbGVSYW5nZSA9IG5ldyBUaWxlUmFuZ2UoTWF0aC5taW4oMCwgc2l6ZVswXSksIE1hdGgubWF4KHNpemVbMF0gLSAxLCAtMSksIE1hdGgubWluKDAsIHNpemVbMV0pLCBNYXRoLm1heChzaXplWzFdIC0gMSwgLTEpKTtcblxuICAgICAgICBpZiAoZXh0ZW50KSB7XG4gICAgICAgICAgdmFyIHJlc3RyaWN0ZWRUaWxlUmFuZ2UgPSB0aGlzLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFooZXh0ZW50LCB6KTtcbiAgICAgICAgICB0aWxlUmFuZ2UubWluWCA9IE1hdGgubWF4KHJlc3RyaWN0ZWRUaWxlUmFuZ2UubWluWCwgdGlsZVJhbmdlLm1pblgpO1xuICAgICAgICAgIHRpbGVSYW5nZS5tYXhYID0gTWF0aC5taW4ocmVzdHJpY3RlZFRpbGVSYW5nZS5tYXhYLCB0aWxlUmFuZ2UubWF4WCk7XG4gICAgICAgICAgdGlsZVJhbmdlLm1pblkgPSBNYXRoLm1heChyZXN0cmljdGVkVGlsZVJhbmdlLm1pblksIHRpbGVSYW5nZS5taW5ZKTtcbiAgICAgICAgICB0aWxlUmFuZ2UubWF4WSA9IE1hdGgubWluKHJlc3RyaWN0ZWRUaWxlUmFuZ2UubWF4WSwgdGlsZVJhbmdlLm1heFkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRpbGVSYW5nZTtcbiAgICAgIH0sIHRoaXMpO1xuICAgIH0gZWxzZSBpZiAoZXh0ZW50KSB7XG4gICAgICB0aGlzLmNhbGN1bGF0ZVRpbGVSYW5nZXNfKGV4dGVudCk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBDYWxsIGEgZnVuY3Rpb24gd2l0aCBlYWNoIHRpbGUgY29vcmRpbmF0ZSBmb3IgYSBnaXZlbiBleHRlbnQgYW5kIHpvb20gbGV2ZWwuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHpvb20gSW50ZWdlciB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQpOiB2b2lkfSBjYWxsYmFjayBGdW5jdGlvbiBjYWxsZWQgd2l0aCBlYWNoIHRpbGUgY29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5mb3JFYWNoVGlsZUNvb3JkID0gZnVuY3Rpb24gKGV4dGVudCwgem9vbSwgY2FsbGJhY2spIHtcbiAgICB2YXIgdGlsZVJhbmdlID0gdGhpcy5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKGV4dGVudCwgem9vbSk7XG5cbiAgICBmb3IgKHZhciBpID0gdGlsZVJhbmdlLm1pblgsIGlpID0gdGlsZVJhbmdlLm1heFg7IGkgPD0gaWk7ICsraSkge1xuICAgICAgZm9yICh2YXIgaiA9IHRpbGVSYW5nZS5taW5ZLCBqaiA9IHRpbGVSYW5nZS5tYXhZOyBqIDw9IGpqOyArK2opIHtcbiAgICAgICAgY2FsbGJhY2soW3pvb20sIGksIGpdKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyLCBpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdCk6IGJvb2xlYW59IGNhbGxiYWNrIENhbGxiYWNrLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGVSYW5nZS5qc1wiKS5kZWZhdWx0PX0gb3B0X3RpbGVSYW5nZSBUZW1wb3JhcnkgaW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHQgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQ9fSBvcHRfZXh0ZW50IFRlbXBvcmFyeSBpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50IG9iamVjdC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ2FsbGJhY2sgc3VjY2VlZGVkLlxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5mb3JFYWNoVGlsZUNvb3JkUGFyZW50VGlsZVJhbmdlID0gZnVuY3Rpb24gKHRpbGVDb29yZCwgY2FsbGJhY2ssIG9wdF90aWxlUmFuZ2UsIG9wdF9leHRlbnQpIHtcbiAgICB2YXIgdGlsZVJhbmdlLCB4LCB5O1xuICAgIHZhciB0aWxlQ29vcmRFeHRlbnQgPSBudWxsO1xuICAgIHZhciB6ID0gdGlsZUNvb3JkWzBdIC0gMTtcblxuICAgIGlmICh0aGlzLnpvb21GYWN0b3JfID09PSAyKSB7XG4gICAgICB4ID0gdGlsZUNvb3JkWzFdO1xuICAgICAgeSA9IHRpbGVDb29yZFsyXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGlsZUNvb3JkRXh0ZW50ID0gdGhpcy5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZUNvb3JkLCBvcHRfZXh0ZW50KTtcbiAgICB9XG5cbiAgICB3aGlsZSAoeiA+PSB0aGlzLm1pblpvb20pIHtcbiAgICAgIGlmICh0aGlzLnpvb21GYWN0b3JfID09PSAyKSB7XG4gICAgICAgIHggPSBNYXRoLmZsb29yKHggLyAyKTtcbiAgICAgICAgeSA9IE1hdGguZmxvb3IoeSAvIDIpO1xuICAgICAgICB0aWxlUmFuZ2UgPSBjcmVhdGVPclVwZGF0ZVRpbGVSYW5nZSh4LCB4LCB5LCB5LCBvcHRfdGlsZVJhbmdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRpbGVSYW5nZSA9IHRoaXMuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWih0aWxlQ29vcmRFeHRlbnQsIHosIG9wdF90aWxlUmFuZ2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2FsbGJhY2soeiwgdGlsZVJhbmdlKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLS16O1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZW50IGZvciB0aGlzIHRpbGUgZ3JpZCwgaWYgaXQgd2FzIGNvbmZpZ3VyZWQuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRFeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW50XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbWF4aW11bSB6b29tIGxldmVsIGZvciB0aGUgZ3JpZC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNYXggem9vbS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRNYXhab29tID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm1heFpvb207XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbmltdW0gem9vbSBsZXZlbCBmb3IgdGhlIGdyaWQuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluIHpvb20uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0TWluWm9vbSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5taW5ab29tO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBvcmlnaW4gZm9yIHRoZSBncmlkIGF0IHRoZSBnaXZlbiB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBJbnRlZ2VyIHpvb20gbGV2ZWwuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gT3JpZ2luLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldE9yaWdpbiA9IGZ1bmN0aW9uICh6KSB7XG4gICAgaWYgKHRoaXMub3JpZ2luXykge1xuICAgICAgcmV0dXJuIHRoaXMub3JpZ2luXztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMub3JpZ2luc19bel07XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSByZXNvbHV0aW9uIGZvciB0aGUgZ2l2ZW4gem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHogSW50ZWdlciB6b29tIGxldmVsLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFJlc29sdXRpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0UmVzb2x1dGlvbiA9IGZ1bmN0aW9uICh6KSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x1dGlvbnNfW3pdO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBsaXN0IG9mIHJlc29sdXRpb25zIGZvciB0aGUgdGlsZSBncmlkLlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBSZXNvbHV0aW9ucy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRSZXNvbHV0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHV0aW9uc187XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHQ9fSBvcHRfdGlsZVJhbmdlIFRlbXBvcmFyeSBpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdCBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9leHRlbnQgVGVtcG9yYXJ5IGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH0gVGlsZSByYW5nZS5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkQ2hpbGRUaWxlUmFuZ2UgPSBmdW5jdGlvbiAodGlsZUNvb3JkLCBvcHRfdGlsZVJhbmdlLCBvcHRfZXh0ZW50KSB7XG4gICAgaWYgKHRpbGVDb29yZFswXSA8IHRoaXMubWF4Wm9vbSkge1xuICAgICAgaWYgKHRoaXMuem9vbUZhY3Rvcl8gPT09IDIpIHtcbiAgICAgICAgdmFyIG1pblggPSB0aWxlQ29vcmRbMV0gKiAyO1xuICAgICAgICB2YXIgbWluWSA9IHRpbGVDb29yZFsyXSAqIDI7XG4gICAgICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZVRpbGVSYW5nZShtaW5YLCBtaW5YICsgMSwgbWluWSwgbWluWSArIDEsIG9wdF90aWxlUmFuZ2UpO1xuICAgICAgfVxuXG4gICAgICB2YXIgdGlsZUNvb3JkRXh0ZW50ID0gdGhpcy5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZUNvb3JkLCBvcHRfZXh0ZW50KTtcbiAgICAgIHJldHVybiB0aGlzLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFoodGlsZUNvb3JkRXh0ZW50LCB0aWxlQ29vcmRbMF0gKyAxLCBvcHRfdGlsZVJhbmdlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZW50IGZvciBhIHRpbGUgcmFuZ2UuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IEludGVnZXIgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH0gdGlsZVJhbmdlIFRpbGUgcmFuZ2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9leHRlbnQgVGVtcG9yYXJ5IGltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnQgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBFeHRlbnQuXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFRpbGVSYW5nZUV4dGVudCA9IGZ1bmN0aW9uICh6LCB0aWxlUmFuZ2UsIG9wdF9leHRlbnQpIHtcbiAgICB2YXIgb3JpZ2luID0gdGhpcy5nZXRPcmlnaW4oeik7XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24oeik7XG4gICAgdmFyIHRpbGVTaXplID0gdG9TaXplKHRoaXMuZ2V0VGlsZVNpemUoeiksIHRoaXMudG1wU2l6ZV8pO1xuICAgIHZhciBtaW5YID0gb3JpZ2luWzBdICsgdGlsZVJhbmdlLm1pblggKiB0aWxlU2l6ZVswXSAqIHJlc29sdXRpb247XG4gICAgdmFyIG1heFggPSBvcmlnaW5bMF0gKyAodGlsZVJhbmdlLm1heFggKyAxKSAqIHRpbGVTaXplWzBdICogcmVzb2x1dGlvbjtcbiAgICB2YXIgbWluWSA9IG9yaWdpblsxXSArIHRpbGVSYW5nZS5taW5ZICogdGlsZVNpemVbMV0gKiByZXNvbHV0aW9uO1xuICAgIHZhciBtYXhZID0gb3JpZ2luWzFdICsgKHRpbGVSYW5nZS5tYXhZICsgMSkgKiB0aWxlU2l6ZVsxXSAqIHJlc29sdXRpb247XG4gICAgcmV0dXJuIGNyZWF0ZU9yVXBkYXRlKG1pblgsIG1pblksIG1heFgsIG1heFksIG9wdF9leHRlbnQpO1xuICB9O1xuICAvKipcbiAgICogR2V0IGEgdGlsZSByYW5nZSBmb3IgdGhlIGdpdmVuIGV4dGVudCBhbmQgaW50ZWdlciB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IEludGVnZXIgem9vbSBsZXZlbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdD19IG9wdF90aWxlUmFuZ2UgVGVtcG9yYXJ5IHRpbGUgcmFuZ2Ugb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlUmFuZ2UuanNcIikuZGVmYXVsdH0gVGlsZSByYW5nZS5cbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWiA9IGZ1bmN0aW9uIChleHRlbnQsIHosIG9wdF90aWxlUmFuZ2UpIHtcbiAgICB2YXIgdGlsZUNvb3JkID0gdG1wVGlsZUNvb3JkO1xuICAgIHRoaXMuZ2V0VGlsZUNvb3JkRm9yWFlBbmRaXyhleHRlbnRbMF0sIGV4dGVudFszXSwgeiwgZmFsc2UsIHRpbGVDb29yZCk7XG4gICAgdmFyIG1pblggPSB0aWxlQ29vcmRbMV07XG4gICAgdmFyIG1pblkgPSB0aWxlQ29vcmRbMl07XG4gICAgdGhpcy5nZXRUaWxlQ29vcmRGb3JYWUFuZFpfKGV4dGVudFsyXSwgZXh0ZW50WzFdLCB6LCB0cnVlLCB0aWxlQ29vcmQpO1xuICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZVRpbGVSYW5nZShtaW5YLCB0aWxlQ29vcmRbMV0sIG1pblksIHRpbGVDb29yZFsyXSwgb3B0X3RpbGVSYW5nZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVGlsZSBjZW50ZXIuXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFRpbGVDb29yZENlbnRlciA9IGZ1bmN0aW9uICh0aWxlQ29vcmQpIHtcbiAgICB2YXIgb3JpZ2luID0gdGhpcy5nZXRPcmlnaW4odGlsZUNvb3JkWzBdKTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRoaXMuZ2V0UmVzb2x1dGlvbih0aWxlQ29vcmRbMF0pO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aGlzLmdldFRpbGVTaXplKHRpbGVDb29yZFswXSksIHRoaXMudG1wU2l6ZV8pO1xuICAgIHJldHVybiBbb3JpZ2luWzBdICsgKHRpbGVDb29yZFsxXSArIDAuNSkgKiB0aWxlU2l6ZVswXSAqIHJlc29sdXRpb24sIG9yaWdpblsxXSAtICh0aWxlQ29vcmRbMl0gKyAwLjUpICogdGlsZVNpemVbMV0gKiByZXNvbHV0aW9uXTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZW50IG9mIGEgdGlsZSBjb29yZGluYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudD19IG9wdF9leHRlbnQgVGVtcG9yYXJ5IGV4dGVudCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlQ29vcmRFeHRlbnQgPSBmdW5jdGlvbiAodGlsZUNvb3JkLCBvcHRfZXh0ZW50KSB7XG4gICAgdmFyIG9yaWdpbiA9IHRoaXMuZ2V0T3JpZ2luKHRpbGVDb29yZFswXSk7XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aGlzLmdldFJlc29sdXRpb24odGlsZUNvb3JkWzBdKTtcbiAgICB2YXIgdGlsZVNpemUgPSB0b1NpemUodGhpcy5nZXRUaWxlU2l6ZSh0aWxlQ29vcmRbMF0pLCB0aGlzLnRtcFNpemVfKTtcbiAgICB2YXIgbWluWCA9IG9yaWdpblswXSArIHRpbGVDb29yZFsxXSAqIHRpbGVTaXplWzBdICogcmVzb2x1dGlvbjtcbiAgICB2YXIgbWluWSA9IG9yaWdpblsxXSAtICh0aWxlQ29vcmRbMl0gKyAxKSAqIHRpbGVTaXplWzFdICogcmVzb2x1dGlvbjtcbiAgICB2YXIgbWF4WCA9IG1pblggKyB0aWxlU2l6ZVswXSAqIHJlc29sdXRpb247XG4gICAgdmFyIG1heFkgPSBtaW5ZICsgdGlsZVNpemVbMV0gKiByZXNvbHV0aW9uO1xuICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZShtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZLCBvcHRfZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGlsZSBjb29yZGluYXRlIGZvciB0aGUgZ2l2ZW4gbWFwIGNvb3JkaW5hdGUgYW5kIHJlc29sdXRpb24uICBUaGlzXG4gICAqIG1ldGhvZCBjb25zaWRlcnMgdGhhdCBjb29yZGluYXRlcyB0aGF0IGludGVyc2VjdCB0aWxlIGJvdW5kYXJpZXMgc2hvdWxkIGJlXG4gICAqIGFzc2lnbmVkIHRoZSBoaWdoZXIgdGlsZSBjb29yZGluYXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQ9fSBvcHRfdGlsZUNvb3JkIERlc3RpbmF0aW9uIGltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkRm9yQ29vcmRBbmRSZXNvbHV0aW9uID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIHJlc29sdXRpb24sIG9wdF90aWxlQ29vcmQpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRUaWxlQ29vcmRGb3JYWUFuZFJlc29sdXRpb25fKGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0sIHJlc29sdXRpb24sIGZhbHNlLCBvcHRfdGlsZUNvb3JkKTtcbiAgfTtcbiAgLyoqXG4gICAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBzaG91bGQgbm90IGJlIGNhbGxlZCBmb3IgcmVzb2x1dGlvbnMgdGhhdCBjb3JyZXNwb25kXG4gICAqIHRvIGFuIGludGVnZXIgem9vbSBsZXZlbC4gIEluc3RlYWQgY2FsbCB0aGUgYGdldFRpbGVDb29yZEZvclhZQW5kWl9gIG1ldGhvZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHJlc29sdXRpb24gUmVzb2x1dGlvbiAoZm9yIGEgbm9uLWludGVnZXIgem9vbSBsZXZlbCkuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSBJbnN0ZWFkIG9mIGxldHRpbmcgZWRnZVxuICAgKiAgICAgaW50ZXJzZWN0aW9ucyBnbyB0byB0aGUgaGlnaGVyIHRpbGUgY29vcmRpbmF0ZSwgbGV0IGVkZ2UgaW50ZXJzZWN0aW9uc1xuICAgKiAgICAgZ28gdG8gdGhlIGxvd2VyIHRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkPX0gb3B0X3RpbGVDb29yZCBUZW1wb3JhcnkgaW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkRm9yWFlBbmRSZXNvbHV0aW9uXyA9IGZ1bmN0aW9uICh4LCB5LCByZXNvbHV0aW9uLCByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5LCBvcHRfdGlsZUNvb3JkKSB7XG4gICAgdmFyIHogPSB0aGlzLmdldFpGb3JSZXNvbHV0aW9uKHJlc29sdXRpb24pO1xuICAgIHZhciBzY2FsZSA9IHJlc29sdXRpb24gLyB0aGlzLmdldFJlc29sdXRpb24oeik7XG4gICAgdmFyIG9yaWdpbiA9IHRoaXMuZ2V0T3JpZ2luKHopO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aGlzLmdldFRpbGVTaXplKHopLCB0aGlzLnRtcFNpemVfKTtcbiAgICB2YXIgYWRqdXN0WCA9IHJldmVyc2VJbnRlcnNlY3Rpb25Qb2xpY3kgPyAwLjUgOiAwO1xuICAgIHZhciBhZGp1c3RZID0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSA/IDAuNSA6IDA7XG4gICAgdmFyIHhGcm9tT3JpZ2luID0gTWF0aC5mbG9vcigoeCAtIG9yaWdpblswXSkgLyByZXNvbHV0aW9uICsgYWRqdXN0WCk7XG4gICAgdmFyIHlGcm9tT3JpZ2luID0gTWF0aC5mbG9vcigob3JpZ2luWzFdIC0geSkgLyByZXNvbHV0aW9uICsgYWRqdXN0WSk7XG4gICAgdmFyIHRpbGVDb29yZFggPSBzY2FsZSAqIHhGcm9tT3JpZ2luIC8gdGlsZVNpemVbMF07XG4gICAgdmFyIHRpbGVDb29yZFkgPSBzY2FsZSAqIHlGcm9tT3JpZ2luIC8gdGlsZVNpemVbMV07XG5cbiAgICBpZiAocmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSkge1xuICAgICAgdGlsZUNvb3JkWCA9IE1hdGguY2VpbCh0aWxlQ29vcmRYKSAtIDE7XG4gICAgICB0aWxlQ29vcmRZID0gTWF0aC5jZWlsKHRpbGVDb29yZFkpIC0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGlsZUNvb3JkWCA9IE1hdGguZmxvb3IodGlsZUNvb3JkWCk7XG4gICAgICB0aWxlQ29vcmRZID0gTWF0aC5mbG9vcih0aWxlQ29vcmRZKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlT3JVcGRhdGVUaWxlQ29vcmQoeiwgdGlsZUNvb3JkWCwgdGlsZUNvb3JkWSwgb3B0X3RpbGVDb29yZCk7XG4gIH07XG4gIC8qKlxuICAgKiBBbHRob3VnaCB0aGVyZSBpcyByZXBldGl0aW9uIGJldHdlZW4gdGhpcyBtZXRob2QgYW5kIGBnZXRUaWxlQ29vcmRGb3JYWUFuZFJlc29sdXRpb25fYCxcbiAgICogdGhleSBzaG91bGQgaGF2ZSBzZXBhcmF0ZSBpbXBsZW1lbnRhdGlvbnMuICBUaGlzIG1ldGhvZCBpcyBmb3IgaW50ZWdlciB6b29tXG4gICAqIGxldmVscy4gIFRoZSBvdGhlciBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGZvciByZXNvbHV0aW9ucyBjb3JyZXNwb25kaW5nXG4gICAqIHRvIG5vbi1pbnRlZ2VyIHpvb20gbGV2ZWxzLlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBNYXAgeCBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBNYXAgeSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBJbnRlZ2VyIHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSBJbnN0ZWFkIG9mIGxldHRpbmcgZWRnZVxuICAgKiAgICAgaW50ZXJzZWN0aW9ucyBnbyB0byB0aGUgaGlnaGVyIHRpbGUgY29vcmRpbmF0ZSwgbGV0IGVkZ2UgaW50ZXJzZWN0aW9uc1xuICAgKiAgICAgZ28gdG8gdGhlIGxvd2VyIHRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkPX0gb3B0X3RpbGVDb29yZCBUZW1wb3JhcnkgaW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCBvYmplY3QuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkRm9yWFlBbmRaXyA9IGZ1bmN0aW9uICh4LCB5LCB6LCByZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5LCBvcHRfdGlsZUNvb3JkKSB7XG4gICAgdmFyIG9yaWdpbiA9IHRoaXMuZ2V0T3JpZ2luKHopO1xuICAgIHZhciByZXNvbHV0aW9uID0gdGhpcy5nZXRSZXNvbHV0aW9uKHopO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aGlzLmdldFRpbGVTaXplKHopLCB0aGlzLnRtcFNpemVfKTtcbiAgICB2YXIgYWRqdXN0WCA9IHJldmVyc2VJbnRlcnNlY3Rpb25Qb2xpY3kgPyAwLjUgOiAwO1xuICAgIHZhciBhZGp1c3RZID0gcmV2ZXJzZUludGVyc2VjdGlvblBvbGljeSA/IDAuNSA6IDA7XG4gICAgdmFyIHhGcm9tT3JpZ2luID0gTWF0aC5mbG9vcigoeCAtIG9yaWdpblswXSkgLyByZXNvbHV0aW9uICsgYWRqdXN0WCk7XG4gICAgdmFyIHlGcm9tT3JpZ2luID0gTWF0aC5mbG9vcigob3JpZ2luWzFdIC0geSkgLyByZXNvbHV0aW9uICsgYWRqdXN0WSk7XG4gICAgdmFyIHRpbGVDb29yZFggPSB4RnJvbU9yaWdpbiAvIHRpbGVTaXplWzBdO1xuICAgIHZhciB0aWxlQ29vcmRZID0geUZyb21PcmlnaW4gLyB0aWxlU2l6ZVsxXTtcblxuICAgIGlmIChyZXZlcnNlSW50ZXJzZWN0aW9uUG9saWN5KSB7XG4gICAgICB0aWxlQ29vcmRYID0gTWF0aC5jZWlsKHRpbGVDb29yZFgpIC0gMTtcbiAgICAgIHRpbGVDb29yZFkgPSBNYXRoLmNlaWwodGlsZUNvb3JkWSkgLSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aWxlQ29vcmRYID0gTWF0aC5mbG9vcih0aWxlQ29vcmRYKTtcbiAgICAgIHRpbGVDb29yZFkgPSBNYXRoLmZsb29yKHRpbGVDb29yZFkpO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVPclVwZGF0ZVRpbGVDb29yZCh6LCB0aWxlQ29vcmRYLCB0aWxlQ29vcmRZLCBvcHRfdGlsZUNvb3JkKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCBhIHRpbGUgY29vcmRpbmF0ZSBnaXZlbiBhIG1hcCBjb29yZGluYXRlIGFuZCB6b29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBab29tIGxldmVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQ9fSBvcHRfdGlsZUNvb3JkIERlc3RpbmF0aW9uIGltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmQgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkRm9yQ29vcmRBbmRaID0gZnVuY3Rpb24gKGNvb3JkaW5hdGUsIHosIG9wdF90aWxlQ29vcmQpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRUaWxlQ29vcmRGb3JYWUFuZFpfKGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0sIHosIGZhbHNlLCBvcHRfdGlsZUNvb3JkKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaWxlIHJlc29sdXRpb24uXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFRpbGVDb29yZFJlc29sdXRpb24gPSBmdW5jdGlvbiAodGlsZUNvb3JkKSB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x1dGlvbnNfW3RpbGVDb29yZFswXV07XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRpbGUgc2l6ZSBmb3IgYSB6b29tIGxldmVsLiBUaGUgdHlwZSBvZiB0aGUgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhlXG4gICAqIGB0aWxlU2l6ZWAgb3IgYHRpbGVTaXplc2AgdGhhdCB0aGUgdGlsZSBncmlkIHdhcyBjb25maWd1cmVkIHdpdGguIFRvIGFsd2F5c1xuICAgKiBnZXQgYW4gYGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZWAsIHJ1biB0aGUgcmVzdWx0IHRocm91Z2ggYGltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZS50b1NpemUoKWAuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gICAqIEByZXR1cm4ge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFRpbGUgc2l6ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVHcmlkLnByb3RvdHlwZS5nZXRUaWxlU2l6ZSA9IGZ1bmN0aW9uICh6KSB7XG4gICAgaWYgKHRoaXMudGlsZVNpemVfKSB7XG4gICAgICByZXR1cm4gdGhpcy50aWxlU2l6ZV87XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnRpbGVTaXplc19bel07XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogWm9vbSBsZXZlbC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHR9IEV4dGVudCB0aWxlIHJhbmdlIGZvciB0aGUgc3BlY2lmaWVkIHpvb20gbGV2ZWwuXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldEZ1bGxUaWxlUmFuZ2UgPSBmdW5jdGlvbiAoeikge1xuICAgIGlmICghdGhpcy5mdWxsVGlsZVJhbmdlc18pIHtcbiAgICAgIHJldHVybiB0aGlzLmV4dGVudF8gPyB0aGlzLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFoodGhpcy5leHRlbnRfLCB6KSA6IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmZ1bGxUaWxlUmFuZ2VzX1t6XTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gcmVzb2x1dGlvbiBSZXNvbHV0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9kaXJlY3Rpb24gSWYgMCwgdGhlIG5lYXJlc3QgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gICAqICAgICBJZiAxLCB0aGUgbmVhcmVzdCBsb3dlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC4gSWYgLTEsIHRoZSBuZWFyZXN0XG4gICAqICAgICBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuIERlZmF1bHQgaXMgMC5cbiAgICogQHJldHVybiB7bnVtYmVyfSBaLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZUdyaWQucHJvdG90eXBlLmdldFpGb3JSZXNvbHV0aW9uID0gZnVuY3Rpb24gKHJlc29sdXRpb24sIG9wdF9kaXJlY3Rpb24pIHtcbiAgICB2YXIgeiA9IGxpbmVhckZpbmROZWFyZXN0KHRoaXMucmVzb2x1dGlvbnNfLCByZXNvbHV0aW9uLCBvcHRfZGlyZWN0aW9uIHx8IDApO1xuICAgIHJldHVybiBjbGFtcCh6LCB0aGlzLm1pblpvb20sIHRoaXMubWF4Wm9vbSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0geyFpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50IGZvciB0aGlzIHRpbGUgZ3JpZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBUaWxlR3JpZC5wcm90b3R5cGUuY2FsY3VsYXRlVGlsZVJhbmdlc18gPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgdmFyIGxlbmd0aCA9IHRoaXMucmVzb2x1dGlvbnNfLmxlbmd0aDtcbiAgICB2YXIgZnVsbFRpbGVSYW5nZXMgPSBuZXcgQXJyYXkobGVuZ3RoKTtcblxuICAgIGZvciAodmFyIHogPSB0aGlzLm1pblpvb207IHogPCBsZW5ndGg7ICsreikge1xuICAgICAgZnVsbFRpbGVSYW5nZXNbel0gPSB0aGlzLmdldFRpbGVSYW5nZUZvckV4dGVudEFuZFooZXh0ZW50LCB6KTtcbiAgICB9XG5cbiAgICB0aGlzLmZ1bGxUaWxlUmFuZ2VzXyA9IGZ1bGxUaWxlUmFuZ2VzO1xuICB9O1xuXG4gIHJldHVybiBUaWxlR3JpZDtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgVGlsZUdyaWQ7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3RpbGVncmlkXG4gKi9cbmltcG9ydCBDb3JuZXIgZnJvbSAnLi9leHRlbnQvQ29ybmVyLmpzJztcbmltcG9ydCBUaWxlR3JpZCBmcm9tICcuL3RpbGVncmlkL1RpbGVHcmlkLmpzJztcbmltcG9ydCBVbml0cyBmcm9tICcuL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IHsgREVGQVVMVF9NQVhfWk9PTSwgREVGQVVMVF9USUxFX1NJWkUgfSBmcm9tICcuL3RpbGVncmlkL2NvbW1vbi5qcyc7XG5pbXBvcnQgeyBNRVRFUlNfUEVSX1VOSVQsIGdldCBhcyBnZXRQcm9qZWN0aW9uIH0gZnJvbSAnLi9wcm9qLmpzJztcbmltcG9ydCB7IGNvbnRhaW5zQ29vcmRpbmF0ZSwgY3JlYXRlT3JVcGRhdGUsIGdldENvcm5lciwgZ2V0SGVpZ2h0LCBnZXRXaWR0aCB9IGZyb20gJy4vZXh0ZW50LmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4vc2l6ZS5qcyc7XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICogQHJldHVybiB7IVRpbGVHcmlkfSBEZWZhdWx0IHRpbGUgZ3JpZCBmb3IgdGhlXG4gKiBwYXNzZWQgcHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKSB7XG4gIHZhciB0aWxlR3JpZCA9IHByb2plY3Rpb24uZ2V0RGVmYXVsdFRpbGVHcmlkKCk7XG5cbiAgaWYgKCF0aWxlR3JpZCkge1xuICAgIHRpbGVHcmlkID0gY3JlYXRlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICBwcm9qZWN0aW9uLnNldERlZmF1bHRUaWxlR3JpZCh0aWxlR3JpZCk7XG4gIH1cblxuICByZXR1cm4gdGlsZUdyaWQ7XG59XG4vKipcbiAqIEBwYXJhbSB7VGlsZUdyaWR9IHRpbGVHcmlkIFRpbGUgZ3JpZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRpbGUgY29vcmRpbmF0ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gd3JhcFgodGlsZUdyaWQsIHRpbGVDb29yZCwgcHJvamVjdGlvbikge1xuICB2YXIgeiA9IHRpbGVDb29yZFswXTtcbiAgdmFyIGNlbnRlciA9IHRpbGVHcmlkLmdldFRpbGVDb29yZENlbnRlcih0aWxlQ29vcmQpO1xuICB2YXIgcHJvamVjdGlvbkV4dGVudCA9IGV4dGVudEZyb21Qcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gIGlmICghY29udGFpbnNDb29yZGluYXRlKHByb2plY3Rpb25FeHRlbnQsIGNlbnRlcikpIHtcbiAgICB2YXIgd29ybGRXaWR0aCA9IGdldFdpZHRoKHByb2plY3Rpb25FeHRlbnQpO1xuICAgIHZhciB3b3JsZHNBd2F5ID0gTWF0aC5jZWlsKChwcm9qZWN0aW9uRXh0ZW50WzBdIC0gY2VudGVyWzBdKSAvIHdvcmxkV2lkdGgpO1xuICAgIGNlbnRlclswXSArPSB3b3JsZFdpZHRoICogd29ybGRzQXdheTtcbiAgICByZXR1cm4gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRm9yQ29vcmRBbmRaKGNlbnRlciwgeik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRpbGVDb29yZDtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X21heFpvb20gTWF4aW11bSB6b29tIGxldmVsIChkZWZhdWx0IGlzXG4gKiAgICAgREVGQVVMVF9NQVhfWk9PTSkuXG4gKiBAcGFyYW0ge251bWJlcnxpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF90aWxlU2l6ZSBUaWxlIHNpemUgKGRlZmF1bHQgdXNlc1xuICogICAgIERFRkFVTFRfVElMRV9TSVpFKS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9leHRlbnQvQ29ybmVyLmpzXCIpLmRlZmF1bHQ9fSBvcHRfY29ybmVyIEV4dGVudCBjb3JuZXIgKGRlZmF1bHQgaXMgYCd0b3AtbGVmdCdgKS5cbiAqIEByZXR1cm4geyFUaWxlR3JpZH0gVGlsZUdyaWQgaW5zdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZvckV4dGVudChleHRlbnQsIG9wdF9tYXhab29tLCBvcHRfdGlsZVNpemUsIG9wdF9jb3JuZXIpIHtcbiAgdmFyIGNvcm5lciA9IG9wdF9jb3JuZXIgIT09IHVuZGVmaW5lZCA/IG9wdF9jb3JuZXIgOiBDb3JuZXIuVE9QX0xFRlQ7XG4gIHZhciByZXNvbHV0aW9ucyA9IHJlc29sdXRpb25zRnJvbUV4dGVudChleHRlbnQsIG9wdF9tYXhab29tLCBvcHRfdGlsZVNpemUpO1xuICByZXR1cm4gbmV3IFRpbGVHcmlkKHtcbiAgICBleHRlbnQ6IGV4dGVudCxcbiAgICBvcmlnaW46IGdldENvcm5lcihleHRlbnQsIGNvcm5lciksXG4gICAgcmVzb2x1dGlvbnM6IHJlc29sdXRpb25zLFxuICAgIHRpbGVTaXplOiBvcHRfdGlsZVNpemVcbiAgfSk7XG59XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFhZWk9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBFeHRlbnQgZm9yIHRoZSB0aWxlIGdyaWQuIFRoZSBvcmlnaW4gZm9yIGFuIFhZWiB0aWxlIGdyaWQgaXMgdGhlXG4gKiB0b3AtbGVmdCBjb3JuZXIgb2YgdGhlIGV4dGVudC4gSWYgYG1heFJlc29sdXRpb25gIGlzIG5vdCBwcm92aWRlZCB0aGUgemVybyBsZXZlbCBvZiB0aGUgZ3JpZCBpcyBkZWZpbmVkIGJ5IHRoZSByZXNvbHV0aW9uXG4gKiBhdCB3aGljaCBvbmUgdGlsZSBmaXRzIGluIHRoZSBwcm92aWRlZCBleHRlbnQuIElmIG5vdCBwcm92aWRlZCwgdGhlIGV4dGVudCBvZiB0aGUgRVBTRzozODU3IHByb2plY3Rpb24gaXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4UmVzb2x1dGlvbl0gUmVzb2x1dGlvbiBhdCBsZXZlbCB6ZXJvLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tXSBNYXhpbXVtIHpvb20uIFRoZSBkZWZhdWx0IGlzIGA0MmAuIFRoaXMgZGV0ZXJtaW5lcyB0aGUgbnVtYmVyIG9mIGxldmVsc1xuICogaW4gdGhlIGdyaWQgc2V0LiBGb3IgZXhhbXBsZSwgYSBgbWF4Wm9vbWAgb2YgMjEgbWVhbnMgdGhlcmUgYXJlIDIyIGxldmVscyBpbiB0aGUgZ3JpZCBzZXQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb209MF0gTWluaW11bSB6b29tLlxuICogQHByb3BlcnR5IHtudW1iZXJ8aW1wb3J0KFwiLi9zaXplLmpzXCIpLlNpemV9IFt0aWxlU2l6ZT1bMjU2LCAyNTZdXSBUaWxlIHNpemUgaW4gcGl4ZWxzLlxuICovXG5cbi8qKlxuICogQ3JlYXRlcyBhIHRpbGUgZ3JpZCB3aXRoIGEgc3RhbmRhcmQgWFlaIHRpbGluZyBzY2hlbWUuXG4gKiBAcGFyYW0ge1hZWk9wdGlvbnM9fSBvcHRfb3B0aW9ucyBUaWxlIGdyaWQgb3B0aW9ucy5cbiAqIEByZXR1cm4geyFUaWxlR3JpZH0gVGlsZSBncmlkIGluc3RhbmNlLlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVYWVoob3B0X29wdGlvbnMpIHtcbiAgdmFyIHh5ek9wdGlvbnMgPSBvcHRfb3B0aW9ucyB8fCB7fTtcbiAgdmFyIGV4dGVudCA9IHh5ek9wdGlvbnMuZXh0ZW50IHx8IGdldFByb2plY3Rpb24oJ0VQU0c6Mzg1NycpLmdldEV4dGVudCgpO1xuICB2YXIgZ3JpZE9wdGlvbnMgPSB7XG4gICAgZXh0ZW50OiBleHRlbnQsXG4gICAgbWluWm9vbTogeHl6T3B0aW9ucy5taW5ab29tLFxuICAgIHRpbGVTaXplOiB4eXpPcHRpb25zLnRpbGVTaXplLFxuICAgIHJlc29sdXRpb25zOiByZXNvbHV0aW9uc0Zyb21FeHRlbnQoZXh0ZW50LCB4eXpPcHRpb25zLm1heFpvb20sIHh5ek9wdGlvbnMudGlsZVNpemUsIHh5ek9wdGlvbnMubWF4UmVzb2x1dGlvbilcbiAgfTtcbiAgcmV0dXJuIG5ldyBUaWxlR3JpZChncmlkT3B0aW9ucyk7XG59XG4vKipcbiAqIENyZWF0ZSBhIHJlc29sdXRpb25zIGFycmF5IGZyb20gYW4gZXh0ZW50LiAgQSB6b29tIGZhY3RvciBvZiAyIGlzIGFzc3VtZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X21heFpvb20gTWF4aW11bSB6b29tIGxldmVsIChkZWZhdWx0IGlzXG4gKiAgICAgREVGQVVMVF9NQVhfWk9PTSkuXG4gKiBAcGFyYW0ge251bWJlcnxpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZT19IG9wdF90aWxlU2l6ZSBUaWxlIHNpemUgKGRlZmF1bHQgdXNlc1xuICogICAgIERFRkFVTFRfVElMRV9TSVpFKS5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X21heFJlc29sdXRpb24gUmVzb2x1dGlvbiBhdCBsZXZlbCB6ZXJvLlxuICogQHJldHVybiB7IUFycmF5PG51bWJlcj59IFJlc29sdXRpb25zIGFycmF5LlxuICovXG5cbmZ1bmN0aW9uIHJlc29sdXRpb25zRnJvbUV4dGVudChleHRlbnQsIG9wdF9tYXhab29tLCBvcHRfdGlsZVNpemUsIG9wdF9tYXhSZXNvbHV0aW9uKSB7XG4gIHZhciBtYXhab29tID0gb3B0X21heFpvb20gIT09IHVuZGVmaW5lZCA/IG9wdF9tYXhab29tIDogREVGQVVMVF9NQVhfWk9PTTtcbiAgdmFyIGhlaWdodCA9IGdldEhlaWdodChleHRlbnQpO1xuICB2YXIgd2lkdGggPSBnZXRXaWR0aChleHRlbnQpO1xuICB2YXIgdGlsZVNpemUgPSB0b1NpemUob3B0X3RpbGVTaXplICE9PSB1bmRlZmluZWQgPyBvcHRfdGlsZVNpemUgOiBERUZBVUxUX1RJTEVfU0laRSk7XG4gIHZhciBtYXhSZXNvbHV0aW9uID0gb3B0X21heFJlc29sdXRpb24gPiAwID8gb3B0X21heFJlc29sdXRpb24gOiBNYXRoLm1heCh3aWR0aCAvIHRpbGVTaXplWzBdLCBoZWlnaHQgLyB0aWxlU2l6ZVsxXSk7XG4gIHZhciBsZW5ndGggPSBtYXhab29tICsgMTtcbiAgdmFyIHJlc29sdXRpb25zID0gbmV3IEFycmF5KGxlbmd0aCk7XG5cbiAgZm9yICh2YXIgeiA9IDA7IHogPCBsZW5ndGg7ICsreikge1xuICAgIHJlc29sdXRpb25zW3pdID0gbWF4UmVzb2x1dGlvbiAvIE1hdGgucG93KDIsIHopO1xuICB9XG5cbiAgcmV0dXJuIHJlc29sdXRpb25zO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfbWF4Wm9vbSBNYXhpbXVtIHpvb20gbGV2ZWwgKGRlZmF1bHQgaXNcbiAqICAgICBERUZBVUxUX01BWF9aT09NKS5cbiAqIEBwYXJhbSB7bnVtYmVyfGltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplPX0gb3B0X3RpbGVTaXplIFRpbGUgc2l6ZSAoZGVmYXVsdCB1c2VzXG4gKiAgICAgREVGQVVMVF9USUxFX1NJWkUpLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC9Db3JuZXIuanNcIikuZGVmYXVsdD19IG9wdF9jb3JuZXIgRXh0ZW50IGNvcm5lciAoZGVmYXVsdCBpcyBgJ3RvcC1sZWZ0J2ApLlxuICogQHJldHVybiB7IVRpbGVHcmlkfSBUaWxlR3JpZCBpbnN0YW5jZS5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24sIG9wdF9tYXhab29tLCBvcHRfdGlsZVNpemUsIG9wdF9jb3JuZXIpIHtcbiAgdmFyIGV4dGVudCA9IGV4dGVudEZyb21Qcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICByZXR1cm4gY3JlYXRlRm9yRXh0ZW50KGV4dGVudCwgb3B0X21heFpvb20sIG9wdF90aWxlU2l6ZSwgb3B0X2Nvcm5lcik7XG59XG4vKipcbiAqIEdlbmVyYXRlIGEgdGlsZSBncmlkIGV4dGVudCBmcm9tIGEgcHJvamVjdGlvbi4gIElmIHRoZSBwcm9qZWN0aW9uIGhhcyBhblxuICogZXh0ZW50LCBpdCBpcyB1c2VkLiAgSWYgbm90LCBhIGdsb2JhbCBleHRlbnQgaXMgYXNzdW1lZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW50RnJvbVByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICBwcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgdmFyIGV4dGVudCA9IHByb2plY3Rpb24uZ2V0RXh0ZW50KCk7XG5cbiAgaWYgKCFleHRlbnQpIHtcbiAgICB2YXIgaGFsZiA9IDE4MCAqIE1FVEVSU19QRVJfVU5JVFtVbml0cy5ERUdSRUVTXSAvIHByb2plY3Rpb24uZ2V0TWV0ZXJzUGVyVW5pdCgpO1xuICAgIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlKC1oYWxmLCAtaGFsZiwgaGFsZiwgaGFsZik7XG4gIH1cblxuICByZXR1cm4gZXh0ZW50O1xufSIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvRmVhdHVyZVxuICovXG5cblxuaW1wb3J0IEJhc2VPYmplY3QsIHsgZ2V0Q2hhbmdlRXZlbnRUeXBlIH0gZnJvbSAnLi9PYmplY3QuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4vZXZlbnRzLmpzJztcbi8qKlxuICogQHR5cGVkZWYge3R5cGVvZiBGZWF0dXJlfHR5cGVvZiBpbXBvcnQoXCIuL3JlbmRlci9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9IEZlYXR1cmVDbGFzc1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0ZlYXR1cmV8aW1wb3J0KFwiLi9yZW5kZXIvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBGZWF0dXJlTGlrZVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQSB2ZWN0b3Igb2JqZWN0IGZvciBnZW9ncmFwaGljIGZlYXR1cmVzIHdpdGggYSBnZW9tZXRyeSBhbmQgb3RoZXJcbiAqIGF0dHJpYnV0ZSBwcm9wZXJ0aWVzLCBzaW1pbGFyIHRvIHRoZSBmZWF0dXJlcyBpbiB2ZWN0b3IgZmlsZSBmb3JtYXRzIGxpa2VcbiAqIEdlb0pTT04uXG4gKlxuICogRmVhdHVyZXMgY2FuIGJlIHN0eWxlZCBpbmRpdmlkdWFsbHkgd2l0aCBgc2V0U3R5bGVgOyBvdGhlcndpc2UgdGhleSB1c2UgdGhlXG4gKiBzdHlsZSBvZiB0aGVpciB2ZWN0b3IgbGF5ZXIuXG4gKlxuICogTm90ZSB0aGF0IGF0dHJpYnV0ZSBwcm9wZXJ0aWVzIGFyZSBzZXQgYXMge0BsaW5rIG1vZHVsZTpvbC9PYmplY3R9IHByb3BlcnRpZXMgb25cbiAqIHRoZSBmZWF0dXJlIG9iamVjdCwgc28gdGhleSBhcmUgb2JzZXJ2YWJsZSwgYW5kIGhhdmUgZ2V0L3NldCBhY2Nlc3NvcnMuXG4gKlxuICogVHlwaWNhbGx5LCBhIGZlYXR1cmUgaGFzIGEgc2luZ2xlIGdlb21ldHJ5IHByb3BlcnR5LiBZb3UgY2FuIHNldCB0aGVcbiAqIGdlb21ldHJ5IHVzaW5nIHRoZSBgc2V0R2VvbWV0cnlgIG1ldGhvZCBhbmQgZ2V0IGl0IHdpdGggYGdldEdlb21ldHJ5YC5cbiAqIEl0IGlzIHBvc3NpYmxlIHRvIHN0b3JlIG1vcmUgdGhhbiBvbmUgZ2VvbWV0cnkgb24gYSBmZWF0dXJlIHVzaW5nIGF0dHJpYnV0ZVxuICogcHJvcGVydGllcy4gQnkgZGVmYXVsdCwgdGhlIGdlb21ldHJ5IHVzZWQgZm9yIHJlbmRlcmluZyBpcyBpZGVudGlmaWVkIGJ5XG4gKiB0aGUgcHJvcGVydHkgbmFtZSBgZ2VvbWV0cnlgLiBJZiB5b3Ugd2FudCB0byB1c2UgYW5vdGhlciBnZW9tZXRyeSBwcm9wZXJ0eVxuICogZm9yIHJlbmRlcmluZywgdXNlIHRoZSBgc2V0R2VvbWV0cnlOYW1lYCBtZXRob2QgdG8gY2hhbmdlIHRoZSBhdHRyaWJ1dGVcbiAqIHByb3BlcnR5IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2VvbWV0cnkgZm9yIHRoZSBmZWF0dXJlLiAgRm9yIGV4YW1wbGU6XG4gKlxuICogYGBganNcbiAqXG4gKiBpbXBvcnQgRmVhdHVyZSBmcm9tICdvbC9GZWF0dXJlJztcbiAqIGltcG9ydCBQb2x5Z29uIGZyb20gJ29sL2dlb20vUG9seWdvbic7XG4gKiBpbXBvcnQgUG9pbnQgZnJvbSAnb2wvZ2VvbS9Qb2ludCc7XG4gKlxuICogdmFyIGZlYXR1cmUgPSBuZXcgRmVhdHVyZSh7XG4gKiAgIGdlb21ldHJ5OiBuZXcgUG9seWdvbihwb2x5Q29vcmRzKSxcbiAqICAgbGFiZWxQb2ludDogbmV3IFBvaW50KGxhYmVsQ29vcmRzKSxcbiAqICAgbmFtZTogJ015IFBvbHlnb24nXG4gKiB9KTtcbiAqXG4gKiAvLyBnZXQgdGhlIHBvbHlnb24gZ2VvbWV0cnlcbiAqIHZhciBwb2x5ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuICpcbiAqIC8vIFJlbmRlciB0aGUgZmVhdHVyZSBhcyBhIHBvaW50IHVzaW5nIHRoZSBjb29yZGluYXRlcyBmcm9tIGxhYmVsUG9pbnRcbiAqIGZlYXR1cmUuc2V0R2VvbWV0cnlOYW1lKCdsYWJlbFBvaW50Jyk7XG4gKlxuICogLy8gZ2V0IHRoZSBwb2ludCBnZW9tZXRyeVxuICogdmFyIHBvaW50ID0gZmVhdHVyZS5nZXRHZW9tZXRyeSgpO1xuICogYGBgXG4gKlxuICogQGFwaVxuICogQHRlbXBsYXRlIHtpbXBvcnQoXCIuL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gR2VvbWV0cnlcbiAqL1xuXG52YXIgRmVhdHVyZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhGZWF0dXJlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtHZW9tZXRyeXxPYmplY3Q8c3RyaW5nLCAqPj19IG9wdF9nZW9tZXRyeU9yUHJvcGVydGllc1xuICAgKiAgICAgWW91IG1heSBwYXNzIGEgR2VvbWV0cnkgb2JqZWN0IGRpcmVjdGx5LCBvciBhbiBvYmplY3QgbGl0ZXJhbCBjb250YWluaW5nXG4gICAqICAgICBwcm9wZXJ0aWVzLiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgbGl0ZXJhbCwgeW91IG1heSBpbmNsdWRlIGEgR2VvbWV0cnlcbiAgICogICAgIGFzc29jaWF0ZWQgd2l0aCBhIGBnZW9tZXRyeWAga2V5LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIEZlYXR1cmUob3B0X2dlb21ldHJ5T3JQcm9wZXJ0aWVzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuaWRfID0gdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLmdlb21ldHJ5TmFtZV8gPSAnZ2VvbWV0cnknO1xuICAgIC8qKlxuICAgICAqIFVzZXIgcHJvdmlkZWQgc3R5bGUuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUxpa2V9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHlsZV8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVGdW5jdGlvbnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5zdHlsZUZ1bmN0aW9uXyA9IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi9ldmVudHMuanNcIikuRXZlbnRzS2V5fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZ2VvbWV0cnlDaGFuZ2VLZXlfID0gbnVsbDtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKF90aGlzLmdlb21ldHJ5TmFtZV8pLCBfdGhpcy5oYW5kbGVHZW9tZXRyeUNoYW5nZWRfKTtcblxuICAgIGlmIChvcHRfZ2VvbWV0cnlPclByb3BlcnRpZXMpIHtcbiAgICAgIGlmICh0eXBlb2ZcbiAgICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICAgIG9wdF9nZW9tZXRyeU9yUHJvcGVydGllcy5nZXRTaW1wbGlmaWVkR2VvbWV0cnkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdmFyIGdlb21ldHJ5ID1cbiAgICAgICAgLyoqIEB0eXBlIHtHZW9tZXRyeX0gKi9cbiAgICAgICAgb3B0X2dlb21ldHJ5T3JQcm9wZXJ0aWVzO1xuXG4gICAgICAgIF90aGlzLnNldEdlb21ldHJ5KGdlb21ldHJ5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgKj59ICovXG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0gb3B0X2dlb21ldHJ5T3JQcm9wZXJ0aWVzO1xuXG4gICAgICAgIF90aGlzLnNldFByb3BlcnRpZXMocHJvcGVydGllcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDbG9uZSB0aGlzIGZlYXR1cmUuIElmIHRoZSBvcmlnaW5hbCBmZWF0dXJlIGhhcyBhIGdlb21ldHJ5IGl0XG4gICAqIGlzIGFsc28gY2xvbmVkLiBUaGUgZmVhdHVyZSBpZCBpcyBub3Qgc2V0IGluIHRoZSBjbG9uZS5cbiAgICogQHJldHVybiB7RmVhdHVyZX0gVGhlIGNsb25lLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNsb25lID0gbmV3IEZlYXR1cmUodGhpcy5oYXNQcm9wZXJ0aWVzKCkgPyB0aGlzLmdldFByb3BlcnRpZXMoKSA6IG51bGwpO1xuICAgIGNsb25lLnNldEdlb21ldHJ5TmFtZSh0aGlzLmdldEdlb21ldHJ5TmFtZSgpKTtcbiAgICB2YXIgZ2VvbWV0cnkgPSB0aGlzLmdldEdlb21ldHJ5KCk7XG5cbiAgICBpZiAoZ2VvbWV0cnkpIHtcbiAgICAgIGNsb25lLnNldEdlb21ldHJ5KGdlb21ldHJ5LmNsb25lKCkpO1xuICAgIH1cblxuICAgIHZhciBzdHlsZSA9IHRoaXMuZ2V0U3R5bGUoKTtcblxuICAgIGlmIChzdHlsZSkge1xuICAgICAgY2xvbmUuc2V0U3R5bGUoc3R5bGUpO1xuICAgIH1cblxuICAgIHJldHVybiBjbG9uZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZSdzIGRlZmF1bHQgZ2VvbWV0cnkuICBBIGZlYXR1cmUgbWF5IGhhdmUgYW55IG51bWJlciBvZiBuYW1lZFxuICAgKiBnZW9tZXRyaWVzLiAgVGhlIFwiZGVmYXVsdFwiIGdlb21ldHJ5ICh0aGUgb25lIHRoYXQgaXMgcmVuZGVyZWQgYnkgZGVmYXVsdCkgaXNcbiAgICogc2V0IHdoZW4gY2FsbGluZyB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmV+RmVhdHVyZSNzZXRHZW9tZXRyeX0uXG4gICAqIEByZXR1cm4ge0dlb21ldHJ5fHVuZGVmaW5lZH0gVGhlIGRlZmF1bHQgZ2VvbWV0cnkgZm9yIHRoZSBmZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuZ2V0R2VvbWV0cnkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7R2VvbWV0cnl8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQodGhpcy5nZW9tZXRyeU5hbWVfKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGZlYXR1cmUgaWRlbnRpZmllci4gIFRoaXMgaXMgYSBzdGFibGUgaWRlbnRpZmllciBmb3IgdGhlIGZlYXR1cmUgYW5kXG4gICAqIGlzIGVpdGhlciBzZXQgd2hlbiByZWFkaW5nIGRhdGEgZnJvbSBhIHJlbW90ZSBzb3VyY2Ugb3Igc2V0IGV4cGxpY2l0bHkgYnlcbiAgICogY2FsbGluZyB7QGxpbmsgbW9kdWxlOm9sL0ZlYXR1cmV+RmVhdHVyZSNzZXRJZH0uXG4gICAqIEByZXR1cm4ge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfSBJZC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEZlYXR1cmUucHJvdG90eXBlLmdldElkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmlkXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgbmFtZSBvZiB0aGUgZmVhdHVyZSdzIGRlZmF1bHQgZ2VvbWV0cnkuICBCeSBkZWZhdWx0LCB0aGUgZGVmYXVsdFxuICAgKiBnZW9tZXRyeSBpcyBuYW1lZCBgZ2VvbWV0cnlgLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IEdldCB0aGUgcHJvcGVydHkgbmFtZSBhc3NvY2lhdGVkIHdpdGggdGhlIGRlZmF1bHQgZ2VvbWV0cnlcbiAgICogICAgIGZvciB0aGlzIGZlYXR1cmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBGZWF0dXJlLnByb3RvdHlwZS5nZXRHZW9tZXRyeU5hbWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2VvbWV0cnlOYW1lXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZSdzIHN0eWxlLiBXaWxsIHJldHVybiB3aGF0IHdhcyBwcm92aWRlZCB0byB0aGVcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfkZlYXR1cmUjc2V0U3R5bGV9IG1ldGhvZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUxpa2V8dW5kZWZpbmVkfSBUaGUgZmVhdHVyZSBzdHlsZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEZlYXR1cmUucHJvdG90eXBlLmdldFN0eWxlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnN0eWxlXztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZSdzIHN0eWxlIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlRnVuY3Rpb258dW5kZWZpbmVkfSBSZXR1cm4gYSBmdW5jdGlvblxuICAgKiByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgc3R5bGUgb2YgdGhpcyBmZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuZ2V0U3R5bGVGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdHlsZUZ1bmN0aW9uXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuaGFuZGxlR2VvbWV0cnlDaGFuZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBGZWF0dXJlLnByb3RvdHlwZS5oYW5kbGVHZW9tZXRyeUNoYW5nZWRfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmdlb21ldHJ5Q2hhbmdlS2V5Xykge1xuICAgICAgdW5saXN0ZW5CeUtleSh0aGlzLmdlb21ldHJ5Q2hhbmdlS2V5Xyk7XG4gICAgICB0aGlzLmdlb21ldHJ5Q2hhbmdlS2V5XyA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGdlb21ldHJ5ID0gdGhpcy5nZXRHZW9tZXRyeSgpO1xuXG4gICAgaWYgKGdlb21ldHJ5KSB7XG4gICAgICB0aGlzLmdlb21ldHJ5Q2hhbmdlS2V5XyA9IGxpc3RlbihnZW9tZXRyeSwgRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVHZW9tZXRyeUNoYW5nZV8sIHRoaXMpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBkZWZhdWx0IGdlb21ldHJ5IGZvciB0aGUgZmVhdHVyZS4gIFRoaXMgd2lsbCB1cGRhdGUgdGhlIHByb3BlcnR5XG4gICAqIHdpdGggdGhlIG5hbWUgcmV0dXJuZWQgYnkge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfkZlYXR1cmUjZ2V0R2VvbWV0cnlOYW1lfS5cbiAgICogQHBhcmFtIHtHZW9tZXRyeXx1bmRlZmluZWR9IGdlb21ldHJ5IFRoZSBuZXcgZ2VvbWV0cnkuXG4gICAqIEBhcGlcbiAgICogQG9ic2VydmFibGVcbiAgICovXG5cblxuICBGZWF0dXJlLnByb3RvdHlwZS5zZXRHZW9tZXRyeSA9IGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIHRoaXMuc2V0KHRoaXMuZ2VvbWV0cnlOYW1lXywgZ2VvbWV0cnkpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBzdHlsZSBmb3IgdGhlIGZlYXR1cmUgdG8gb3ZlcnJpZGUgdGhlIGxheWVyIHN0eWxlLiAgVGhpcyBjYW4gYmUgYVxuICAgKiBzaW5nbGUgc3R5bGUgb2JqZWN0LCBhbiBhcnJheSBvZiBzdHlsZXMsIG9yIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhXG4gICAqIHJlc29sdXRpb24gYW5kIHJldHVybnMgYW4gYXJyYXkgb2Ygc3R5bGVzLiBUbyB1bnNldCB0aGUgZmVhdHVyZSBzdHlsZSwgY2FsbFxuICAgKiBgc2V0U3R5bGUoKWAgd2l0aG91dCBhcmd1bWVudHMgb3IgYSBmYWxzZXkgdmFsdWUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZUxpa2U9fSBvcHRfc3R5bGUgU3R5bGUgZm9yIHRoaXMgZmVhdHVyZS5cbiAgICogQGFwaVxuICAgKiBAZmlyZXMgbW9kdWxlOm9sL2V2ZW50cy9FdmVudH5CYXNlRXZlbnQjZXZlbnQ6Y2hhbmdlXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuc2V0U3R5bGUgPSBmdW5jdGlvbiAob3B0X3N0eWxlKSB7XG4gICAgdGhpcy5zdHlsZV8gPSBvcHRfc3R5bGU7XG4gICAgdGhpcy5zdHlsZUZ1bmN0aW9uXyA9ICFvcHRfc3R5bGUgPyB1bmRlZmluZWQgOiBjcmVhdGVTdHlsZUZ1bmN0aW9uKG9wdF9zdHlsZSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGZlYXR1cmUgaWQuICBUaGUgZmVhdHVyZSBpZCBpcyBjb25zaWRlcmVkIHN0YWJsZSBhbmQgbWF5IGJlIHVzZWQgd2hlblxuICAgKiByZXF1ZXN0aW5nIGZlYXR1cmVzIG9yIGNvbXBhcmluZyBpZGVudGlmaWVycyByZXR1cm5lZCBmcm9tIGEgcmVtb3RlIHNvdXJjZS5cbiAgICogVGhlIGZlYXR1cmUgaWQgY2FuIGJlIHVzZWQgd2l0aCB0aGVcbiAgICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVmVjdG9yflZlY3RvclNvdXJjZSNnZXRGZWF0dXJlQnlJZH0gbWV0aG9kLlxuICAgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd8dW5kZWZpbmVkfSBpZCBUaGUgZmVhdHVyZSBpZC5cbiAgICogQGFwaVxuICAgKiBAZmlyZXMgbW9kdWxlOm9sL2V2ZW50cy9FdmVudH5CYXNlRXZlbnQjZXZlbnQ6Y2hhbmdlXG4gICAqL1xuXG5cbiAgRmVhdHVyZS5wcm90b3R5cGUuc2V0SWQgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICB0aGlzLmlkXyA9IGlkO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBwcm9wZXJ0eSBuYW1lIHRvIGJlIHVzZWQgd2hlbiBnZXR0aW5nIHRoZSBmZWF0dXJlJ3MgZGVmYXVsdCBnZW9tZXRyeS5cbiAgICogV2hlbiBjYWxsaW5nIHtAbGluayBtb2R1bGU6b2wvRmVhdHVyZX5GZWF0dXJlI2dldEdlb21ldHJ5fSwgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSB3aXRoXG4gICAqIHRoaXMgbmFtZSB3aWxsIGJlIHJldHVybmVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSBUaGUgcHJvcGVydHkgbmFtZSBvZiB0aGUgZGVmYXVsdCBnZW9tZXRyeS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEZlYXR1cmUucHJvdG90eXBlLnNldEdlb21ldHJ5TmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZSh0aGlzLmdlb21ldHJ5TmFtZV8pLCB0aGlzLmhhbmRsZUdlb21ldHJ5Q2hhbmdlZF8pO1xuICAgIHRoaXMuZ2VvbWV0cnlOYW1lXyA9IG5hbWU7XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZSh0aGlzLmdlb21ldHJ5TmFtZV8pLCB0aGlzLmhhbmRsZUdlb21ldHJ5Q2hhbmdlZF8pO1xuICAgIHRoaXMuaGFuZGxlR2VvbWV0cnlDaGFuZ2VkXygpO1xuICB9O1xuXG4gIHJldHVybiBGZWF0dXJlO1xufShCYXNlT2JqZWN0KTtcbi8qKlxuICogQ29udmVydCB0aGUgcHJvdmlkZWQgb2JqZWN0IGludG8gYSBmZWF0dXJlIHN0eWxlIGZ1bmN0aW9uLiAgRnVuY3Rpb25zIHBhc3NlZFxuICogdGhyb3VnaCB1bmNoYW5nZWQuICBBcnJheXMgb2YgU3R5bGUgb3Igc2luZ2xlIHN0eWxlIG9iamVjdHMgd3JhcHBlZFxuICogaW4gYSBuZXcgZmVhdHVyZSBzdHlsZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7IWltcG9ydChcIi4vc3R5bGUvU3R5bGUuanNcIikuU3R5bGVGdW5jdGlvbnwhQXJyYXk8aW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0PnwhaW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSBvYmpcbiAqICAgICBBIGZlYXR1cmUgc3R5bGUgZnVuY3Rpb24sIGEgc2luZ2xlIHN0eWxlLCBvciBhbiBhcnJheSBvZiBzdHlsZXMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlRnVuY3Rpb259IEEgc3R5bGUgZnVuY3Rpb24uXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3R5bGVGdW5jdGlvbihvYmopIHtcbiAgaWYgKHR5cGVvZiBvYmogPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxpbXBvcnQoXCIuL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuICAgIHZhciBzdHlsZXNfMTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgIHN0eWxlc18xID0gb2JqO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnQodHlwZW9mXG4gICAgICAvKiogQHR5cGUgez99ICovXG4gICAgICBvYmouZ2V0WkluZGV4ID09PSAnZnVuY3Rpb24nLCA0MSk7IC8vIEV4cGVjdGVkIGFuIGBpbXBvcnQoXCIuL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlYCBvciBhbiBhcnJheSBvZiBgaW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5TdHlsZWBcblxuICAgICAgdmFyIHN0eWxlID1cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgb2JqO1xuICAgICAgc3R5bGVzXzEgPSBbc3R5bGVdO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gc3R5bGVzXzE7XG4gICAgfTtcbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgRmVhdHVyZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2dlb20vR2VvbWV0cnlDb2xsZWN0aW9uXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IEdlb21ldHJ5IGZyb20gJy4vR2VvbWV0cnkuanMnO1xuaW1wb3J0IEdlb21ldHJ5VHlwZSBmcm9tICcuL0dlb21ldHJ5VHlwZS5qcyc7XG5pbXBvcnQgeyBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFksIGNyZWF0ZU9yVXBkYXRlRW1wdHksIGV4dGVuZCwgZ2V0Q2VudGVyIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGxpc3RlbiwgdW5saXN0ZW5CeUtleSB9IGZyb20gJy4uL2V2ZW50cy5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEFuIGFycmF5IG9mIHtAbGluayBtb2R1bGU6b2wvZ2VvbS9HZW9tZXRyeX0gb2JqZWN0cy5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIEdlb21ldHJ5Q29sbGVjdGlvbiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhHZW9tZXRyeUNvbGxlY3Rpb24sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PEdlb21ldHJ5Pj19IG9wdF9nZW9tZXRyaWVzIEdlb21ldHJpZXMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gR2VvbWV0cnlDb2xsZWN0aW9uKG9wdF9nZW9tZXRyaWVzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxHZW9tZXRyeT59XG4gICAgICovXG5cblxuICAgIF90aGlzLmdlb21ldHJpZXNfID0gb3B0X2dlb21ldHJpZXMgPyBvcHRfZ2VvbWV0cmllcyA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuY2hhbmdlRXZlbnRzS2V5c18gPSBbXTtcblxuICAgIF90aGlzLmxpc3Rlbkdlb21ldHJpZXNDaGFuZ2VfKCk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgR2VvbWV0cnlDb2xsZWN0aW9uLnByb3RvdHlwZS51bmxpc3Rlbkdlb21ldHJpZXNDaGFuZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2hhbmdlRXZlbnRzS2V5c18uZm9yRWFjaCh1bmxpc3RlbkJ5S2V5KTtcbiAgICB0aGlzLmNoYW5nZUV2ZW50c0tleXNfLmxlbmd0aCA9IDA7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUubGlzdGVuR2VvbWV0cmllc0NoYW5nZV8gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmdlb21ldHJpZXNfKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gdGhpcy5nZW9tZXRyaWVzXy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB0aGlzLmNoYW5nZUV2ZW50c0tleXNfLnB1c2gobGlzdGVuKHRoaXMuZ2VvbWV0cmllc19baV0sIEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMuY2hhbmdlZCwgdGhpcykpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIE1ha2UgYSBjb21wbGV0ZSBjb3B5IG9mIHRoZSBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7IUdlb21ldHJ5Q29sbGVjdGlvbn0gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBnZW9tZXRyeUNvbGxlY3Rpb24gPSBuZXcgR2VvbWV0cnlDb2xsZWN0aW9uKG51bGwpO1xuICAgIGdlb21ldHJ5Q29sbGVjdGlvbi5zZXRHZW9tZXRyaWVzKHRoaXMuZ2VvbWV0cmllc18pO1xuICAgIGdlb21ldHJ5Q29sbGVjdGlvbi5hcHBseVByb3BlcnRpZXModGhpcyk7XG4gICAgcmV0dXJuIGdlb21ldHJ5Q29sbGVjdGlvbjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUuY2xvc2VzdFBvaW50WFkgPSBmdW5jdGlvbiAoeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpIHtcbiAgICBpZiAobWluU3F1YXJlZERpc3RhbmNlIDwgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZKHRoaXMuZ2V0RXh0ZW50KCksIHgsIHkpKSB7XG4gICAgICByZXR1cm4gbWluU3F1YXJlZERpc3RhbmNlO1xuICAgIH1cblxuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgbWluU3F1YXJlZERpc3RhbmNlID0gZ2VvbWV0cmllc1tpXS5jbG9zZXN0UG9pbnRYWSh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENvbnRhaW5zICh4LCB5KS5cbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmNvbnRhaW5zWFkgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgaWYgKGdlb21ldHJpZXNbaV0uY29udGFpbnNYWSh4LCB5KSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmNvbXB1dGVFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgY3JlYXRlT3JVcGRhdGVFbXB0eShleHRlbnQpO1xuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgZXh0ZW5kKGV4dGVudCwgZ2VvbWV0cmllc1tpXS5nZXRFeHRlbnQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgZ2VvbWV0cmllcyB0aGF0IG1ha2UgdXAgdGhpcyBnZW9tZXRyeSBjb2xsZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtBcnJheTxHZW9tZXRyeT59IEdlb21ldHJpZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmdldEdlb21ldHJpZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNsb25lR2VvbWV0cmllcyh0aGlzLmdlb21ldHJpZXNfKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PEdlb21ldHJ5Pn0gR2VvbWV0cmllcy5cbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmdldEdlb21ldHJpZXNBcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZW9tZXRyaWVzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PEdlb21ldHJ5Pn0gR2VvbWV0cmllcy5cbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmdldEdlb21ldHJpZXNBcnJheVJlY3Vyc2l2ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PEdlb21ldHJ5Pn0gKi9cbiAgICB2YXIgZ2VvbWV0cmllc0FycmF5ID0gW107XG4gICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXNfO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBpZiAoZ2VvbWV0cmllc1tpXS5nZXRUeXBlKCkgPT09IHRoaXMuZ2V0VHlwZSgpKSB7XG4gICAgICAgIGdlb21ldHJpZXNBcnJheSA9IGdlb21ldHJpZXNBcnJheS5jb25jYXQoXG4gICAgICAgIC8qKiBAdHlwZSB7R2VvbWV0cnlDb2xsZWN0aW9ufSAqL1xuICAgICAgICBnZW9tZXRyaWVzW2ldLmdldEdlb21ldHJpZXNBcnJheVJlY3Vyc2l2ZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGdlb21ldHJpZXNBcnJheS5wdXNoKGdlb21ldHJpZXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBnZW9tZXRyaWVzQXJyYXk7XG4gIH07XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzaW1wbGlmaWVkIHZlcnNpb24gb2YgdGhpcyBnZW9tZXRyeSB1c2luZyB0aGUgRG91Z2xhcyBQZXVja2VyIGFsZ29yaXRobS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge0dlb21ldHJ5Q29sbGVjdGlvbn0gU2ltcGxpZmllZCBHZW9tZXRyeUNvbGxlY3Rpb24uXG4gICAqL1xuXG5cbiAgR2VvbWV0cnlDb2xsZWN0aW9uLnByb3RvdHlwZS5nZXRTaW1wbGlmaWVkR2VvbWV0cnkgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIGlmICh0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeVJldmlzaW9uICE9PSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSA9IDA7XG4gICAgICB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeVJldmlzaW9uID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIGlmIChzcXVhcmVkVG9sZXJhbmNlIDwgMCB8fCB0aGlzLnNpbXBsaWZpZWRHZW9tZXRyeU1heE1pblNxdWFyZWRUb2xlcmFuY2UgIT09IDAgJiYgc3F1YXJlZFRvbGVyYW5jZSA8IHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIHNpbXBsaWZpZWRHZW9tZXRyaWVzID0gW107XG4gICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXNfO1xuICAgIHZhciBzaW1wbGlmaWVkID0gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBnZW9tZXRyaWVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBnZW9tZXRyeSA9IGdlb21ldHJpZXNbaV07XG4gICAgICB2YXIgc2ltcGxpZmllZEdlb21ldHJ5ID0gZ2VvbWV0cnkuZ2V0U2ltcGxpZmllZEdlb21ldHJ5KHNxdWFyZWRUb2xlcmFuY2UpO1xuICAgICAgc2ltcGxpZmllZEdlb21ldHJpZXMucHVzaChzaW1wbGlmaWVkR2VvbWV0cnkpO1xuXG4gICAgICBpZiAoc2ltcGxpZmllZEdlb21ldHJ5ICE9PSBnZW9tZXRyeSkge1xuICAgICAgICBzaW1wbGlmaWVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2ltcGxpZmllZCkge1xuICAgICAgdmFyIHNpbXBsaWZpZWRHZW9tZXRyeUNvbGxlY3Rpb24gPSBuZXcgR2VvbWV0cnlDb2xsZWN0aW9uKG51bGwpO1xuICAgICAgc2ltcGxpZmllZEdlb21ldHJ5Q29sbGVjdGlvbi5zZXRHZW9tZXRyaWVzQXJyYXkoc2ltcGxpZmllZEdlb21ldHJpZXMpO1xuICAgICAgcmV0dXJuIHNpbXBsaWZpZWRHZW9tZXRyeUNvbGxlY3Rpb247XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2ltcGxpZmllZEdlb21ldHJ5TWF4TWluU3F1YXJlZFRvbGVyYW5jZSA9IHNxdWFyZWRUb2xlcmFuY2U7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT047XG4gIH07XG4gIC8qKlxuICAgKiBUZXN0IGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIHBhc3NlZCBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBleHRlbnQgaW50ZXJzZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnlDb2xsZWN0aW9uLnByb3RvdHlwZS5pbnRlcnNlY3RzRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgaWYgKGdlb21ldHJpZXNbaV0uaW50ZXJzZWN0c0V4dGVudChleHRlbnQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IElzIGVtcHR5LlxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZW9tZXRyaWVzXy5sZW5ndGggPT09IDA7XG4gIH07XG4gIC8qKlxuICAgKiBSb3RhdGUgdGhlIGdlb21ldHJ5IGFyb3VuZCBhIGdpdmVuIGNvb3JkaW5hdGUuIFRoaXMgbW9kaWZpZXMgdGhlIGdlb21ldHJ5XG4gICAqIGNvb3JkaW5hdGVzIGluIHBsYWNlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYW5nbGUgUm90YXRpb24gYW5nbGUgaW4gcmFkaWFucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGFuY2hvciBUaGUgcm90YXRpb24gY2VudGVyLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnlDb2xsZWN0aW9uLnByb3RvdHlwZS5yb3RhdGUgPSBmdW5jdGlvbiAoYW5nbGUsIGFuY2hvcikge1xuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgZ2VvbWV0cmllc1tpXS5yb3RhdGUoYW5nbGUsIGFuY2hvcik7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBTY2FsZSB0aGUgZ2VvbWV0cnkgKHdpdGggYW4gb3B0aW9uYWwgb3JpZ2luKS4gIFRoaXMgbW9kaWZpZXMgdGhlIGdlb21ldHJ5XG4gICAqIGNvb3JkaW5hdGVzIGluIHBsYWNlLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN4IFRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeC1kaXJlY3Rpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X3N5IFRoZSBzY2FsaW5nIGZhY3RvciBpbiB0aGUgeS1kaXJlY3Rpb24gKGRlZmF1bHRzIHRvIHN4KS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU9fSBvcHRfYW5jaG9yIFRoZSBzY2FsZSBvcmlnaW4gKGRlZmF1bHRzIHRvIHRoZSBjZW50ZXJcbiAgICogICAgIG9mIHRoZSBnZW9tZXRyeSBleHRlbnQpLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvbWV0cnlDb2xsZWN0aW9uLnByb3RvdHlwZS5zY2FsZSA9IGZ1bmN0aW9uIChzeCwgb3B0X3N5LCBvcHRfYW5jaG9yKSB7XG4gICAgdmFyIGFuY2hvciA9IG9wdF9hbmNob3I7XG5cbiAgICBpZiAoIWFuY2hvcikge1xuICAgICAgYW5jaG9yID0gZ2V0Q2VudGVyKHRoaXMuZ2V0RXh0ZW50KCkpO1xuICAgIH1cblxuICAgIHZhciBnZW9tZXRyaWVzID0gdGhpcy5nZW9tZXRyaWVzXztcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb21ldHJpZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgZ2VvbWV0cmllc1tpXS5zY2FsZShzeCwgb3B0X3N5LCBhbmNob3IpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBnZW9tZXRyaWVzIHRoYXQgbWFrZSB1cCB0aGlzIGdlb21ldHJ5IGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXk8R2VvbWV0cnk+fSBnZW9tZXRyaWVzIEdlb21ldHJpZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLnNldEdlb21ldHJpZXMgPSBmdW5jdGlvbiAoZ2VvbWV0cmllcykge1xuICAgIHRoaXMuc2V0R2VvbWV0cmllc0FycmF5KGNsb25lR2VvbWV0cmllcyhnZW9tZXRyaWVzKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PEdlb21ldHJ5Pn0gZ2VvbWV0cmllcyBHZW9tZXRyaWVzLlxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUuc2V0R2VvbWV0cmllc0FycmF5ID0gZnVuY3Rpb24gKGdlb21ldHJpZXMpIHtcbiAgICB0aGlzLnVubGlzdGVuR2VvbWV0cmllc0NoYW5nZV8oKTtcbiAgICB0aGlzLmdlb21ldHJpZXNfID0gZ2VvbWV0cmllcztcbiAgICB0aGlzLmxpc3Rlbkdlb21ldHJpZXNDaGFuZ2VfKCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBBcHBseSBhIHRyYW5zZm9ybSBmdW5jdGlvbiB0byB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBUaGUgZ2VvbWV0cnkgaXMgbW9kaWZpZWQgaW4gcGxhY2UuXG4gICAqIElmIHlvdSBkbyBub3Qgd2FudCB0aGUgZ2VvbWV0cnkgbW9kaWZpZWQgaW4gcGxhY2UsIGZpcnN0IGBjbG9uZSgpYCBpdCBhbmRcbiAgICogdGhlbiB1c2UgdGhpcyBmdW5jdGlvbiBvbiB0aGUgY2xvbmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtIGZ1bmN0aW9uLlxuICAgKiBDYWxsZWQgd2l0aCBhIGZsYXQgYXJyYXkgb2YgZ2VvbWV0cnkgY29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmFwcGx5VHJhbnNmb3JtID0gZnVuY3Rpb24gKHRyYW5zZm9ybUZuKSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXNfO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBnZW9tZXRyaWVzW2ldLmFwcGx5VHJhbnNmb3JtKHRyYW5zZm9ybUZuKTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFRyYW5zbGF0ZSB0aGUgZ2VvbWV0cnkuICBUaGlzIG1vZGlmaWVzIHRoZSBnZW9tZXRyeSBjb29yZGluYXRlcyBpbiBwbGFjZS4gIElmXG4gICAqIGluc3RlYWQgeW91IHdhbnQgYSBuZXcgZ2VvbWV0cnksIGZpcnN0IGBjbG9uZSgpYCB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gZGVsdGFYIERlbHRhIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVkgRGVsdGEgWS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb21ldHJ5Q29sbGVjdGlvbi5wcm90b3R5cGUudHJhbnNsYXRlID0gZnVuY3Rpb24gKGRlbHRhWCwgZGVsdGFZKSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSB0aGlzLmdlb21ldHJpZXNfO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICBnZW9tZXRyaWVzW2ldLnRyYW5zbGF0ZShkZWx0YVgsIGRlbHRhWSk7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBDbGVhbiB1cC5cbiAgICovXG5cblxuICBHZW9tZXRyeUNvbGxlY3Rpb24ucHJvdG90eXBlLmRpc3Bvc2VJbnRlcm5hbCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVubGlzdGVuR2VvbWV0cmllc0NoYW5nZV8oKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUuZGlzcG9zZUludGVybmFsLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIEdlb21ldHJ5Q29sbGVjdGlvbjtcbn0oR2VvbWV0cnkpO1xuLyoqXG4gKiBAcGFyYW0ge0FycmF5PEdlb21ldHJ5Pn0gZ2VvbWV0cmllcyBHZW9tZXRyaWVzLlxuICogQHJldHVybiB7QXJyYXk8R2VvbWV0cnk+fSBDbG9uZWQgZ2VvbWV0cmllcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIGNsb25lR2VvbWV0cmllcyhnZW9tZXRyaWVzKSB7XG4gIHZhciBjbG9uZWRHZW9tZXRyaWVzID0gW107XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2VvbWV0cmllcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgY2xvbmVkR2VvbWV0cmllcy5wdXNoKGdlb21ldHJpZXNbaV0uY2xvbmUoKSk7XG4gIH1cblxuICByZXR1cm4gY2xvbmVkR2VvbWV0cmllcztcbn1cblxuZXhwb3J0IGRlZmF1bHQgR2VvbWV0cnlDb2xsZWN0aW9uOyIsIi8qKlxuICogQG1vZHVsZSBvbC9mb3JtYXQvRmVhdHVyZVxuICovXG5pbXBvcnQgVW5pdHMgZnJvbSAnLi4vcHJvai9Vbml0cy5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi4vb2JqLmpzJztcbmltcG9ydCB7IGVxdWl2YWxlbnQgYXMgZXF1aXZhbGVudFByb2plY3Rpb24sIGdldCBhcyBnZXRQcm9qZWN0aW9uLCB0cmFuc2Zvcm1FeHRlbnQgfSBmcm9tICcuLi9wcm9qLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUmVhZE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5Qcm9qZWN0aW9uTGlrZX0gW2RhdGFQcm9qZWN0aW9uXSBQcm9qZWN0aW9uIG9mIHRoZSBkYXRhIHdlIGFyZSByZWFkaW5nLlxuICogSWYgbm90IHByb3ZpZGVkLCB0aGUgcHJvamVjdGlvbiB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgZGF0YSAod2hlcmUgcG9zc2libGUpIG9yXG4gKiB0aGUgYGRhdGFQcm9qZWN0aW9uYCBvZiB0aGUgZm9ybWF0IGlzIGFzc2lnbmVkICh3aGVyZSBzZXQpLiBJZiB0aGUgcHJvamVjdGlvblxuICogY2FuIG5vdCBiZSBkZXJpdmVkIGZyb20gdGhlIGRhdGEgYW5kIGlmIG5vIGBkYXRhUHJvamVjdGlvbmAgaXMgc2V0IGZvciBhIGZvcm1hdCxcbiAqIHRoZSBmZWF0dXJlcyB3aWxsIG5vdCBiZSByZXByb2plY3RlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF0gVGlsZSBleHRlbnQgaW4gbWFwIHVuaXRzIG9mIHRoZSB0aWxlIGJlaW5nIHJlYWQuXG4gKiBUaGlzIGlzIG9ubHkgcmVxdWlyZWQgd2hlbiByZWFkaW5nIGRhdGEgd2l0aCB0aWxlIHBpeGVscyBhcyBnZW9tZXRyeSB1bml0cy4gV2hlbiBjb25maWd1cmVkLFxuICogYSBgZGF0YVByb2plY3Rpb25gIHdpdGggYFRJTEVfUElYRUxTYCBhcyBgdW5pdHNgIGFuZCB0aGUgdGlsZSdzIHBpeGVsIGV4dGVudCBhcyBgZXh0ZW50YCBuZWVkcyB0byBiZVxuICogcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtmZWF0dXJlUHJvamVjdGlvbl0gUHJvamVjdGlvbiBvZiB0aGUgZmVhdHVyZSBnZW9tZXRyaWVzXG4gKiBjcmVhdGVkIGJ5IHRoZSBmb3JtYXQgcmVhZGVyLiBJZiBub3QgcHJvdmlkZWQsIGZlYXR1cmVzIHdpbGwgYmUgcmV0dXJuZWQgaW4gdGhlXG4gKiBgZGF0YVByb2plY3Rpb25gLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gV3JpdGVPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtkYXRhUHJvamVjdGlvbl0gUHJvamVjdGlvbiBvZiB0aGUgZGF0YSB3ZSBhcmUgd3JpdGluZy5cbiAqIElmIG5vdCBwcm92aWRlZCwgdGhlIGBkYXRhUHJvamVjdGlvbmAgb2YgdGhlIGZvcm1hdCBpcyBhc3NpZ25lZCAod2hlcmUgc2V0KS5cbiAqIElmIG5vIGBkYXRhUHJvamVjdGlvbmAgaXMgc2V0IGZvciBhIGZvcm1hdCwgdGhlIGZlYXR1cmVzIHdpbGwgYmUgcmV0dXJuZWRcbiAqIGluIHRoZSBgZmVhdHVyZVByb2plY3Rpb25gLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBbZmVhdHVyZVByb2plY3Rpb25dIFByb2plY3Rpb24gb2YgdGhlIGZlYXR1cmUgZ2VvbWV0cmllc1xuICogdGhhdCB3aWxsIGJlIHNlcmlhbGl6ZWQgYnkgdGhlIGZvcm1hdCB3cml0ZXIuIElmIG5vdCBwcm92aWRlZCwgZ2VvbWV0cmllcyBhcmUgYXNzdW1lZFxuICogdG8gYmUgaW4gdGhlIGBkYXRhUHJvamVjdGlvbmAgaWYgdGhhdCBpcyBzZXQ7IGluIG90aGVyIHdvcmRzLCB0aGV5IGFyZSBub3QgdHJhbnNmb3JtZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtyaWdodEhhbmRlZF0gV2hlbiB3cml0aW5nIGdlb21ldHJpZXMsIGZvbGxvdyB0aGUgcmlnaHQtaGFuZFxuICogcnVsZSBmb3IgbGluZWFyIHJpbmcgb3JpZW50YXRpb24uICBUaGlzIG1lYW5zIHRoYXQgcG9seWdvbnMgd2lsbCBoYXZlIGNvdW50ZXItY2xvY2t3aXNlXG4gKiBleHRlcmlvciByaW5ncyBhbmQgY2xvY2t3aXNlIGludGVyaW9yIHJpbmdzLiAgQnkgZGVmYXVsdCwgY29vcmRpbmF0ZXMgYXJlIHNlcmlhbGl6ZWRcbiAqIGFzIHRoZXkgYXJlIHByb3ZpZGVkIGF0IGNvbnN0cnVjdGlvbi4gIElmIGB0cnVlYCwgdGhlIHJpZ2h0LWhhbmQgcnVsZSB3aWxsXG4gKiBiZSBhcHBsaWVkLiAgSWYgYGZhbHNlYCwgdGhlIGxlZnQtaGFuZCBydWxlIHdpbGwgYmUgYXBwbGllZCAoY2xvY2t3aXNlIGZvclxuICogZXh0ZXJpb3IgYW5kIGNvdW50ZXItY2xvY2t3aXNlIGZvciBpbnRlcmlvciByaW5ncykuICBOb3RlIHRoYXQgbm90IGFsbFxuICogZm9ybWF0cyBzdXBwb3J0IHRoaXMuICBUaGUgR2VvSlNPTiBmb3JtYXQgZG9lcyB1c2UgdGhpcyBwcm9wZXJ0eSB3aGVuIHdyaXRpbmdcbiAqIGdlb21ldHJpZXMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2RlY2ltYWxzXSBNYXhpbXVtIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyBmb3IgY29vcmRpbmF0ZXMuXG4gKiBDb29yZGluYXRlcyBhcmUgc3RvcmVkIGludGVybmFsbHkgYXMgZmxvYXRzLCBidXQgZmxvYXRpbmctcG9pbnQgYXJpdGhtZXRpYyBjYW4gY3JlYXRlXG4gKiBjb29yZGluYXRlcyB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzLCBub3QgZ2VuZXJhbGx5IHdhbnRlZCBvbiBvdXRwdXQuXG4gKiBTZXQgYSBudW1iZXIgaGVyZSB0byByb3VuZCBjb29yZGluYXRlcy4gQ2FuIGFsc28gYmUgdXNlZCB0byBlbnN1cmUgdGhhdFxuICogY29vcmRpbmF0ZXMgcmVhZCBpbiBjYW4gYmUgd3JpdHRlbiBiYWNrIG91dCB3aXRoIHRoZSBzYW1lIG51bWJlciBvZiBkZWNpbWFscy5cbiAqIERlZmF1bHQgaXMgbm8gcm91bmRpbmcuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzOyBub3JtYWxseSBvbmx5IHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdFxuICogaW5zdGFudGlhdGVkIGluIGFwcHMuXG4gKiBCYXNlIGNsYXNzIGZvciBmZWF0dXJlIGZvcm1hdHMuXG4gKiB7QGxpbmsgbW9kdWxlOm9sL2Zvcm1hdC9GZWF0dXJlfkZlYXR1cmVGb3JtYXR9IHN1YmNsYXNzZXMgcHJvdmlkZSB0aGUgYWJpbGl0eSB0byBkZWNvZGUgYW5kIGVuY29kZVxuICoge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfkZlYXR1cmV9IG9iamVjdHMgZnJvbSBhIHZhcmlldHkgb2YgY29tbW9ubHkgdXNlZCBnZW9zcGF0aWFsXG4gKiBmaWxlIGZvcm1hdHMuICBTZWUgdGhlIGRvY3VtZW50YXRpb24gZm9yIGVhY2ggZm9ybWF0IGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQGFic3RyYWN0XG4gKiBAYXBpXG4gKi9cblxudmFyIEZlYXR1cmVGb3JtYXQgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGZWF0dXJlRm9ybWF0KCkge1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG4gICAgdGhpcy5kYXRhUHJvamVjdGlvbiA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIHRoaXMuZGVmYXVsdEZlYXR1cmVQcm9qZWN0aW9uID0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogQWRkcyB0aGUgZGF0YSBwcm9qZWN0aW9uIHRvIHRoZSByZWFkIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcGFyYW0ge1JlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICogQHJldHVybiB7UmVhZE9wdGlvbnN8dW5kZWZpbmVkfSBPcHRpb25zLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUuZ2V0UmVhZE9wdGlvbnMgPSBmdW5jdGlvbiAoc291cmNlLCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBvcHRpb25zO1xuXG4gICAgaWYgKG9wdF9vcHRpb25zKSB7XG4gICAgICB2YXIgZGF0YVByb2plY3Rpb24gPSBvcHRfb3B0aW9ucy5kYXRhUHJvamVjdGlvbiA/IGdldFByb2plY3Rpb24ob3B0X29wdGlvbnMuZGF0YVByb2plY3Rpb24pIDogdGhpcy5yZWFkUHJvamVjdGlvbihzb3VyY2UpO1xuXG4gICAgICBpZiAob3B0X29wdGlvbnMuZXh0ZW50ICYmIGRhdGFQcm9qZWN0aW9uICYmIGRhdGFQcm9qZWN0aW9uLmdldFVuaXRzKCkgPT09IFVuaXRzLlRJTEVfUElYRUxTKSB7XG4gICAgICAgIGRhdGFQcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbihkYXRhUHJvamVjdGlvbik7XG4gICAgICAgIGRhdGFQcm9qZWN0aW9uLnNldFdvcmxkRXh0ZW50KG9wdF9vcHRpb25zLmV4dGVudCk7XG4gICAgICB9XG5cbiAgICAgIG9wdGlvbnMgPSB7XG4gICAgICAgIGRhdGFQcm9qZWN0aW9uOiBkYXRhUHJvamVjdGlvbixcbiAgICAgICAgZmVhdHVyZVByb2plY3Rpb246IG9wdF9vcHRpb25zLmZlYXR1cmVQcm9qZWN0aW9uXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFkYXB0T3B0aW9ucyhvcHRpb25zKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldHMgdGhlIGBkYXRhUHJvamVjdGlvbmAgb24gdGhlIG9wdGlvbnMsIGlmIG5vIGBkYXRhUHJvamVjdGlvbmBcbiAgICogaXMgc2V0LlxuICAgKiBAcGFyYW0ge1dyaXRlT3B0aW9uc3xSZWFkT3B0aW9uc3x1bmRlZmluZWR9IG9wdGlvbnNcbiAgICogICAgIE9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7V3JpdGVPcHRpb25zfFJlYWRPcHRpb25zfHVuZGVmaW5lZH1cbiAgICogICAgIFVwZGF0ZWQgb3B0aW9ucy5cbiAgICovXG5cblxuICBGZWF0dXJlRm9ybWF0LnByb3RvdHlwZS5hZGFwdE9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHJldHVybiBhc3NpZ24oe1xuICAgICAgZGF0YVByb2plY3Rpb246IHRoaXMuZGF0YVByb2plY3Rpb24sXG4gICAgICBmZWF0dXJlUHJvamVjdGlvbjogdGhpcy5kZWZhdWx0RmVhdHVyZVByb2plY3Rpb25cbiAgICB9LCBvcHRpb25zKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0Zvcm1hdFR5cGUuanNcIikuZGVmYXVsdH0gRm9ybWF0LlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWFkIGEgc2luZ2xlIGZlYXR1cmUgZnJvbSBhIHNvdXJjZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcGFyYW0ge1JlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlfSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLnJlYWRGZWF0dXJlID0gZnVuY3Rpb24gKHNvdXJjZSwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgYWxsIGZlYXR1cmVzIGZyb20gYSBzb3VyY2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge0RvY3VtZW50fEVsZW1lbnR8QXJyYXlCdWZmZXJ8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHBhcmFtIHtSZWFkT3B0aW9ucz19IG9wdF9vcHRpb25zIFJlYWQgb3B0aW9ucy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZT59IEZlYXR1cmVzLlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLnJlYWRGZWF0dXJlcyA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWFkIGEgc2luZ2xlIGdlb21ldHJ5IGZyb20gYSBzb3VyY2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge0RvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHBhcmFtIHtSZWFkT3B0aW9ucz19IG9wdF9vcHRpb25zIFJlYWQgb3B0aW9ucy5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeS5cbiAgICovXG5cblxuICBGZWF0dXJlRm9ybWF0LnByb3RvdHlwZS5yZWFkR2VvbWV0cnkgPSBmdW5jdGlvbiAoc291cmNlLCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmVhZCB0aGUgcHJvamVjdGlvbiBmcm9tIGEgc291cmNlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtEb2N1bWVudHxFbGVtZW50fE9iamVjdHxzdHJpbmd9IHNvdXJjZSBTb3VyY2UuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBQcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLnJlYWRQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogRW5jb2RlIGEgZmVhdHVyZSBpbiB0aGlzIGZvcm1hdC5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7V3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBSZXN1bHQuXG4gICAqL1xuXG5cbiAgRmVhdHVyZUZvcm1hdC5wcm90b3R5cGUud3JpdGVGZWF0dXJlID0gZnVuY3Rpb24gKGZlYXR1cmUsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBFbmNvZGUgYW4gYXJyYXkgb2YgZmVhdHVyZXMgaW4gdGhpcyBmb3JtYXQuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59IGZlYXR1cmVzIEZlYXR1cmVzLlxuICAgKiBAcGFyYW0ge1dyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gUmVzdWx0LlxuICAgKi9cblxuXG4gIEZlYXR1cmVGb3JtYXQucHJvdG90eXBlLndyaXRlRmVhdHVyZXMgPSBmdW5jdGlvbiAoZmVhdHVyZXMsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBXcml0ZSBhIHNpbmdsZSBnZW9tZXRyeSBpbiB0aGlzIGZvcm1hdC5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtXcml0ZU9wdGlvbnM9fSBvcHRfb3B0aW9ucyBXcml0ZSBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFJlc3VsdC5cbiAgICovXG5cblxuICBGZWF0dXJlRm9ybWF0LnByb3RvdHlwZS53cml0ZUdlb21ldHJ5ID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuXG4gIHJldHVybiBGZWF0dXJlRm9ybWF0O1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBGZWF0dXJlRm9ybWF0O1xuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHdyaXRlIFNldCB0byB0cnVlIGZvciB3cml0aW5nLCBmYWxzZSBmb3IgcmVhZGluZy5cbiAqIEBwYXJhbSB7KFdyaXRlT3B0aW9uc3xSZWFkT3B0aW9ucyk9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBUcmFuc2Zvcm1lZCBnZW9tZXRyeS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtR2VvbWV0cnlXaXRoT3B0aW9ucyhnZW9tZXRyeSwgd3JpdGUsIG9wdF9vcHRpb25zKSB7XG4gIHZhciBmZWF0dXJlUHJvamVjdGlvbiA9IG9wdF9vcHRpb25zID8gZ2V0UHJvamVjdGlvbihvcHRfb3B0aW9ucy5mZWF0dXJlUHJvamVjdGlvbikgOiBudWxsO1xuICB2YXIgZGF0YVByb2plY3Rpb24gPSBvcHRfb3B0aW9ucyA/IGdldFByb2plY3Rpb24ob3B0X29wdGlvbnMuZGF0YVByb2plY3Rpb24pIDogbnVsbDtcbiAgdmFyIHRyYW5zZm9ybWVkO1xuXG4gIGlmIChmZWF0dXJlUHJvamVjdGlvbiAmJiBkYXRhUHJvamVjdGlvbiAmJiAhZXF1aXZhbGVudFByb2plY3Rpb24oZmVhdHVyZVByb2plY3Rpb24sIGRhdGFQcm9qZWN0aW9uKSkge1xuICAgIHRyYW5zZm9ybWVkID0gKHdyaXRlID8gZ2VvbWV0cnkuY2xvbmUoKSA6IGdlb21ldHJ5KS50cmFuc2Zvcm0od3JpdGUgPyBmZWF0dXJlUHJvamVjdGlvbiA6IGRhdGFQcm9qZWN0aW9uLCB3cml0ZSA/IGRhdGFQcm9qZWN0aW9uIDogZmVhdHVyZVByb2plY3Rpb24pO1xuICB9IGVsc2Uge1xuICAgIHRyYW5zZm9ybWVkID0gZ2VvbWV0cnk7XG4gIH1cblxuICBpZiAod3JpdGUgJiYgb3B0X29wdGlvbnMgJiZcbiAgLyoqIEB0eXBlIHtXcml0ZU9wdGlvbnN9ICovXG4gIG9wdF9vcHRpb25zLmRlY2ltYWxzICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgcG93ZXJfMSA9IE1hdGgucG93KDEwLFxuICAgIC8qKiBAdHlwZSB7V3JpdGVPcHRpb25zfSAqL1xuICAgIG9wdF9vcHRpb25zLmRlY2ltYWxzKTsgLy8gaWYgZGVjaW1hbHMgb3B0aW9uIG9uIHdyaXRlLCByb3VuZCBlYWNoIGNvb3JkaW5hdGUgYXBwcm9wcmlhdGVseVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBUcmFuc2Zvcm1lZCBjb29yZGluYXRlcy5cbiAgICAgKi9cblxuICAgIHZhciB0cmFuc2Zvcm0gPSBmdW5jdGlvbiB0cmFuc2Zvcm0oY29vcmRpbmF0ZXMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgY29vcmRpbmF0ZXNbaV0gPSBNYXRoLnJvdW5kKGNvb3JkaW5hdGVzW2ldICogcG93ZXJfMSkgLyBwb3dlcl8xO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29vcmRpbmF0ZXM7XG4gICAgfTtcblxuICAgIGlmICh0cmFuc2Zvcm1lZCA9PT0gZ2VvbWV0cnkpIHtcbiAgICAgIHRyYW5zZm9ybWVkID0gZ2VvbWV0cnkuY2xvbmUoKTtcbiAgICB9XG5cbiAgICB0cmFuc2Zvcm1lZC5hcHBseVRyYW5zZm9ybSh0cmFuc2Zvcm0pO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybWVkO1xufVxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge1JlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVHJhbnNmb3JtZWQgZXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1FeHRlbnRXaXRoT3B0aW9ucyhleHRlbnQsIG9wdF9vcHRpb25zKSB7XG4gIHZhciBmZWF0dXJlUHJvamVjdGlvbiA9IG9wdF9vcHRpb25zID8gZ2V0UHJvamVjdGlvbihvcHRfb3B0aW9ucy5mZWF0dXJlUHJvamVjdGlvbikgOiBudWxsO1xuICB2YXIgZGF0YVByb2plY3Rpb24gPSBvcHRfb3B0aW9ucyA/IGdldFByb2plY3Rpb24ob3B0X29wdGlvbnMuZGF0YVByb2plY3Rpb24pIDogbnVsbDtcblxuICBpZiAoZmVhdHVyZVByb2plY3Rpb24gJiYgZGF0YVByb2plY3Rpb24gJiYgIWVxdWl2YWxlbnRQcm9qZWN0aW9uKGZlYXR1cmVQcm9qZWN0aW9uLCBkYXRhUHJvamVjdGlvbikpIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgZGF0YVByb2plY3Rpb24sIGZlYXR1cmVQcm9qZWN0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXh0ZW50O1xuICB9XG59IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9mb3JtYXQvSlNPTkZlYXR1cmVcbiAqL1xuXG5cbmltcG9ydCBGZWF0dXJlRm9ybWF0IGZyb20gJy4vRmVhdHVyZS5qcyc7XG5pbXBvcnQgRm9ybWF0VHlwZSBmcm9tICcuL0Zvcm1hdFR5cGUuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuLi91dGlsLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQWJzdHJhY3QgYmFzZSBjbGFzczsgbm9ybWFsbHkgb25seSB1c2VkIGZvciBjcmVhdGluZyBzdWJjbGFzc2VzIGFuZCBub3RcbiAqIGluc3RhbnRpYXRlZCBpbiBhcHBzLlxuICogQmFzZSBjbGFzcyBmb3IgSlNPTiBmZWF0dXJlIGZvcm1hdHMuXG4gKlxuICogQGFic3RyYWN0XG4gKi9cblxudmFyIEpTT05GZWF0dXJlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEpTT05GZWF0dXJlLCBfc3VwZXIpO1xuXG4gIGZ1bmN0aW9uIEpTT05GZWF0dXJlKCkge1xuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0Zvcm1hdFR5cGUuanNcIikuZGVmYXVsdH0gRm9ybWF0LlxuICAgKi9cblxuXG4gIEpTT05GZWF0dXJlLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBGb3JtYXRUeXBlLkpTT047XG4gIH07XG4gIC8qKlxuICAgKiBSZWFkIGEgZmVhdHVyZS4gIE9ubHkgd29ya3MgZm9yIGEgc2luZ2xlIGZlYXR1cmUuIFVzZSBgcmVhZEZlYXR1cmVzYCB0b1xuICAgKiByZWFkIGEgZmVhdHVyZSBjb2xsZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfERvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gRmVhdHVyZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEpTT05GZWF0dXJlLnByb3RvdHlwZS5yZWFkRmVhdHVyZSA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZEZlYXR1cmVGcm9tT2JqZWN0KGdldE9iamVjdChzb3VyY2UpLCB0aGlzLmdldFJlYWRPcHRpb25zKHNvdXJjZSwgb3B0X29wdGlvbnMpKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlYWQgYWxsIGZlYXR1cmVzLiAgV29ya3Mgd2l0aCBib3RoIGEgc2luZ2xlIGZlYXR1cmUgYW5kIGEgZmVhdHVyZVxuICAgKiBjb2xsZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfERvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdD59IEZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSlNPTkZlYXR1cmUucHJvdG90eXBlLnJlYWRGZWF0dXJlcyA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZEZlYXR1cmVzRnJvbU9iamVjdChnZXRPYmplY3Qoc291cmNlKSwgdGhpcy5nZXRSZWFkT3B0aW9ucyhzb3VyY2UsIG9wdF9vcHRpb25zKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBPYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLlJlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gRmVhdHVyZS5cbiAgICovXG5cblxuICBKU09ORmVhdHVyZS5wcm90b3R5cGUucmVhZEZlYXR1cmVGcm9tT2JqZWN0ID0gZnVuY3Rpb24gKG9iamVjdCwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IE9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gRmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgSlNPTkZlYXR1cmUucHJvdG90eXBlLnJlYWRGZWF0dXJlc0Zyb21PYmplY3QgPSBmdW5jdGlvbiAob2JqZWN0LCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogUmVhZCBhIGdlb21ldHJ5LlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfERvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBKU09ORmVhdHVyZS5wcm90b3R5cGUucmVhZEdlb21ldHJ5ID0gZnVuY3Rpb24gKHNvdXJjZSwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5yZWFkR2VvbWV0cnlGcm9tT2JqZWN0KGdldE9iamVjdChzb3VyY2UpLCB0aGlzLmdldFJlYWRPcHRpb25zKHNvdXJjZSwgb3B0X29wdGlvbnMpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IE9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeS5cbiAgICovXG5cblxuICBKU09ORmVhdHVyZS5wcm90b3R5cGUucmVhZEdlb21ldHJ5RnJvbU9iamVjdCA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZWFkIHRoZSBwcm9qZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfERvY3VtZW50fEVsZW1lbnR8T2JqZWN0fHN0cmluZ30gc291cmNlIFNvdXJjZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IFByb2plY3Rpb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBKU09ORmVhdHVyZS5wcm90b3R5cGUucmVhZFByb2plY3Rpb24gPSBmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZFByb2plY3Rpb25Gcm9tT2JqZWN0KGdldE9iamVjdChzb3VyY2UpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IE9iamVjdC5cbiAgICogQHByb3RlY3RlZFxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gUHJvamVjdGlvbi5cbiAgICovXG5cblxuICBKU09ORmVhdHVyZS5wcm90b3R5cGUucmVhZFByb2plY3Rpb25Gcm9tT2JqZWN0ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogRW5jb2RlIGEgZmVhdHVyZSBhcyBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gRW5jb2RlZCBmZWF0dXJlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSlNPTkZlYXR1cmUucHJvdG90eXBlLndyaXRlRmVhdHVyZSA9IGZ1bmN0aW9uIChmZWF0dXJlLCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLndyaXRlRmVhdHVyZU9iamVjdChmZWF0dXJlLCBvcHRfb3B0aW9ucykpO1xuICB9O1xuICAvKipcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmZWF0dXJlIEZlYXR1cmUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge09iamVjdH0gT2JqZWN0LlxuICAgKi9cblxuXG4gIEpTT05GZWF0dXJlLnByb3RvdHlwZS53cml0ZUZlYXR1cmVPYmplY3QgPSBmdW5jdGlvbiAoZmVhdHVyZSwgb3B0X29wdGlvbnMpIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEVuY29kZSBhbiBhcnJheSBvZiBmZWF0dXJlcyBhcyBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gZmVhdHVyZXMgRmVhdHVyZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gRW5jb2RlZCBmZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEpTT05GZWF0dXJlLnByb3RvdHlwZS53cml0ZUZlYXR1cmVzID0gZnVuY3Rpb24gKGZlYXR1cmVzLCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLndyaXRlRmVhdHVyZXNPYmplY3QoZmVhdHVyZXMsIG9wdF9vcHRpb25zKSk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSBmZWF0dXJlcyBGZWF0dXJlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7T2JqZWN0fSBPYmplY3QuXG4gICAqL1xuXG5cbiAgSlNPTkZlYXR1cmUucHJvdG90eXBlLndyaXRlRmVhdHVyZXNPYmplY3QgPSBmdW5jdGlvbiAoZmVhdHVyZXMsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIGFic3RyYWN0KCk7XG4gIH07XG4gIC8qKlxuICAgKiBFbmNvZGUgYSBnZW9tZXRyeSBhcyBzdHJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBFbmNvZGVkIGdlb21ldHJ5LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgSlNPTkZlYXR1cmUucHJvdG90eXBlLndyaXRlR2VvbWV0cnkgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMud3JpdGVHZW9tZXRyeU9iamVjdChnZW9tZXRyeSwgb3B0X29wdGlvbnMpKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge09iamVjdH0gT2JqZWN0LlxuICAgKi9cblxuXG4gIEpTT05GZWF0dXJlLnByb3RvdHlwZS53cml0ZUdlb21ldHJ5T2JqZWN0ID0gZnVuY3Rpb24gKGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICAgIHJldHVybiBhYnN0cmFjdCgpO1xuICB9O1xuXG4gIHJldHVybiBKU09ORmVhdHVyZTtcbn0oRmVhdHVyZUZvcm1hdCk7XG4vKipcbiAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICogQHJldHVybiB7T2JqZWN0fSBPYmplY3QuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRPYmplY3Qoc291cmNlKSB7XG4gIGlmICh0eXBlb2Ygc291cmNlID09PSAnc3RyaW5nJykge1xuICAgIHZhciBvYmplY3QgPSBKU09OLnBhcnNlKHNvdXJjZSk7XG4gICAgcmV0dXJuIG9iamVjdCA/XG4gICAgLyoqIEB0eXBlIHtPYmplY3R9ICovXG4gICAgb2JqZWN0IDogbnVsbDtcbiAgfSBlbHNlIGlmIChzb3VyY2UgIT09IG51bGwpIHtcbiAgICByZXR1cm4gc291cmNlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEpTT05GZWF0dXJlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9MaW5lU3RyaW5nXG4gKi9cblxuXG5pbXBvcnQgR2VvbWV0cnlMYXlvdXQgZnJvbSAnLi9HZW9tZXRyeUxheW91dC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFzc2lnbkNsb3Nlc3RQb2ludCwgbWF4U3F1YXJlZERlbHRhIH0gZnJvbSAnLi9mbGF0L2Nsb3Nlc3QuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGRvdWdsYXNQZXVja2VyIH0gZnJvbSAnLi9mbGF0L3NpbXBsaWZ5LmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGZvckVhY2ggYXMgZm9yRWFjaFNlZ21lbnQgfSBmcm9tICcuL2ZsYXQvc2VnbWVudHMuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzIH0gZnJvbSAnLi9mbGF0L2luZmxhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJwb2xhdGVQb2ludCwgbGluZVN0cmluZ0Nvb3JkaW5hdGVBdE0gfSBmcm9tICcuL2ZsYXQvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0c0xpbmVTdHJpbmcgfSBmcm9tICcuL2ZsYXQvaW50ZXJzZWN0c2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaW5lU3RyaW5nTGVuZ3RoIH0gZnJvbSAnLi9mbGF0L2xlbmd0aC5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIExpbmVzdHJpbmcgZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBMaW5lU3RyaW5nID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKExpbmVTdHJpbmcsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqICAgICBGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIExpbmVTdHJpbmcoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuZmxhdE1pZHBvaW50XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmxhdE1pZHBvaW50UmV2aXNpb25fID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFfID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSAtMTtcblxuICAgIGlmIChvcHRfbGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBjb29yZGluYXRlIHRvIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbGluZXN0cmluZy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmFwcGVuZENvb3JkaW5hdGUgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZSkge1xuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gY29vcmRpbmF0ZS5zbGljZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHRlbmQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIGNvb3JkaW5hdGUpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTGluZVN0cmluZ30gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGluZVN0cmluZyA9IG5ldyBMaW5lU3RyaW5nKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgICBsaW5lU3RyaW5nLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbGluZVN0cmluZztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tYXhEZWx0YVJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHRoaXMubWF4RGVsdGFfID0gTWF0aC5zcXJ0KG1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgMCkpO1xuICAgICAgdGhpcy5tYXhEZWx0YVJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXNzaWduQ2xvc2VzdFBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlLCB0aGlzLm1heERlbHRhXywgZmFsc2UsIHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEl0ZXJhdGUgb3ZlciBlYWNoIHNlZ21lbnQsIGNhbGxpbmcgdGhlIHByb3ZpZGVkIGNhbGxiYWNrLlxuICAgKiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyBhIHRydXRoeSB2YWx1ZSB0aGUgZnVuY3Rpb24gcmV0dXJucyB0aGF0XG4gICAqIHZhbHVlIGltbWVkaWF0ZWx5LiBPdGhlcndpc2UgdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbih0aGlzOiBTLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IFR9IGNhbGxiYWNrIEZ1bmN0aW9uXG4gICAqICAgICBjYWxsZWQgZm9yIGVhY2ggc2VnbWVudC4gVGhlIGZ1bmN0aW9uIHdpbGwgcmVjZWl2ZSB0d28gYXJndW1lbnRzLCB0aGUgc3RhcnQgYW5kIGVuZCBjb29yZGluYXRlcyBvZiB0aGUgc2VnbWVudC5cbiAgICogQHJldHVybiB7VHxib29sZWFufSBWYWx1ZS5cbiAgICogQHRlbXBsYXRlIFQsU1xuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZVN0cmluZy5wcm90b3R5cGUuZm9yRWFjaFNlZ21lbnQgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZm9yRWFjaFNlZ21lbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIGNhbGxiYWNrKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGNvb3JkaW5hdGUgYXQgYG1gIHVzaW5nIGxpbmVhciBpbnRlcnBvbGF0aW9uLCBvciBgbnVsbGAgaWYgbm9cbiAgICogc3VjaCBjb29yZGluYXRlIGV4aXN0cy5cbiAgICpcbiAgICogYG9wdF9leHRyYXBvbGF0ZWAgY29udHJvbHMgZXh0cmFwb2xhdGlvbiBiZXlvbmQgdGhlIHJhbmdlIG9mIE1zIGluIHRoZVxuICAgKiBNdWx0aUxpbmVTdHJpbmcuIElmIGBvcHRfZXh0cmFwb2xhdGVgIGlzIGB0cnVlYCB0aGVuIE1zIGxlc3MgdGhhbiB0aGUgZmlyc3RcbiAgICogTSB3aWxsIHJldHVybiB0aGUgZmlyc3QgY29vcmRpbmF0ZSBhbmQgTXMgZ3JlYXRlciB0aGFuIHRoZSBsYXN0IE0gd2lsbFxuICAgKiByZXR1cm4gdGhlIGxhc3QgY29vcmRpbmF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IG0gTS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2V4dHJhcG9sYXRlIEV4dHJhcG9sYXRlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldENvb3JkaW5hdGVBdE0gPSBmdW5jdGlvbiAobSwgb3B0X2V4dHJhcG9sYXRlKSB7XG4gICAgaWYgKHRoaXMubGF5b3V0ICE9IEdlb21ldHJ5TGF5b3V0LlhZTSAmJiB0aGlzLmxheW91dCAhPSBHZW9tZXRyeUxheW91dC5YWVpNKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgZXh0cmFwb2xhdGUgPSBvcHRfZXh0cmFwb2xhdGUgIT09IHVuZGVmaW5lZCA/IG9wdF9leHRyYXBvbGF0ZSA6IGZhbHNlO1xuICAgIHJldHVybiBsaW5lU3RyaW5nQ29vcmRpbmF0ZUF0TSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgbSwgZXh0cmFwb2xhdGUpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBjb29yZGluYXRlcyBvZiB0aGUgbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gQ29vcmRpbmF0ZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaW5mbGF0ZUNvb3JkaW5hdGVzKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgsIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZSBhdCB0aGUgcHJvdmlkZWQgZnJhY3Rpb24gYWxvbmcgdGhlIGxpbmVzdHJpbmcuXG4gICAqIFRoZSBgZnJhY3Rpb25gIGlzIGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMSwgd2hlcmUgMCBpcyB0aGUgc3RhcnQgb2YgdGhlXG4gICAqIGxpbmVzdHJpbmcgYW5kIDEgaXMgdGhlIGVuZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGZyYWN0aW9uIEZyYWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT19IG9wdF9kZXN0IE9wdGlvbmFsIGNvb3JkaW5hdGUgd2hvc2UgdmFsdWVzIHdpbGxcbiAgICogICAgIGJlIG1vZGlmaWVkLiBJZiBub3QgcHJvdmlkZWQsIGEgbmV3IGNvb3JkaW5hdGUgd2lsbCBiZSByZXR1cm5lZC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlIG9mIHRoZSBpbnRlcnBvbGF0ZWQgcG9pbnQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlQXQgPSBmdW5jdGlvbiAoZnJhY3Rpb24sIG9wdF9kZXN0KSB7XG4gICAgcmV0dXJuIGludGVycG9sYXRlUG9pbnQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIGZyYWN0aW9uLCBvcHRfZGVzdCwgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGxpbmVzdHJpbmcgb24gcHJvamVjdGVkIHBsYW5lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IExlbmd0aCAob24gcHJvamVjdGVkIHBsYW5lKS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldExlbmd0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gbGluZVN0cmluZ0xlbmd0aCh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IG1pZHBvaW50LlxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5mbGF0TWlkcG9pbnRSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLmZsYXRNaWRwb2ludF8gPSB0aGlzLmdldENvb3JkaW5hdGVBdCgwLjUsIHRoaXMuZmxhdE1pZHBvaW50Xyk7XG4gICAgICB0aGlzLmZsYXRNaWRwb2ludFJldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mbGF0TWlkcG9pbnRfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge0xpbmVTdHJpbmd9IFNpbXBsaWZpZWQgTGluZVN0cmluZy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICB2YXIgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gZG91Z2xhc1BldWNrZXIodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCwgdGhpcy5zdHJpZGUsIHNxdWFyZWRUb2xlcmFuY2UsIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIDApO1xuICAgIHJldHVybiBuZXcgTGluZVN0cmluZyhzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExpbmVTdHJpbmcucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORztcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBMaW5lU3RyaW5nLnByb3RvdHlwZS5pbnRlcnNlY3RzRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHJldHVybiBpbnRlcnNlY3RzTGluZVN0cmluZyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIGxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7IUFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTGluZVN0cmluZy5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMSk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRlZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gTGluZVN0cmluZztcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBMaW5lU3RyaW5nOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9NdWx0aUxpbmVTdHJpbmdcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IExpbmVTdHJpbmcgZnJvbSAnLi9MaW5lU3RyaW5nLmpzJztcbmltcG9ydCBTaW1wbGVHZW9tZXRyeSBmcm9tICcuL1NpbXBsZUdlb21ldHJ5LmpzJztcbmltcG9ydCB7IGFycmF5TWF4U3F1YXJlZERlbHRhLCBhc3NpZ25DbG9zZXN0QXJyYXlQb2ludCB9IGZyb20gJy4vZmxhdC9jbG9zZXN0LmpzJztcbmltcG9ydCB7IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSB9IGZyb20gJy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheSB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGRvdWdsYXNQZXVja2VyQXJyYXkgfSBmcm9tICcuL2ZsYXQvc2ltcGxpZnkuanMnO1xuaW1wb3J0IHsgZXh0ZW5kIH0gZnJvbSAnLi4vYXJyYXkuanMnO1xuaW1wb3J0IHsgaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW5mbGF0ZS5qcyc7XG5pbXBvcnQgeyBpbnRlcnBvbGF0ZVBvaW50LCBsaW5lU3RyaW5nc0Nvb3JkaW5hdGVBdE0gfSBmcm9tICcuL2ZsYXQvaW50ZXJwb2xhdGUuanMnO1xuaW1wb3J0IHsgaW50ZXJzZWN0c0xpbmVTdHJpbmdBcnJheSB9IGZyb20gJy4vZmxhdC9pbnRlcnNlY3RzZXh0ZW50LmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTXVsdGktbGluZXN0cmluZyBnZW9tZXRyeS5cbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIE11bHRpTGluZVN0cmluZyA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNdWx0aUxpbmVTdHJpbmcsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58TGluZVN0cmluZz58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXNcbiAgICogICAgIENvb3JkaW5hdGVzIG9yIExpbmVTdHJpbmcgZ2VvbWV0cmllcy4gKEZvciBpbnRlcm5hbCB1c2UsIGZsYXQgY29vcmRpbmF0ZXMgaW5cbiAgICogICAgIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFuZCBgb3B0X2VuZHNgIGFyZSBhbHNvIGFjY2VwdGVkLilcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X2VuZHMgRmxhdCBjb29yZGluYXRlIGVuZHMgZm9yIGludGVybmFsIHVzZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBNdWx0aUxpbmVTdHJpbmcoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQsIG9wdF9lbmRzKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5lbmRzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heERlbHRhXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLm1heERlbHRhUmV2aXNpb25fID0gLTE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjb29yZGluYXRlc1swXSkpIHtcbiAgICAgIF90aGlzLnNldENvb3JkaW5hdGVzKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0KTtcbiAgICB9IGVsc2UgaWYgKG9wdF9sYXlvdXQgIT09IHVuZGVmaW5lZCAmJiBvcHRfZW5kcykge1xuICAgICAgX3RoaXMuc2V0RmxhdENvb3JkaW5hdGVzKG9wdF9sYXlvdXQsXG4gICAgICAvKiogQHR5cGUge0FycmF5PG51bWJlcj59ICovXG4gICAgICBjb29yZGluYXRlcyk7XG5cbiAgICAgIF90aGlzLmVuZHNfID0gb3B0X2VuZHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBsYXlvdXQgPSBfdGhpcy5nZXRMYXlvdXQoKTtcblxuICAgICAgdmFyIGxpbmVTdHJpbmdzID1cbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8TGluZVN0cmluZz59ICovXG4gICAgICBjb29yZGluYXRlcztcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSBbXTtcbiAgICAgIHZhciBlbmRzID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGxpbmVTdHJpbmdzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIGxpbmVTdHJpbmcgPSBsaW5lU3RyaW5nc1tpXTtcblxuICAgICAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgICAgIGxheW91dCA9IGxpbmVTdHJpbmcuZ2V0TGF5b3V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICBleHRlbmQoZmxhdENvb3JkaW5hdGVzLCBsaW5lU3RyaW5nLmdldEZsYXRDb29yZGluYXRlcygpKTtcbiAgICAgICAgZW5kcy5wdXNoKGZsYXRDb29yZGluYXRlcy5sZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMobGF5b3V0LCBmbGF0Q29vcmRpbmF0ZXMpO1xuXG4gICAgICBfdGhpcy5lbmRzXyA9IGVuZHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBsaW5lc3RyaW5nIHRvIHRoZSBtdWx0aWxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7TGluZVN0cmluZ30gbGluZVN0cmluZyBMaW5lU3RyaW5nLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5hcHBlbmRMaW5lU3RyaW5nID0gZnVuY3Rpb24gKGxpbmVTdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IGxpbmVTdHJpbmcuZ2V0RmxhdENvb3JkaW5hdGVzKCkuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXh0ZW5kKHRoaXMuZmxhdENvb3JkaW5hdGVzLCBsaW5lU3RyaW5nLmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCkpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kc18ucHVzaCh0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGgpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTXVsdGlMaW5lU3RyaW5nfSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG11bHRpTGluZVN0cmluZyA9IG5ldyBNdWx0aUxpbmVTdHJpbmcodGhpcy5mbGF0Q29vcmRpbmF0ZXMuc2xpY2UoKSwgdGhpcy5sYXlvdXQsIHRoaXMuZW5kc18uc2xpY2UoKSk7XG4gICAgbXVsdGlMaW5lU3RyaW5nLmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbXVsdGlMaW5lU3RyaW5nO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNsb3Nlc3RQb2ludCBDbG9zZXN0IHBvaW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWluU3F1YXJlZERpc3RhbmNlIE1pbmltdW0gc3F1YXJlZCBkaXN0YW5jZS5cbiAgICogQHJldHVybiB7bnVtYmVyfSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5jbG9zZXN0UG9pbnRYWSA9IGZ1bmN0aW9uICh4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSkge1xuICAgIGlmIChtaW5TcXVhcmVkRGlzdGFuY2UgPCBjbG9zZXN0U3F1YXJlZERpc3RhbmNlWFkodGhpcy5nZXRFeHRlbnQoKSwgeCwgeSkpIHtcbiAgICAgIHJldHVybiBtaW5TcXVhcmVkRGlzdGFuY2U7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gIT0gdGhpcy5nZXRSZXZpc2lvbigpKSB7XG4gICAgICB0aGlzLm1heERlbHRhXyA9IE1hdGguc3FydChhcnJheU1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIDApKTtcbiAgICAgIHRoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzc2lnbkNsb3Nlc3RBcnJheVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgdGhpcy5tYXhEZWx0YV8sIGZhbHNlLCB4LCB5LCBjbG9zZXN0UG9pbnQsIG1pblNxdWFyZWREaXN0YW5jZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb29yZGluYXRlIGF0IGBtYCB1c2luZyBsaW5lYXIgaW50ZXJwb2xhdGlvbiwgb3IgYG51bGxgIGlmIG5vXG4gICAqIHN1Y2ggY29vcmRpbmF0ZSBleGlzdHMuXG4gICAqXG4gICAqIGBvcHRfZXh0cmFwb2xhdGVgIGNvbnRyb2xzIGV4dHJhcG9sYXRpb24gYmV5b25kIHRoZSByYW5nZSBvZiBNcyBpbiB0aGVcbiAgICogTXVsdGlMaW5lU3RyaW5nLiBJZiBgb3B0X2V4dHJhcG9sYXRlYCBpcyBgdHJ1ZWAgdGhlbiBNcyBsZXNzIHRoYW4gdGhlIGZpcnN0XG4gICAqIE0gd2lsbCByZXR1cm4gdGhlIGZpcnN0IGNvb3JkaW5hdGUgYW5kIE1zIGdyZWF0ZXIgdGhhbiB0aGUgbGFzdCBNIHdpbGxcbiAgICogcmV0dXJuIHRoZSBsYXN0IGNvb3JkaW5hdGUuXG4gICAqXG4gICAqIGBvcHRfaW50ZXJwb2xhdGVgIGNvbnRyb2xzIGludGVycG9sYXRpb24gYmV0d2VlbiBjb25zZWN1dGl2ZSBMaW5lU3RyaW5nc1xuICAgKiB3aXRoaW4gdGhlIE11bHRpTGluZVN0cmluZy4gSWYgYG9wdF9pbnRlcnBvbGF0ZWAgaXMgYHRydWVgIHRoZSBjb29yZGluYXRlc1xuICAgKiB3aWxsIGJlIGxpbmVhcmx5IGludGVycG9sYXRlZCBiZXR3ZWVuIHRoZSBsYXN0IGNvb3JkaW5hdGUgb2Ygb25lIExpbmVTdHJpbmdcbiAgICogYW5kIHRoZSBmaXJzdCBjb29yZGluYXRlIG9mIHRoZSBuZXh0IExpbmVTdHJpbmcuICBJZiBgb3B0X2ludGVycG9sYXRlYCBpc1xuICAgKiBgZmFsc2VgIHRoZW4gdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGBudWxsYCBmb3IgTXMgZmFsbGluZyBiZXR3ZWVuXG4gICAqIExpbmVTdHJpbmdzLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbSBNLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW49fSBvcHRfZXh0cmFwb2xhdGUgRXh0cmFwb2xhdGUuIERlZmF1bHQgaXMgYGZhbHNlYC5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X2ludGVycG9sYXRlIEludGVycG9sYXRlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQ29vcmRpbmF0ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZUF0TSA9IGZ1bmN0aW9uIChtLCBvcHRfZXh0cmFwb2xhdGUsIG9wdF9pbnRlcnBvbGF0ZSkge1xuICAgIGlmICh0aGlzLmxheW91dCAhPSBHZW9tZXRyeUxheW91dC5YWU0gJiYgdGhpcy5sYXlvdXQgIT0gR2VvbWV0cnlMYXlvdXQuWFlaTSB8fCB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBleHRyYXBvbGF0ZSA9IG9wdF9leHRyYXBvbGF0ZSAhPT0gdW5kZWZpbmVkID8gb3B0X2V4dHJhcG9sYXRlIDogZmFsc2U7XG4gICAgdmFyIGludGVycG9sYXRlID0gb3B0X2ludGVycG9sYXRlICE9PSB1bmRlZmluZWQgPyBvcHRfaW50ZXJwb2xhdGUgOiBmYWxzZTtcbiAgICByZXR1cm4gbGluZVN0cmluZ3NDb29yZGluYXRlQXRNKHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgbSwgZXh0cmFwb2xhdGUsIGludGVycG9sYXRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaW5mbGF0ZUNvb3JkaW5hdGVzQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIHRoaXMuZW5kc18sIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEVuZHMuXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRFbmRzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsaW5lc3RyaW5nIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7TGluZVN0cmluZ30gTGluZVN0cmluZy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0TGluZVN0cmluZyA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgIGlmIChpbmRleCA8IDAgfHwgdGhpcy5lbmRzXy5sZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgTGluZVN0cmluZyh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZShpbmRleCA9PT0gMCA/IDAgOiB0aGlzLmVuZHNfW2luZGV4IC0gMV0sIHRoaXMuZW5kc19baW5kZXhdKSwgdGhpcy5sYXlvdXQpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBsaW5lc3RyaW5ncyBvZiB0aGlzIG11bHRpbGluZXN0cmluZy5cbiAgICogQHJldHVybiB7QXJyYXk8TGluZVN0cmluZz59IExpbmVTdHJpbmdzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5nZXRMaW5lU3RyaW5ncyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGVuZHMgPSB0aGlzLmVuZHNfO1xuICAgIHZhciBsYXlvdXQgPSB0aGlzLmxheW91dDtcbiAgICAvKiogQHR5cGUge0FycmF5PExpbmVTdHJpbmc+fSAqL1xuXG4gICAgdmFyIGxpbmVTdHJpbmdzID0gW107XG4gICAgdmFyIG9mZnNldCA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIHZhciBlbmQgPSBlbmRzW2ldO1xuICAgICAgdmFyIGxpbmVTdHJpbmcgPSBuZXcgTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMuc2xpY2Uob2Zmc2V0LCBlbmQpLCBsYXlvdXQpO1xuICAgICAgbGluZVN0cmluZ3MucHVzaChsaW5lU3RyaW5nKTtcbiAgICAgIG9mZnNldCA9IGVuZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZVN0cmluZ3M7XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBGbGF0IG1pZHBvaW50cy5cbiAgICovXG5cblxuICBNdWx0aUxpbmVTdHJpbmcucHJvdG90eXBlLmdldEZsYXRNaWRwb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1pZHBvaW50cyA9IFtdO1xuICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmZsYXRDb29yZGluYXRlcztcbiAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICB2YXIgZW5kcyA9IHRoaXMuZW5kc187XG4gICAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZW5kID0gZW5kc1tpXTtcbiAgICAgIHZhciBtaWRwb2ludCA9IGludGVycG9sYXRlUG9pbnQoZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlLCAwLjUpO1xuICAgICAgZXh0ZW5kKG1pZHBvaW50cywgbWlkcG9pbnQpO1xuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIHJldHVybiBtaWRwb2ludHM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHJldHVybiB7TXVsdGlMaW5lU3RyaW5nfSBTaW1wbGlmaWVkIE11bHRpTGluZVN0cmluZy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0U2ltcGxpZmllZEdlb21ldHJ5SW50ZXJuYWwgPSBmdW5jdGlvbiAoc3F1YXJlZFRvbGVyYW5jZSkge1xuICAgIHZhciBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgdmFyIHNpbXBsaWZpZWRFbmRzID0gW107XG4gICAgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBkb3VnbGFzUGV1Y2tlckFycmF5KHRoaXMuZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNfLCB0aGlzLnN0cmlkZSwgc3F1YXJlZFRvbGVyYW5jZSwgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgMCwgc2ltcGxpZmllZEVuZHMpO1xuICAgIHJldHVybiBuZXcgTXVsdGlMaW5lU3RyaW5nKHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBzaW1wbGlmaWVkRW5kcyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHR5cGUgb2YgdGhpcyBnZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkgdHlwZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpTGluZVN0cmluZy5wcm90b3R5cGUuaW50ZXJzZWN0c0V4dGVudCA9IGZ1bmN0aW9uIChleHRlbnQpIHtcbiAgICByZXR1cm4gaW50ZXJzZWN0c0xpbmVTdHJpbmdBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzXywgdGhpcy5zdHJpZGUsIGV4dGVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBtdWx0aWxpbmVzdHJpbmcuXG4gICAqIEBwYXJhbSB7IUFycmF5PEFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT4+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtHZW9tZXRyeUxheW91dD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlMaW5lU3RyaW5nLnByb3RvdHlwZS5zZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgb3B0X2xheW91dCkge1xuICAgIHRoaXMuc2V0TGF5b3V0KG9wdF9sYXlvdXQsIGNvb3JkaW5hdGVzLCAyKTtcblxuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgfVxuXG4gICAgdmFyIGVuZHMgPSBkZWZsYXRlQ29vcmRpbmF0ZXNBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlLCB0aGlzLmVuZHNfKTtcbiAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBlbmRzLmxlbmd0aCA9PT0gMCA/IDAgOiBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG5cbiAgcmV0dXJuIE11bHRpTGluZVN0cmluZztcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBNdWx0aUxpbmVTdHJpbmc7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9nZW9tL011bHRpUG9pbnRcbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IFBvaW50IGZyb20gJy4vUG9pbnQuanMnO1xuaW1wb3J0IFNpbXBsZUdlb21ldHJ5IGZyb20gJy4vU2ltcGxlR2VvbWV0cnkuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZLCBjb250YWluc1hZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9kZWZsYXRlLmpzJztcbmltcG9ydCB7IGV4dGVuZCB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGluZmxhdGVDb29yZGluYXRlcyB9IGZyb20gJy4vZmxhdC9pbmZsYXRlLmpzJztcbmltcG9ydCB7IHNxdWFyZWREaXN0YW5jZSBhcyBzcXVhcmVkRHggfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogQGNsYXNzZGVzY1xuICogTXVsdGktcG9pbnQgZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBNdWx0aVBvaW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKE11bHRpUG9pbnQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT58QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZXMgQ29vcmRpbmF0ZXMuXG4gICAqICAgICBGb3IgaW50ZXJuYWwgdXNlLCBmbGF0IGNvb3JkaW5hdGVzIGluIGNvbWJpbmF0aW9uIHdpdGggYG9wdF9sYXlvdXRgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE11bHRpUG9pbnQoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuXG4gICAgaWYgKG9wdF9sYXlvdXQgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3RoaXMuc2V0Q29vcmRpbmF0ZXMoXG4gICAgICAvKiogQHR5cGUge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG4gICAgICBjb29yZGluYXRlcywgb3B0X2xheW91dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIHBhc3NlZCBwb2ludCB0byB0aGlzIG11bHRpcG9pbnQuXG4gICAqIEBwYXJhbSB7UG9pbnR9IHBvaW50IFBvaW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuYXBwZW5kUG9pbnQgPSBmdW5jdGlvbiAocG9pbnQpIHtcbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IHBvaW50LmdldEZsYXRDb29yZGluYXRlcygpLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4dGVuZCh0aGlzLmZsYXRDb29yZGluYXRlcywgcG9pbnQuZ2V0RmxhdENvb3JkaW5hdGVzKCkpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTXVsdGlQb2ludH0gQ2xvbmUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvaW50LnByb3RvdHlwZS5jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbXVsdGlQb2ludCA9IG5ldyBNdWx0aVBvaW50KHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKCksIHRoaXMubGF5b3V0KTtcbiAgICBtdWx0aVBvaW50LmFwcGx5UHJvcGVydGllcyh0aGlzKTtcbiAgICByZXR1cm4gbXVsdGlQb2ludDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmNsb3Nlc3RQb2ludFhZID0gZnVuY3Rpb24gKHgsIHksIGNsb3Nlc3RQb2ludCwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgaWYgKG1pblNxdWFyZWREaXN0YW5jZSA8IGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWSh0aGlzLmdldEV4dGVudCgpLCB4LCB5KSkge1xuICAgICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgICB9XG5cbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZmxhdENvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyBpICs9IHN0cmlkZSkge1xuICAgICAgdmFyIHNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREeCh4LCB5LCBmbGF0Q29vcmRpbmF0ZXNbaV0sIGZsYXRDb29yZGluYXRlc1tpICsgMV0pO1xuXG4gICAgICBpZiAoc3F1YXJlZERpc3RhbmNlIDwgbWluU3F1YXJlZERpc3RhbmNlKSB7XG4gICAgICAgIG1pblNxdWFyZWREaXN0YW5jZSA9IHNxdWFyZWREaXN0YW5jZTtcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmlkZTsgKytqKSB7XG4gICAgICAgICAgY2xvc2VzdFBvaW50W2pdID0gZmxhdENvb3JkaW5hdGVzW2kgKyBqXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNsb3Nlc3RQb2ludC5sZW5ndGggPSBzdHJpZGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1pblNxdWFyZWREaXN0YW5jZTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpcG9pbnQuXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGluZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoLCB0aGlzLnN0cmlkZSk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHBvaW50IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBJbmRleC5cbiAgICogQHJldHVybiB7UG9pbnR9IFBvaW50LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0UG9pbnQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcbiAgICB2YXIgbiA9ICF0aGlzLmZsYXRDb29yZGluYXRlcyA/IDAgOiB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggLyB0aGlzLnN0cmlkZTtcblxuICAgIGlmIChpbmRleCA8IDAgfHwgbiA8PSBpbmRleCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQb2ludCh0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZShpbmRleCAqIHRoaXMuc3RyaWRlLCAoaW5kZXggKyAxKSAqIHRoaXMuc3RyaWRlKSwgdGhpcy5sYXlvdXQpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBwb2ludHMgb2YgdGhpcyBtdWx0aXBvaW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxQb2ludD59IFBvaW50cy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmdldFBvaW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gdGhpcy5mbGF0Q29vcmRpbmF0ZXM7XG4gICAgdmFyIGxheW91dCA9IHRoaXMubGF5b3V0O1xuICAgIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZTtcbiAgICAvKiogQHR5cGUge0FycmF5PFBvaW50Pn0gKi9cblxuICAgIHZhciBwb2ludHMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZhciBwb2ludCA9IG5ldyBQb2ludChmbGF0Q29vcmRpbmF0ZXMuc2xpY2UoaSwgaSArIHN0cmlkZSksIGxheW91dCk7XG4gICAgICBwb2ludHMucHVzaChwb2ludCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UO1xuICB9O1xuICAvKipcbiAgICogVGVzdCBpZiB0aGUgZ2VvbWV0cnkgYW5kIHRoZSBwYXNzZWQgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgZXh0ZW50IGludGVyc2VjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9pbnQucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIHZhciBzdHJpZGUgPSB0aGlzLnN0cmlkZTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZsYXRDb29yZGluYXRlcy5sZW5ndGg7IGkgPCBpaTsgaSArPSBzdHJpZGUpIHtcbiAgICAgIHZhciB4ID0gZmxhdENvb3JkaW5hdGVzW2ldO1xuICAgICAgdmFyIHkgPSBmbGF0Q29vcmRpbmF0ZXNbaSArIDFdO1xuXG4gICAgICBpZiAoY29udGFpbnNYWShleHRlbnQsIHgsIHkpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpcG9pbnQuXG4gICAqIEBwYXJhbSB7IUFycmF5PGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2ludC5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMSk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IGRlZmxhdGVDb29yZGluYXRlcyh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgY29vcmRpbmF0ZXMsIHRoaXMuc3RyaWRlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcblxuICByZXR1cm4gTXVsdGlQb2ludDtcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBNdWx0aVBvaW50OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvZ2VvbS9NdWx0aVBvbHlnb25cbiAqL1xuXG5cbmltcG9ydCBHZW9tZXRyeUxheW91dCBmcm9tICcuL0dlb21ldHJ5TGF5b3V0LmpzJztcbmltcG9ydCBHZW9tZXRyeVR5cGUgZnJvbSAnLi9HZW9tZXRyeVR5cGUuanMnO1xuaW1wb3J0IE11bHRpUG9pbnQgZnJvbSAnLi9NdWx0aVBvaW50LmpzJztcbmltcG9ydCBQb2x5Z29uIGZyb20gJy4vUG9seWdvbi5qcyc7XG5pbXBvcnQgU2ltcGxlR2VvbWV0cnkgZnJvbSAnLi9TaW1wbGVHZW9tZXRyeS5qcyc7XG5pbXBvcnQgeyBhc3NpZ25DbG9zZXN0TXVsdGlBcnJheVBvaW50LCBtdWx0aUFycmF5TWF4U3F1YXJlZERlbHRhIH0gZnJvbSAnLi9mbGF0L2Nsb3Nlc3QuanMnO1xuaW1wb3J0IHsgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGRlZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkgfSBmcm9tICcuL2ZsYXQvZGVmbGF0ZS5qcyc7XG5pbXBvcnQgeyBleHRlbmQgfSBmcm9tICcuLi9hcnJheS5qcyc7XG5pbXBvcnQgeyBnZXRJbnRlcmlvclBvaW50c09mTXVsdGlBcnJheSB9IGZyb20gJy4vZmxhdC9pbnRlcmlvcnBvaW50LmpzJztcbmltcG9ydCB7IGluZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW5mbGF0ZS5qcyc7XG5pbXBvcnQgeyBpbnRlcnNlY3RzTGluZWFyUmluZ011bHRpQXJyYXkgfSBmcm9tICcuL2ZsYXQvaW50ZXJzZWN0c2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc3NBcmVPcmllbnRlZCwgb3JpZW50TGluZWFyUmluZ3NBcnJheSB9IGZyb20gJy4vZmxhdC9vcmllbnQuanMnO1xuaW1wb3J0IHsgbGluZWFyUmluZ3NzIGFzIGxpbmVhclJpbmdzc0FyZWEgfSBmcm9tICcuL2ZsYXQvYXJlYS5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc3MgYXMgbGluZWFyUmluZ3NzQ2VudGVyIH0gZnJvbSAnLi9mbGF0L2NlbnRlci5qcyc7XG5pbXBvcnQgeyBsaW5lYXJSaW5nc3NDb250YWluc1hZIH0gZnJvbSAnLi9mbGF0L2NvbnRhaW5zLmpzJztcbmltcG9ydCB7IHF1YW50aXplTXVsdGlBcnJheSB9IGZyb20gJy4vZmxhdC9zaW1wbGlmeS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIE11bHRpLXBvbHlnb24gZ2VvbWV0cnkuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBNdWx0aVBvbHlnb24gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoTXVsdGlQb2x5Z29uLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+PnxQb2x5Z29uPnxBcnJheTxudW1iZXI+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogICAgIEZvciBpbnRlcm5hbCB1c2UsIGZsYXQgY29vcmRpbmF0ZXMgaW4gY29tYmluYXRpb24gd2l0aCBgb3B0X2xheW91dGAgYW5kIGBvcHRfZW5kc3NgIGFyZSBhbHNvIGFjY2VwdGVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vR2VvbWV0cnlMYXlvdXQuanNcIikuZGVmYXVsdD19IG9wdF9sYXlvdXQgTGF5b3V0LlxuICAgKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+PX0gb3B0X2VuZHNzIEFycmF5IG9mIGVuZHMgZm9yIGludGVybmFsIHVzZSB3aXRoIGZsYXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gTXVsdGlQb2x5Z29uKGNvb3JkaW5hdGVzLCBvcHRfbGF5b3V0LCBvcHRfZW5kc3MpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzKSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxBcnJheTxudW1iZXI+Pn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5lbmRzc18gPSBbXTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNSZXZpc2lvbl8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmxhdEludGVyaW9yUG9pbnRzXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFfID0gLTE7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubWF4RGVsdGFSZXZpc2lvbl8gPSAtMTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmllbnRlZFJldmlzaW9uXyA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5PG51bWJlcj59XG4gICAgICovXG5cbiAgICBfdGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18gPSBudWxsO1xuXG4gICAgaWYgKCFvcHRfZW5kc3MgJiYgIUFycmF5LmlzQXJyYXkoY29vcmRpbmF0ZXNbMF0pKSB7XG4gICAgICB2YXIgbGF5b3V0ID0gX3RoaXMuZ2V0TGF5b3V0KCk7XG5cbiAgICAgIHZhciBwb2x5Z29ucyA9XG4gICAgICAvKiogQHR5cGUge0FycmF5PFBvbHlnb24+fSAqL1xuICAgICAgY29vcmRpbmF0ZXM7XG4gICAgICB2YXIgZmxhdENvb3JkaW5hdGVzID0gW107XG4gICAgICB2YXIgZW5kc3MgPSBbXTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcG9seWdvbnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgcG9seWdvbiA9IHBvbHlnb25zW2ldO1xuXG4gICAgICAgIGlmIChpID09PSAwKSB7XG4gICAgICAgICAgbGF5b3V0ID0gcG9seWdvbi5nZXRMYXlvdXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvZmZzZXQgPSBmbGF0Q29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgICAgICB2YXIgZW5kcyA9IHBvbHlnb24uZ2V0RW5kcygpO1xuXG4gICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IGVuZHMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgIGVuZHNbal0gKz0gb2Zmc2V0O1xuICAgICAgICB9XG5cbiAgICAgICAgZXh0ZW5kKGZsYXRDb29yZGluYXRlcywgcG9seWdvbi5nZXRGbGF0Q29vcmRpbmF0ZXMoKSk7XG4gICAgICAgIGVuZHNzLnB1c2goZW5kcyk7XG4gICAgICB9XG5cbiAgICAgIG9wdF9sYXlvdXQgPSBsYXlvdXQ7XG4gICAgICBjb29yZGluYXRlcyA9IGZsYXRDb29yZGluYXRlcztcbiAgICAgIG9wdF9lbmRzcyA9IGVuZHNzO1xuICAgIH1cblxuICAgIGlmIChvcHRfbGF5b3V0ICE9PSB1bmRlZmluZWQgJiYgb3B0X2VuZHNzKSB7XG4gICAgICBfdGhpcy5zZXRGbGF0Q29vcmRpbmF0ZXMob3B0X2xheW91dCxcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICAgIGNvb3JkaW5hdGVzKTtcblxuICAgICAgX3RoaXMuZW5kc3NfID0gb3B0X2VuZHNzO1xuICAgIH0gZWxzZSB7XG4gICAgICBfdGhpcy5zZXRDb29yZGluYXRlcyhcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj4+fSAqL1xuICAgICAgY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpO1xuICAgIH1cblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQXBwZW5kIHRoZSBwYXNzZWQgcG9seWdvbiB0byB0aGlzIG11bHRpcG9seWdvbi5cbiAgICogQHBhcmFtIHtQb2x5Z29ufSBwb2x5Z29uIFBvbHlnb24uXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmFwcGVuZFBvbHlnb24gPSBmdW5jdGlvbiAocG9seWdvbikge1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cbiAgICB2YXIgZW5kcztcblxuICAgIGlmICghdGhpcy5mbGF0Q29vcmRpbmF0ZXMpIHtcbiAgICAgIHRoaXMuZmxhdENvb3JkaW5hdGVzID0gcG9seWdvbi5nZXRGbGF0Q29vcmRpbmF0ZXMoKS5zbGljZSgpO1xuICAgICAgZW5kcyA9IHBvbHlnb24uZ2V0RW5kcygpLnNsaWNlKCk7XG4gICAgICB0aGlzLmVuZHNzXy5wdXNoKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBvZmZzZXQgPSB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGg7XG4gICAgICBleHRlbmQodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIHBvbHlnb24uZ2V0RmxhdENvb3JkaW5hdGVzKCkpO1xuICAgICAgZW5kcyA9IHBvbHlnb24uZ2V0RW5kcygpLnNsaWNlKCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBlbmRzW2ldICs9IG9mZnNldDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVuZHNzXy5wdXNoKGVuZHMpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTWFrZSBhIGNvbXBsZXRlIGNvcHkgb2YgdGhlIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHshTXVsdGlQb2x5Z29ufSBDbG9uZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGxlbiA9IHRoaXMuZW5kc3NfLmxlbmd0aDtcbiAgICB2YXIgbmV3RW5kc3MgPSBuZXcgQXJyYXkobGVuKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIG5ld0VuZHNzW2ldID0gdGhpcy5lbmRzc19baV0uc2xpY2UoKTtcbiAgICB9XG5cbiAgICB2YXIgbXVsdGlQb2x5Z29uID0gbmV3IE11bHRpUG9seWdvbih0aGlzLmZsYXRDb29yZGluYXRlcy5zbGljZSgpLCB0aGlzLmxheW91dCwgbmV3RW5kc3MpO1xuICAgIG11bHRpUG9seWdvbi5hcHBseVByb3BlcnRpZXModGhpcyk7XG4gICAgcmV0dXJuIG11bHRpUG9seWdvbjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjbG9zZXN0UG9pbnQgQ2xvc2VzdCBwb2ludC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG1pblNxdWFyZWREaXN0YW5jZSBNaW5pbXVtIHNxdWFyZWQgZGlzdGFuY2UuXG4gICAqIEByZXR1cm4ge251bWJlcn0gTWluaW11bSBzcXVhcmVkIGRpc3RhbmNlLlxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuY2xvc2VzdFBvaW50WFkgPSBmdW5jdGlvbiAoeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpIHtcbiAgICBpZiAobWluU3F1YXJlZERpc3RhbmNlIDwgY2xvc2VzdFNxdWFyZWREaXN0YW5jZVhZKHRoaXMuZ2V0RXh0ZW50KCksIHgsIHkpKSB7XG4gICAgICByZXR1cm4gbWluU3F1YXJlZERpc3RhbmNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1heERlbHRhUmV2aXNpb25fICE9IHRoaXMuZ2V0UmV2aXNpb24oKSkge1xuICAgICAgdGhpcy5tYXhEZWx0YV8gPSBNYXRoLnNxcnQobXVsdGlBcnJheU1heFNxdWFyZWREZWx0YSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlLCAwKSk7XG4gICAgICB0aGlzLm1heERlbHRhUmV2aXNpb25fID0gdGhpcy5nZXRSZXZpc2lvbigpO1xuICAgIH1cblxuICAgIHJldHVybiBhc3NpZ25DbG9zZXN0TXVsdGlBcnJheVBvaW50KHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlLCB0aGlzLm1heERlbHRhXywgdHJ1ZSwgeCwgeSwgY2xvc2VzdFBvaW50LCBtaW5TcXVhcmVkRGlzdGFuY2UpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHggWC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMgKHgsIHkpLlxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuY29udGFpbnNYWSA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIGxpbmVhclJpbmdzc0NvbnRhaW5zWFkodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIHgsIHkpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBhcmVhIG9mIHRoZSBtdWx0aXBvbHlnb24gb24gcHJvamVjdGVkIHBsYW5lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEFyZWEgKG9uIHByb2plY3RlZCBwbGFuZSkuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldEFyZWEgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGxpbmVhclJpbmdzc0FyZWEodGhpcy5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcygpLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBjb29yZGluYXRlIGFycmF5IGZvciB0aGlzIGdlb21ldHJ5LiAgVGhpcyBhcnJheSBoYXMgdGhlIHN0cnVjdHVyZVxuICAgKiBvZiBhIEdlb0pTT04gY29vcmRpbmF0ZSBhcnJheSBmb3IgbXVsdGktcG9seWdvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yaWdodCBPcmllbnQgY29vcmRpbmF0ZXMgYWNjb3JkaW5nIHRvIHRoZSByaWdodC1oYW5kXG4gICAqICAgICBydWxlIChjb3VudGVyLWNsb2Nrd2lzZSBmb3IgZXh0ZXJpb3IgYW5kIGNsb2Nrd2lzZSBmb3IgaW50ZXJpb3IgcmluZ3MpLlxuICAgKiAgICAgSWYgYGZhbHNlYCwgY29vcmRpbmF0ZXMgd2lsbCBiZSBvcmllbnRlZCBhY2NvcmRpbmcgdG8gdGhlIGxlZnQtaGFuZCBydWxlXG4gICAqICAgICAoY2xvY2t3aXNlIGZvciBleHRlcmlvciBhbmQgY291bnRlci1jbG9ja3dpc2UgZm9yIGludGVyaW9yIHJpbmdzKS5cbiAgICogICAgIEJ5IGRlZmF1bHQsIGNvb3JkaW5hdGUgb3JpZW50YXRpb24gd2lsbCBkZXBlbmQgb24gaG93IHRoZSBnZW9tZXRyeSB3YXNcbiAgICogICAgIGNvbnN0cnVjdGVkLlxuICAgKiBAcmV0dXJuIHtBcnJheTxBcnJheTxBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pj59IENvb3JkaW5hdGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uIChvcHRfcmlnaHQpIHtcbiAgICB2YXIgZmxhdENvb3JkaW5hdGVzO1xuXG4gICAgaWYgKG9wdF9yaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCkuc2xpY2UoKTtcbiAgICAgIG9yaWVudExpbmVhclJpbmdzQXJyYXkoZmxhdENvb3JkaW5hdGVzLCAwLCB0aGlzLmVuZHNzXywgdGhpcy5zdHJpZGUsIG9wdF9yaWdodCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIH1cblxuICAgIHJldHVybiBpbmZsYXRlTXVsdGlDb29yZGluYXRlc0FycmF5KGZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PEFycmF5PG51bWJlcj4+fSBFbmRzcy5cbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldEVuZHNzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmVuZHNzXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IEZsYXQgaW50ZXJpb3IgcG9pbnRzLlxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuZ2V0RmxhdEludGVyaW9yUG9pbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmZsYXRJbnRlcmlvclBvaW50c1JldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHZhciBmbGF0Q2VudGVycyA9IGxpbmVhclJpbmdzc0NlbnRlcih0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlKTtcbiAgICAgIHRoaXMuZmxhdEludGVyaW9yUG9pbnRzXyA9IGdldEludGVyaW9yUG9pbnRzT2ZNdWx0aUFycmF5KHRoaXMuZ2V0T3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXMoKSwgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlLCBmbGF0Q2VudGVycyk7XG4gICAgICB0aGlzLmZsYXRJbnRlcmlvclBvaW50c1JldmlzaW9uXyA9IHRoaXMuZ2V0UmV2aXNpb24oKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5mbGF0SW50ZXJpb3JQb2ludHNfO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBpbnRlcmlvciBwb2ludHMgYXMge0BsaW5rIG1vZHVsZTpvbC9nZW9tL011bHRpUG9pbnQgbXVsdGlwb2ludH0uXG4gICAqIEByZXR1cm4ge011bHRpUG9pbnR9IEludGVyaW9yIHBvaW50cyBhcyBYWU0gY29vcmRpbmF0ZXMsIHdoZXJlIE0gaXNcbiAgICogdGhlIGxlbmd0aCBvZiB0aGUgaG9yaXpvbnRhbCBpbnRlcnNlY3Rpb24gdGhhdCB0aGUgcG9pbnQgYmVsb25ncyB0by5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuZ2V0SW50ZXJpb3JQb2ludHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBNdWx0aVBvaW50KHRoaXMuZ2V0RmxhdEludGVyaW9yUG9pbnRzKCkuc2xpY2UoKSwgR2VvbWV0cnlMYXlvdXQuWFlNKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE9yaWVudGVkIGZsYXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRPcmllbnRlZEZsYXRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5vcmllbnRlZFJldmlzaW9uXyAhPSB0aGlzLmdldFJldmlzaW9uKCkpIHtcbiAgICAgIHZhciBmbGF0Q29vcmRpbmF0ZXMgPSB0aGlzLmZsYXRDb29yZGluYXRlcztcblxuICAgICAgaWYgKGxpbmVhclJpbmdzc0FyZU9yaWVudGVkKGZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlKSkge1xuICAgICAgICB0aGlzLm9yaWVudGVkRmxhdENvb3JkaW5hdGVzXyA9IGZsYXRDb29yZGluYXRlcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXNfID0gZmxhdENvb3JkaW5hdGVzLnNsaWNlKCk7XG4gICAgICAgIHRoaXMub3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXNfLmxlbmd0aCA9IG9yaWVudExpbmVhclJpbmdzQXJyYXkodGhpcy5vcmllbnRlZEZsYXRDb29yZGluYXRlc18sIDAsIHRoaXMuZW5kc3NfLCB0aGlzLnN0cmlkZSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMub3JpZW50ZWRSZXZpc2lvbl8gPSB0aGlzLmdldFJldmlzaW9uKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub3JpZW50ZWRGbGF0Q29vcmRpbmF0ZXNfO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHNxdWFyZWRUb2xlcmFuY2UgU3F1YXJlZCB0b2xlcmFuY2UuXG4gICAqIEByZXR1cm4ge011bHRpUG9seWdvbn0gU2ltcGxpZmllZCBNdWx0aVBvbHlnb24uXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmdldFNpbXBsaWZpZWRHZW9tZXRyeUludGVybmFsID0gZnVuY3Rpb24gKHNxdWFyZWRUb2xlcmFuY2UpIHtcbiAgICB2YXIgc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIHZhciBzaW1wbGlmaWVkRW5kc3MgPSBbXTtcbiAgICBzaW1wbGlmaWVkRmxhdENvb3JkaW5hdGVzLmxlbmd0aCA9IHF1YW50aXplTXVsdGlBcnJheSh0aGlzLmZsYXRDb29yZGluYXRlcywgMCwgdGhpcy5lbmRzc18sIHRoaXMuc3RyaWRlLCBNYXRoLnNxcnQoc3F1YXJlZFRvbGVyYW5jZSksIHNpbXBsaWZpZWRGbGF0Q29vcmRpbmF0ZXMsIDAsIHNpbXBsaWZpZWRFbmRzcyk7XG4gICAgcmV0dXJuIG5ldyBNdWx0aVBvbHlnb24oc2ltcGxpZmllZEZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFksIHNpbXBsaWZpZWRFbmRzcyk7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHBvbHlnb24gYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IEluZGV4LlxuICAgKiBAcmV0dXJuIHtQb2x5Z29ufSBQb2x5Z29uLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRQb2x5Z29uID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgaWYgKGluZGV4IDwgMCB8fCB0aGlzLmVuZHNzXy5sZW5ndGggPD0gaW5kZXgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBvZmZzZXQ7XG5cbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBwcmV2RW5kcyA9IHRoaXMuZW5kc3NfW2luZGV4IC0gMV07XG4gICAgICBvZmZzZXQgPSBwcmV2RW5kc1twcmV2RW5kcy5sZW5ndGggLSAxXTtcbiAgICB9XG5cbiAgICB2YXIgZW5kcyA9IHRoaXMuZW5kc3NfW2luZGV4XS5zbGljZSgpO1xuICAgIHZhciBlbmQgPSBlbmRzW2VuZHMubGVuZ3RoIC0gMV07XG5cbiAgICBpZiAob2Zmc2V0ICE9PSAwKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBlbmRzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgZW5kc1tpXSAtPSBvZmZzZXQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQb2x5Z29uKHRoaXMuZmxhdENvb3JkaW5hdGVzLnNsaWNlKG9mZnNldCwgZW5kKSwgdGhpcy5sYXlvdXQsIGVuZHMpO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBwb2x5Z29ucyBvZiB0aGlzIG11bHRpcG9seWdvbi5cbiAgICogQHJldHVybiB7QXJyYXk8UG9seWdvbj59IFBvbHlnb25zLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRQb2x5Z29ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGF5b3V0ID0gdGhpcy5sYXlvdXQ7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IHRoaXMuZmxhdENvb3JkaW5hdGVzO1xuICAgIHZhciBlbmRzcyA9IHRoaXMuZW5kc3NfO1xuICAgIHZhciBwb2x5Z29ucyA9IFtdO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGlpID0gZW5kc3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgdmFyIGVuZHMgPSBlbmRzc1tpXS5zbGljZSgpO1xuICAgICAgdmFyIGVuZCA9IGVuZHNbZW5kcy5sZW5ndGggLSAxXTtcblxuICAgICAgaWYgKG9mZnNldCAhPT0gMCkge1xuICAgICAgICBmb3IgKHZhciBqID0gMCwgamogPSBlbmRzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICAgICAgICBlbmRzW2pdIC09IG9mZnNldDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB2YXIgcG9seWdvbiA9IG5ldyBQb2x5Z29uKGZsYXRDb29yZGluYXRlcy5zbGljZShvZmZzZXQsIGVuZCksIGxheW91dCwgZW5kcyk7XG4gICAgICBwb2x5Z29ucy5wdXNoKHBvbHlnb24pO1xuICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgIH1cblxuICAgIHJldHVybiBwb2x5Z29ucztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdHlwZSBvZiB0aGlzIGdlb21ldHJ5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeSB0eXBlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTXVsdGlQb2x5Z29uLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBHZW9tZXRyeVR5cGUuTVVMVElfUE9MWUdPTjtcbiAgfTtcbiAgLyoqXG4gICAqIFRlc3QgaWYgdGhlIGdlb21ldHJ5IGFuZCB0aGUgcGFzc2VkIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSBnZW9tZXRyeSBhbmQgdGhlIGV4dGVudCBpbnRlcnNlY3QuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNdWx0aVBvbHlnb24ucHJvdG90eXBlLmludGVyc2VjdHNFeHRlbnQgPSBmdW5jdGlvbiAoZXh0ZW50KSB7XG4gICAgcmV0dXJuIGludGVyc2VjdHNMaW5lYXJSaW5nTXVsdGlBcnJheSh0aGlzLmdldE9yaWVudGVkRmxhdENvb3JkaW5hdGVzKCksIDAsIHRoaXMuZW5kc3NfLCB0aGlzLnN0cmlkZSwgZXh0ZW50KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgY29vcmRpbmF0ZXMgb2YgdGhlIG11bHRpcG9seWdvbi5cbiAgICogQHBhcmFtIHshQXJyYXk8QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj4+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0dlb21ldHJ5TGF5b3V0LmpzXCIpLmRlZmF1bHQ9fSBvcHRfbGF5b3V0IExheW91dC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE11bHRpUG9seWdvbi5wcm90b3R5cGUuc2V0Q29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoY29vcmRpbmF0ZXMsIG9wdF9sYXlvdXQpIHtcbiAgICB0aGlzLnNldExheW91dChvcHRfbGF5b3V0LCBjb29yZGluYXRlcywgMyk7XG5cbiAgICBpZiAoIXRoaXMuZmxhdENvb3JkaW5hdGVzKSB7XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIH1cblxuICAgIHZhciBlbmRzcyA9IGRlZmxhdGVNdWx0aUNvb3JkaW5hdGVzQXJyYXkodGhpcy5mbGF0Q29vcmRpbmF0ZXMsIDAsIGNvb3JkaW5hdGVzLCB0aGlzLnN0cmlkZSwgdGhpcy5lbmRzc18pO1xuXG4gICAgaWYgKGVuZHNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5mbGF0Q29vcmRpbmF0ZXMubGVuZ3RoID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGxhc3RFbmRzID0gZW5kc3NbZW5kc3MubGVuZ3RoIC0gMV07XG4gICAgICB0aGlzLmZsYXRDb29yZGluYXRlcy5sZW5ndGggPSBsYXN0RW5kcy5sZW5ndGggPT09IDAgPyAwIDogbGFzdEVuZHNbbGFzdEVuZHMubGVuZ3RoIC0gMV07XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG5cbiAgcmV0dXJuIE11bHRpUG9seWdvbjtcbn0oU2ltcGxlR2VvbWV0cnkpO1xuXG5leHBvcnQgZGVmYXVsdCBNdWx0aVBvbHlnb247IiwiLyoqXG4gKiBAbW9kdWxlIG9sL2Zvcm1hdC9HZW9KU09OXG4gKi9cbnZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG5cbmltcG9ydCBGZWF0dXJlIGZyb20gJy4uL0ZlYXR1cmUuanMnO1xuaW1wb3J0IEdlb21ldHJ5Q29sbGVjdGlvbiBmcm9tICcuLi9nZW9tL0dlb21ldHJ5Q29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4uL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBKU09ORmVhdHVyZSBmcm9tICcuL0pTT05GZWF0dXJlLmpzJztcbmltcG9ydCBMaW5lU3RyaW5nIGZyb20gJy4uL2dlb20vTGluZVN0cmluZy5qcyc7XG5pbXBvcnQgTXVsdGlMaW5lU3RyaW5nIGZyb20gJy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzJztcbmltcG9ydCBNdWx0aVBvaW50IGZyb20gJy4uL2dlb20vTXVsdGlQb2ludC5qcyc7XG5pbXBvcnQgTXVsdGlQb2x5Z29uIGZyb20gJy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzJztcbmltcG9ydCBQb2ludCBmcm9tICcuLi9nZW9tL1BvaW50LmpzJztcbmltcG9ydCBQb2x5Z29uIGZyb20gJy4uL2dlb20vUG9seWdvbi5qcyc7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuLi9hc3NlcnRzLmpzJztcbmltcG9ydCB7IGFzc2lnbiwgaXNFbXB0eSB9IGZyb20gJy4uL29iai5qcyc7XG5pbXBvcnQgeyBnZXQgYXMgZ2V0UHJvamVjdGlvbiB9IGZyb20gJy4uL3Byb2ouanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtR2VvbWV0cnlXaXRoT3B0aW9ucyB9IGZyb20gJy4vRmVhdHVyZS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCJnZW9qc29uXCIpLkdlb0pTT059IEdlb0pTT05PYmplY3RcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCJnZW9qc29uXCIpLkZlYXR1cmV9IEdlb0pTT05GZWF0dXJlXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiZ2VvanNvblwiKS5GZWF0dXJlQ29sbGVjdGlvbn0gR2VvSlNPTkZlYXR1cmVDb2xsZWN0aW9uXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiZ2VvanNvblwiKS5HZW9tZXRyeX0gR2VvSlNPTkdlb21ldHJ5XG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiZ2VvanNvblwiKS5Qb2ludH0gR2VvSlNPTlBvaW50XG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiZ2VvanNvblwiKS5MaW5lU3RyaW5nfSBHZW9KU09OTGluZVN0cmluZ1xuICogQHR5cGVkZWYge2ltcG9ydChcImdlb2pzb25cIikuUG9seWdvbn0gR2VvSlNPTlBvbHlnb25cbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCJnZW9qc29uXCIpLk11bHRpUG9pbnR9IEdlb0pTT05NdWx0aVBvaW50XG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiZ2VvanNvblwiKS5NdWx0aUxpbmVTdHJpbmd9IEdlb0pTT05NdWx0aUxpbmVTdHJpbmdcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCJnZW9qc29uXCIpLk11bHRpUG9seWdvbn0gR2VvSlNPTk11bHRpUG9seWdvblxuICogQHR5cGVkZWYge2ltcG9ydChcImdlb2pzb25cIikuR2VvbWV0cnlDb2xsZWN0aW9ufSBHZW9KU09OR2VvbWV0cnlDb2xsZWN0aW9uXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtkYXRhUHJvamVjdGlvbj0nRVBTRzo0MzI2J10gRGVmYXVsdCBkYXRhIHByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtmZWF0dXJlUHJvamVjdGlvbl0gUHJvamVjdGlvbiBmb3IgZmVhdHVyZXMgcmVhZCBvclxuICogd3JpdHRlbiBieSB0aGUgZm9ybWF0LiAgT3B0aW9ucyBwYXNzZWQgdG8gcmVhZCBvciB3cml0ZSBtZXRob2RzIHdpbGwgdGFrZSBwcmVjZWRlbmNlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtnZW9tZXRyeU5hbWVdIEdlb21ldHJ5IG5hbWUgdG8gdXNlIHdoZW4gY3JlYXRpbmcgZmVhdHVyZXMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtleHRyYWN0R2VvbWV0cnlOYW1lPWZhbHNlXSBDZXJ0YWluIEdlb0pTT04gcHJvdmlkZXJzIGluY2x1ZGVcbiAqIHRoZSBnZW9tZXRyeV9uYW1lIGZpZWxkIGluIHRoZSBmZWF0dXJlIEdlb0pTT04uIElmIHNldCB0byBgdHJ1ZWAgdGhlIEdlb0pTT04gcmVhZGVyXG4gKiB3aWxsIGxvb2sgZm9yIHRoYXQgZmllbGQgdG8gc2V0IHRoZSBnZW9tZXRyeSBuYW1lLiBJZiBib3RoIHRoaXMgZmllbGQgaXMgc2V0IHRvIGB0cnVlYFxuICogYW5kIGEgYGdlb21ldHJ5TmFtZWAgaXMgcHJvdmlkZWQsIHRoZSBgZ2VvbWV0cnlOYW1lYCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEZlYXR1cmUgZm9ybWF0IGZvciByZWFkaW5nIGFuZCB3cml0aW5nIGRhdGEgaW4gdGhlIEdlb0pTT04gZm9ybWF0LlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgR2VvSlNPTiA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhHZW9KU09OLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBHZW9KU09OKG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5kYXRhUHJvamVjdGlvbiA9IGdldFByb2plY3Rpb24ob3B0aW9ucy5kYXRhUHJvamVjdGlvbiA/IG9wdGlvbnMuZGF0YVByb2plY3Rpb24gOiAnRVBTRzo0MzI2Jyk7XG5cbiAgICBpZiAob3B0aW9ucy5mZWF0dXJlUHJvamVjdGlvbikge1xuICAgICAgX3RoaXMuZGVmYXVsdEZlYXR1cmVQcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbihvcHRpb25zLmZlYXR1cmVQcm9qZWN0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgZ2VvbWV0cnkgYXR0cmlidXRlIGZvciBmZWF0dXJlcy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nfHVuZGVmaW5lZH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5nZW9tZXRyeU5hbWVfID0gb3B0aW9ucy5nZW9tZXRyeU5hbWU7XG4gICAgLyoqXG4gICAgICogTG9vayBmb3IgdGhlIGdlb21ldHJ5IG5hbWUgaW4gdGhlIGZlYXR1cmUgR2VvSlNPTlxuICAgICAqIEB0eXBlIHtib29sZWFufHVuZGVmaW5lZH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgX3RoaXMuZXh0cmFjdEdlb21ldHJ5TmFtZV8gPSBvcHRpb25zLmV4dHJhY3RHZW9tZXRyeU5hbWU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IE9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBGZWF0dXJlLlxuICAgKi9cblxuXG4gIEdlb0pTT04ucHJvdG90eXBlLnJlYWRGZWF0dXJlRnJvbU9iamVjdCA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdF9vcHRpb25zKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0dlb0pTT05GZWF0dXJlfVxuICAgICAqL1xuICAgIHZhciBnZW9KU09ORmVhdHVyZSA9IG51bGw7XG5cbiAgICBpZiAob2JqZWN0Wyd0eXBlJ10gPT09ICdGZWF0dXJlJykge1xuICAgICAgZ2VvSlNPTkZlYXR1cmUgPVxuICAgICAgLyoqIEB0eXBlIHtHZW9KU09ORmVhdHVyZX0gKi9cbiAgICAgIG9iamVjdDtcbiAgICB9IGVsc2Uge1xuICAgICAgZ2VvSlNPTkZlYXR1cmUgPSB7XG4gICAgICAgICd0eXBlJzogJ0ZlYXR1cmUnLFxuICAgICAgICAnZ2VvbWV0cnknOlxuICAgICAgICAvKiogQHR5cGUge0dlb0pTT05HZW9tZXRyeX0gKi9cbiAgICAgICAgb2JqZWN0LFxuICAgICAgICAncHJvcGVydGllcyc6IG51bGxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIGdlb21ldHJ5ID0gcmVhZEdlb21ldHJ5KGdlb0pTT05GZWF0dXJlWydnZW9tZXRyeSddLCBvcHRfb3B0aW9ucyk7XG4gICAgdmFyIGZlYXR1cmUgPSBuZXcgRmVhdHVyZSgpO1xuXG4gICAgaWYgKHRoaXMuZ2VvbWV0cnlOYW1lXykge1xuICAgICAgZmVhdHVyZS5zZXRHZW9tZXRyeU5hbWUodGhpcy5nZW9tZXRyeU5hbWVfKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZXh0cmFjdEdlb21ldHJ5TmFtZV8gJiYgJ2dlb21ldHJ5X25hbWUnIGluIGdlb0pTT05GZWF0dXJlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZlYXR1cmUuc2V0R2VvbWV0cnlOYW1lKGdlb0pTT05GZWF0dXJlWydnZW9tZXRyeV9uYW1lJ10pO1xuICAgIH1cblxuICAgIGZlYXR1cmUuc2V0R2VvbWV0cnkoZ2VvbWV0cnkpO1xuXG4gICAgaWYgKCdpZCcgaW4gZ2VvSlNPTkZlYXR1cmUpIHtcbiAgICAgIGZlYXR1cmUuc2V0SWQoZ2VvSlNPTkZlYXR1cmVbJ2lkJ10pO1xuICAgIH1cblxuICAgIGlmIChnZW9KU09ORmVhdHVyZVsncHJvcGVydGllcyddKSB7XG4gICAgICBmZWF0dXJlLnNldFByb3BlcnRpZXMoZ2VvSlNPTkZlYXR1cmVbJ3Byb3BlcnRpZXMnXSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZlYXR1cmU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IE9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybiB7QXJyYXk8RmVhdHVyZT59IEZlYXR1cmVzLlxuICAgKi9cblxuXG4gIEdlb0pTT04ucHJvdG90eXBlLnJlYWRGZWF0dXJlc0Zyb21PYmplY3QgPSBmdW5jdGlvbiAob2JqZWN0LCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBnZW9KU09OT2JqZWN0ID1cbiAgICAvKiogQHR5cGUge0dlb0pTT05PYmplY3R9ICovXG4gICAgb2JqZWN0O1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vRmVhdHVyZS5qc1wiKS5kZWZhdWx0Pn0gKi9cblxuICAgIHZhciBmZWF0dXJlcyA9IG51bGw7XG5cbiAgICBpZiAoZ2VvSlNPTk9iamVjdFsndHlwZSddID09PSAnRmVhdHVyZUNvbGxlY3Rpb24nKSB7XG4gICAgICB2YXIgZ2VvSlNPTkZlYXR1cmVDb2xsZWN0aW9uID1cbiAgICAgIC8qKiBAdHlwZSB7R2VvSlNPTkZlYXR1cmVDb2xsZWN0aW9ufSAqL1xuICAgICAgb2JqZWN0O1xuICAgICAgZmVhdHVyZXMgPSBbXTtcbiAgICAgIHZhciBnZW9KU09ORmVhdHVyZXMgPSBnZW9KU09ORmVhdHVyZUNvbGxlY3Rpb25bJ2ZlYXR1cmVzJ107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGdlb0pTT05GZWF0dXJlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICAgIGZlYXR1cmVzLnB1c2godGhpcy5yZWFkRmVhdHVyZUZyb21PYmplY3QoZ2VvSlNPTkZlYXR1cmVzW2ldLCBvcHRfb3B0aW9ucykpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmZWF0dXJlcyA9IFt0aGlzLnJlYWRGZWF0dXJlRnJvbU9iamVjdChvYmplY3QsIG9wdF9vcHRpb25zKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZlYXR1cmVzO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtHZW9KU09OR2VvbWV0cnl9IG9iamVjdCBPYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLlJlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2dlb20vR2VvbWV0cnkuanNcIikuZGVmYXVsdH0gR2VvbWV0cnkuXG4gICAqL1xuXG5cbiAgR2VvSlNPTi5wcm90b3R5cGUucmVhZEdlb21ldHJ5RnJvbU9iamVjdCA9IGZ1bmN0aW9uIChvYmplY3QsIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIHJlYWRHZW9tZXRyeShvYmplY3QsIG9wdF9vcHRpb25zKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgT2JqZWN0LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBQcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIEdlb0pTT04ucHJvdG90eXBlLnJlYWRQcm9qZWN0aW9uRnJvbU9iamVjdCA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICB2YXIgY3JzID0gb2JqZWN0WydjcnMnXTtcbiAgICB2YXIgcHJvamVjdGlvbjtcblxuICAgIGlmIChjcnMpIHtcbiAgICAgIGlmIChjcnNbJ3R5cGUnXSA9PSAnbmFtZScpIHtcbiAgICAgICAgcHJvamVjdGlvbiA9IGdldFByb2plY3Rpb24oY3JzWydwcm9wZXJ0aWVzJ11bJ25hbWUnXSk7XG4gICAgICB9IGVsc2UgaWYgKGNyc1sndHlwZSddID09PSAnRVBTRycpIHtcbiAgICAgICAgcHJvamVjdGlvbiA9IGdldFByb2plY3Rpb24oJ0VQU0c6JyArIGNyc1sncHJvcGVydGllcyddWydjb2RlJ10pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXNzZXJ0KGZhbHNlLCAzNik7IC8vIFVua25vd24gU1JTIHR5cGVcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcHJvamVjdGlvbiA9IHRoaXMuZGF0YVByb2plY3Rpb247XG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICBwcm9qZWN0aW9uXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEVuY29kZSBhIGZlYXR1cmUgYXMgYSBHZW9KU09OIEZlYXR1cmUgb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5Xcml0ZU9wdGlvbnM9fSBvcHRfb3B0aW9ucyBXcml0ZSBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtHZW9KU09ORmVhdHVyZX0gT2JqZWN0LlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgR2VvSlNPTi5wcm90b3R5cGUud3JpdGVGZWF0dXJlT2JqZWN0ID0gZnVuY3Rpb24gKGZlYXR1cmUsIG9wdF9vcHRpb25zKSB7XG4gICAgb3B0X29wdGlvbnMgPSB0aGlzLmFkYXB0T3B0aW9ucyhvcHRfb3B0aW9ucyk7XG4gICAgLyoqIEB0eXBlIHtHZW9KU09ORmVhdHVyZX0gKi9cblxuICAgIHZhciBvYmplY3QgPSB7XG4gICAgICAndHlwZSc6ICdGZWF0dXJlJyxcbiAgICAgIGdlb21ldHJ5OiBudWxsLFxuICAgICAgcHJvcGVydGllczogbnVsbFxuICAgIH07XG4gICAgdmFyIGlkID0gZmVhdHVyZS5nZXRJZCgpO1xuXG4gICAgaWYgKGlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9iamVjdC5pZCA9IGlkO1xuICAgIH1cblxuICAgIGlmICghZmVhdHVyZS5oYXNQcm9wZXJ0aWVzKCkpIHtcbiAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgfVxuXG4gICAgdmFyIHByb3BlcnRpZXMgPSBmZWF0dXJlLmdldFByb3BlcnRpZXMoKTtcbiAgICB2YXIgZ2VvbWV0cnkgPSBmZWF0dXJlLmdldEdlb21ldHJ5KCk7XG5cbiAgICBpZiAoZ2VvbWV0cnkpIHtcbiAgICAgIG9iamVjdC5nZW9tZXRyeSA9IHdyaXRlR2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKTtcbiAgICAgIGRlbGV0ZSBwcm9wZXJ0aWVzW2ZlYXR1cmUuZ2V0R2VvbWV0cnlOYW1lKCldO1xuICAgIH1cblxuICAgIGlmICghaXNFbXB0eShwcm9wZXJ0aWVzKSkge1xuICAgICAgb2JqZWN0LnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG4gIC8qKlxuICAgKiBFbmNvZGUgYW4gYXJyYXkgb2YgZmVhdHVyZXMgYXMgYSBHZW9KU09OIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSBmZWF0dXJlcyBGZWF0dXJlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7R2VvSlNPTkZlYXR1cmVDb2xsZWN0aW9ufSBHZW9KU09OIE9iamVjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb0pTT04ucHJvdG90eXBlLndyaXRlRmVhdHVyZXNPYmplY3QgPSBmdW5jdGlvbiAoZmVhdHVyZXMsIG9wdF9vcHRpb25zKSB7XG4gICAgb3B0X29wdGlvbnMgPSB0aGlzLmFkYXB0T3B0aW9ucyhvcHRfb3B0aW9ucyk7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZlYXR1cmVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIG9iamVjdHMucHVzaCh0aGlzLndyaXRlRmVhdHVyZU9iamVjdChmZWF0dXJlc1tpXSwgb3B0X29wdGlvbnMpKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJyxcbiAgICAgIGZlYXR1cmVzOiBvYmplY3RzXG4gICAgfTtcbiAgfTtcbiAgLyoqXG4gICAqIEVuY29kZSBhIGdlb21ldHJ5IGFzIGEgR2VvSlNPTiBvYmplY3QuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAgICogQHJldHVybiB7R2VvSlNPTkdlb21ldHJ5fEdlb0pTT05HZW9tZXRyeUNvbGxlY3Rpb259IE9iamVjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEdlb0pTT04ucHJvdG90eXBlLndyaXRlR2VvbWV0cnlPYmplY3QgPSBmdW5jdGlvbiAoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIHdyaXRlR2VvbWV0cnkoZ2VvbWV0cnksIHRoaXMuYWRhcHRPcHRpb25zKG9wdF9vcHRpb25zKSk7XG4gIH07XG5cbiAgcmV0dXJuIEdlb0pTT047XG59KEpTT05GZWF0dXJlKTtcbi8qKlxuICogQHBhcmFtIHtHZW9KU09OR2VvbWV0cnl8R2VvSlNPTkdlb21ldHJ5Q29sbGVjdGlvbn0gb2JqZWN0IE9iamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLlJlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBHZW9tZXRyeS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlYWRHZW9tZXRyeShvYmplY3QsIG9wdF9vcHRpb25zKSB7XG4gIGlmICghb2JqZWN0KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9XG4gICAqL1xuXG5cbiAgdmFyIGdlb21ldHJ5O1xuXG4gIHN3aXRjaCAob2JqZWN0Wyd0eXBlJ10pIHtcbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0lOVDpcbiAgICAgIHtcbiAgICAgICAgZ2VvbWV0cnkgPSByZWFkUG9pbnRHZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtHZW9KU09OUG9pbnR9ICovXG4gICAgICAgIG9iamVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkc6XG4gICAgICB7XG4gICAgICAgIGdlb21ldHJ5ID0gcmVhZExpbmVTdHJpbmdHZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtHZW9KU09OTGluZVN0cmluZ30gKi9cbiAgICAgICAgb2JqZWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5QT0xZR09OOlxuICAgICAge1xuICAgICAgICBnZW9tZXRyeSA9IHJlYWRQb2x5Z29uR2VvbWV0cnkoXG4gICAgICAgIC8qKiBAdHlwZSB7R2VvSlNPTlBvbHlnb259ICovXG4gICAgICAgIG9iamVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ6XG4gICAgICB7XG4gICAgICAgIGdlb21ldHJ5ID0gcmVhZE11bHRpUG9pbnRHZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtHZW9KU09OTXVsdGlQb2ludH0gKi9cbiAgICAgICAgb2JqZWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORzpcbiAgICAgIHtcbiAgICAgICAgZ2VvbWV0cnkgPSByZWFkTXVsdGlMaW5lU3RyaW5nR2VvbWV0cnkoXG4gICAgICAgIC8qKiBAdHlwZSB7R2VvSlNPTk11bHRpTGluZVN0cmluZ30gKi9cbiAgICAgICAgb2JqZWN0KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9QT0xZR09OOlxuICAgICAge1xuICAgICAgICBnZW9tZXRyeSA9IHJlYWRNdWx0aVBvbHlnb25HZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtHZW9KU09OTXVsdGlQb2x5Z29ufSAqL1xuICAgICAgICBvYmplY3QpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLkdFT01FVFJZX0NPTExFQ1RJT046XG4gICAgICB7XG4gICAgICAgIGdlb21ldHJ5ID0gcmVhZEdlb21ldHJ5Q29sbGVjdGlvbkdlb21ldHJ5KFxuICAgICAgICAvKiogQHR5cGUge0dlb0pTT05HZW9tZXRyeUNvbGxlY3Rpb259ICovXG4gICAgICAgIG9iamVjdCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBHZW9KU09OIHR5cGU6ICcgKyBvYmplY3QudHlwZSk7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtR2VvbWV0cnlXaXRoT3B0aW9ucyhnZW9tZXRyeSwgZmFsc2UsIG9wdF9vcHRpb25zKTtcbn1cbi8qKlxuICogQHBhcmFtIHtHZW9KU09OR2VvbWV0cnlDb2xsZWN0aW9ufSBvYmplY3QgT2JqZWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnM9fSBvcHRfb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtHZW9tZXRyeUNvbGxlY3Rpb259IEdlb21ldHJ5IGNvbGxlY3Rpb24uXG4gKi9cblxuXG5mdW5jdGlvbiByZWFkR2VvbWV0cnlDb2xsZWN0aW9uR2VvbWV0cnkob2JqZWN0LCBvcHRfb3B0aW9ucykge1xuICB2YXIgZ2VvbWV0cmllcyA9IG9iamVjdFsnZ2VvbWV0cmllcyddLm1hcChcbiAgLyoqXG4gICAqIEBwYXJhbSB7R2VvSlNPTkdlb21ldHJ5fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICovXG4gIGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIHJldHVybiByZWFkR2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKTtcbiAgfSk7XG4gIHJldHVybiBuZXcgR2VvbWV0cnlDb2xsZWN0aW9uKGdlb21ldHJpZXMpO1xufVxuLyoqXG4gKiBAcGFyYW0ge0dlb0pTT05Qb2ludH0gb2JqZWN0IE9iamVjdC5cbiAqIEByZXR1cm4ge1BvaW50fSBQb2ludC5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlYWRQb2ludEdlb21ldHJ5KG9iamVjdCkge1xuICByZXR1cm4gbmV3IFBvaW50KG9iamVjdFsnY29vcmRpbmF0ZXMnXSk7XG59XG4vKipcbiAqIEBwYXJhbSB7R2VvSlNPTkxpbmVTdHJpbmd9IG9iamVjdCBPYmplY3QuXG4gKiBAcmV0dXJuIHtMaW5lU3RyaW5nfSBMaW5lU3RyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVhZExpbmVTdHJpbmdHZW9tZXRyeShvYmplY3QpIHtcbiAgcmV0dXJuIG5ldyBMaW5lU3RyaW5nKG9iamVjdFsnY29vcmRpbmF0ZXMnXSk7XG59XG4vKipcbiAqIEBwYXJhbSB7R2VvSlNPTk11bHRpTGluZVN0cmluZ30gb2JqZWN0IE9iamVjdC5cbiAqIEByZXR1cm4ge011bHRpTGluZVN0cmluZ30gTXVsdGlMaW5lU3RyaW5nLlxuICovXG5cblxuZnVuY3Rpb24gcmVhZE11bHRpTGluZVN0cmluZ0dlb21ldHJ5KG9iamVjdCkge1xuICByZXR1cm4gbmV3IE11bHRpTGluZVN0cmluZyhvYmplY3RbJ2Nvb3JkaW5hdGVzJ10pO1xufVxuLyoqXG4gKiBAcGFyYW0ge0dlb0pTT05NdWx0aVBvaW50fSBvYmplY3QgT2JqZWN0LlxuICogQHJldHVybiB7TXVsdGlQb2ludH0gTXVsdGlQb2ludC5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlYWRNdWx0aVBvaW50R2VvbWV0cnkob2JqZWN0KSB7XG4gIHJldHVybiBuZXcgTXVsdGlQb2ludChvYmplY3RbJ2Nvb3JkaW5hdGVzJ10pO1xufVxuLyoqXG4gKiBAcGFyYW0ge0dlb0pTT05NdWx0aVBvbHlnb259IG9iamVjdCBPYmplY3QuXG4gKiBAcmV0dXJuIHtNdWx0aVBvbHlnb259IE11bHRpUG9seWdvbi5cbiAqL1xuXG5cbmZ1bmN0aW9uIHJlYWRNdWx0aVBvbHlnb25HZW9tZXRyeShvYmplY3QpIHtcbiAgcmV0dXJuIG5ldyBNdWx0aVBvbHlnb24ob2JqZWN0Wydjb29yZGluYXRlcyddKTtcbn1cbi8qKlxuICogQHBhcmFtIHtHZW9KU09OUG9seWdvbn0gb2JqZWN0IE9iamVjdC5cbiAqIEByZXR1cm4ge1BvbHlnb259IFBvbHlnb24uXG4gKi9cblxuXG5mdW5jdGlvbiByZWFkUG9seWdvbkdlb21ldHJ5KG9iamVjdCkge1xuICByZXR1cm4gbmV3IFBvbHlnb24ob2JqZWN0Wydjb29yZGluYXRlcyddKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5LmpzXCIpLmRlZmF1bHR9IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAqIEByZXR1cm4ge0dlb0pTT05HZW9tZXRyeX0gR2VvSlNPTiBnZW9tZXRyeS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHdyaXRlR2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIGdlb21ldHJ5ID0gdHJhbnNmb3JtR2VvbWV0cnlXaXRoT3B0aW9ucyhnZW9tZXRyeSwgdHJ1ZSwgb3B0X29wdGlvbnMpO1xuICB2YXIgdHlwZSA9IGdlb21ldHJ5LmdldFR5cGUoKTtcbiAgLyoqIEB0eXBlIHtHZW9KU09OR2VvbWV0cnl9ICovXG5cbiAgdmFyIGdlb0pTT047XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuUE9JTlQ6XG4gICAgICB7XG4gICAgICAgIGdlb0pTT04gPSB3cml0ZVBvaW50R2VvbWV0cnkoXG4gICAgICAgIC8qKiBAdHlwZSB7UG9pbnR9ICovXG4gICAgICAgIGdlb21ldHJ5LCBvcHRfb3B0aW9ucyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkc6XG4gICAgICB7XG4gICAgICAgIGdlb0pTT04gPSB3cml0ZUxpbmVTdHJpbmdHZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtMaW5lU3RyaW5nfSAqL1xuICAgICAgICBnZW9tZXRyeSwgb3B0X29wdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLlBPTFlHT046XG4gICAgICB7XG4gICAgICAgIGdlb0pTT04gPSB3cml0ZVBvbHlnb25HZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtQb2x5Z29ufSAqL1xuICAgICAgICBnZW9tZXRyeSwgb3B0X29wdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX1BPSU5UOlxuICAgICAge1xuICAgICAgICBnZW9KU09OID0gd3JpdGVNdWx0aVBvaW50R2VvbWV0cnkoXG4gICAgICAgIC8qKiBAdHlwZSB7TXVsdGlQb2ludH0gKi9cbiAgICAgICAgZ2VvbWV0cnksIG9wdF9vcHRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5NVUxUSV9MSU5FX1NUUklORzpcbiAgICAgIHtcbiAgICAgICAgZ2VvSlNPTiA9IHdyaXRlTXVsdGlMaW5lU3RyaW5nR2VvbWV0cnkoXG4gICAgICAgIC8qKiBAdHlwZSB7TXVsdGlMaW5lU3RyaW5nfSAqL1xuICAgICAgICBnZW9tZXRyeSwgb3B0X29wdGlvbnMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIGNhc2UgR2VvbWV0cnlUeXBlLk1VTFRJX1BPTFlHT046XG4gICAgICB7XG4gICAgICAgIGdlb0pTT04gPSB3cml0ZU11bHRpUG9seWdvbkdlb21ldHJ5KFxuICAgICAgICAvKiogQHR5cGUge011bHRpUG9seWdvbn0gKi9cbiAgICAgICAgZ2VvbWV0cnksIG9wdF9vcHRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICBjYXNlIEdlb21ldHJ5VHlwZS5HRU9NRVRSWV9DT0xMRUNUSU9OOlxuICAgICAge1xuICAgICAgICBnZW9KU09OID0gd3JpdGVHZW9tZXRyeUNvbGxlY3Rpb25HZW9tZXRyeShcbiAgICAgICAgLyoqIEB0eXBlIHtHZW9tZXRyeUNvbGxlY3Rpb259ICovXG4gICAgICAgIGdlb21ldHJ5LCBvcHRfb3B0aW9ucyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgY2FzZSBHZW9tZXRyeVR5cGUuQ0lSQ0xFOlxuICAgICAge1xuICAgICAgICBnZW9KU09OID0ge1xuICAgICAgICAgIHR5cGU6ICdHZW9tZXRyeUNvbGxlY3Rpb24nLFxuICAgICAgICAgIGdlb21ldHJpZXM6IFtdXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBnZW9tZXRyeSB0eXBlOiAnICsgdHlwZSk7XG4gICAgICB9XG4gIH1cblxuICByZXR1cm4gZ2VvSlNPTjtcbn1cbi8qKlxuICogQHBhcmFtIHtHZW9tZXRyeUNvbGxlY3Rpb259IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAqIEByZXR1cm4ge0dlb0pTT05HZW9tZXRyeUNvbGxlY3Rpb259IEdlb0pTT04gZ2VvbWV0cnkgY29sbGVjdGlvbi5cbiAqL1xuXG5cbmZ1bmN0aW9uIHdyaXRlR2VvbWV0cnlDb2xsZWN0aW9uR2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHZhciBnZW9tZXRyaWVzID0gZ2VvbWV0cnkuZ2V0R2VvbWV0cmllc0FycmF5KCkubWFwKGZ1bmN0aW9uIChnZW9tZXRyeSkge1xuICAgIHZhciBvcHRpb25zID0gYXNzaWduKHt9LCBvcHRfb3B0aW9ucyk7XG4gICAgZGVsZXRlIG9wdGlvbnMuZmVhdHVyZVByb2plY3Rpb247XG4gICAgcmV0dXJuIHdyaXRlR2VvbWV0cnkoZ2VvbWV0cnksIG9wdGlvbnMpO1xuICB9KTtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnR2VvbWV0cnlDb2xsZWN0aW9uJyxcbiAgICBnZW9tZXRyaWVzOiBnZW9tZXRyaWVzXG4gIH07XG59XG4vKipcbiAqIEBwYXJhbSB7TGluZVN0cmluZ30gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5Xcml0ZU9wdGlvbnM9fSBvcHRfb3B0aW9ucyBXcml0ZSBvcHRpb25zLlxuICogQHJldHVybiB7R2VvSlNPTkdlb21ldHJ5fSBHZW9KU09OIGdlb21ldHJ5LlxuICovXG5cblxuZnVuY3Rpb24gd3JpdGVMaW5lU3RyaW5nR2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0xpbmVTdHJpbmcnLFxuICAgIGNvb3JkaW5hdGVzOiBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpXG4gIH07XG59XG4vKipcbiAqIEBwYXJhbSB7TXVsdGlMaW5lU3RyaW5nfSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtHZW9KU09OR2VvbWV0cnl9IEdlb0pTT04gZ2VvbWV0cnkuXG4gKi9cblxuXG5mdW5jdGlvbiB3cml0ZU11bHRpTGluZVN0cmluZ0dlb21ldHJ5KGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6ICdNdWx0aUxpbmVTdHJpbmcnLFxuICAgIGNvb3JkaW5hdGVzOiBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpXG4gIH07XG59XG4vKipcbiAqIEBwYXJhbSB7TXVsdGlQb2ludH0gZ2VvbWV0cnkgR2VvbWV0cnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5Xcml0ZU9wdGlvbnM9fSBvcHRfb3B0aW9ucyBXcml0ZSBvcHRpb25zLlxuICogQHJldHVybiB7R2VvSlNPTkdlb21ldHJ5fSBHZW9KU09OIGdlb21ldHJ5LlxuICovXG5cblxuZnVuY3Rpb24gd3JpdGVNdWx0aVBvaW50R2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ011bHRpUG9pbnQnLFxuICAgIGNvb3JkaW5hdGVzOiBnZW9tZXRyeS5nZXRDb29yZGluYXRlcygpXG4gIH07XG59XG4vKipcbiAqIEBwYXJhbSB7TXVsdGlQb2x5Z29ufSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtHZW9KU09OR2VvbWV0cnl9IEdlb0pTT04gZ2VvbWV0cnkuXG4gKi9cblxuXG5mdW5jdGlvbiB3cml0ZU11bHRpUG9seWdvbkdlb21ldHJ5KGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICB2YXIgcmlnaHQ7XG5cbiAgaWYgKG9wdF9vcHRpb25zKSB7XG4gICAgcmlnaHQgPSBvcHRfb3B0aW9ucy5yaWdodEhhbmRlZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ011bHRpUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IGdlb21ldHJ5LmdldENvb3JkaW5hdGVzKHJpZ2h0KVxuICB9O1xufVxuLyoqXG4gKiBAcGFyYW0ge1BvaW50fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLldyaXRlT3B0aW9ucz19IG9wdF9vcHRpb25zIFdyaXRlIG9wdGlvbnMuXG4gKiBAcmV0dXJuIHtHZW9KU09OR2VvbWV0cnl9IEdlb0pTT04gZ2VvbWV0cnkuXG4gKi9cblxuXG5mdW5jdGlvbiB3cml0ZVBvaW50R2VvbWV0cnkoZ2VvbWV0cnksIG9wdF9vcHRpb25zKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ1BvaW50JyxcbiAgICBjb29yZGluYXRlczogZ2VvbWV0cnkuZ2V0Q29vcmRpbmF0ZXMoKVxuICB9O1xufVxuLyoqXG4gKiBAcGFyYW0ge1BvbHlnb259IGdlb21ldHJ5IEdlb21ldHJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuV3JpdGVPcHRpb25zPX0gb3B0X29wdGlvbnMgV3JpdGUgb3B0aW9ucy5cbiAqIEByZXR1cm4ge0dlb0pTT05HZW9tZXRyeX0gR2VvSlNPTiBnZW9tZXRyeS5cbiAqL1xuXG5cbmZ1bmN0aW9uIHdyaXRlUG9seWdvbkdlb21ldHJ5KGdlb21ldHJ5LCBvcHRfb3B0aW9ucykge1xuICB2YXIgcmlnaHQ7XG5cbiAgaWYgKG9wdF9vcHRpb25zKSB7XG4gICAgcmlnaHQgPSBvcHRfb3B0aW9ucy5yaWdodEhhbmRlZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogJ1BvbHlnb24nLFxuICAgIGNvb3JkaW5hdGVzOiBnZW9tZXRyeS5nZXRDb29yZGluYXRlcyhyaWdodClcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgR2VvSlNPTjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvZm9ybWF0L01WVFxuICovXG4vL0ZJWE1FIEltcGxlbWVudCBwcm9qZWN0aW9uIGhhbmRsaW5nXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRmVhdHVyZUZvcm1hdCwgeyB0cmFuc2Zvcm1HZW9tZXRyeVdpdGhPcHRpb25zIH0gZnJvbSAnLi9GZWF0dXJlLmpzJztcbmltcG9ydCBGb3JtYXRUeXBlIGZyb20gJy4vRm9ybWF0VHlwZS5qcyc7XG5pbXBvcnQgR2VvbWV0cnlMYXlvdXQgZnJvbSAnLi4vZ2VvbS9HZW9tZXRyeUxheW91dC5qcyc7XG5pbXBvcnQgR2VvbWV0cnlUeXBlIGZyb20gJy4uL2dlb20vR2VvbWV0cnlUeXBlLmpzJztcbmltcG9ydCBMaW5lU3RyaW5nIGZyb20gJy4uL2dlb20vTGluZVN0cmluZy5qcyc7XG5pbXBvcnQgTXVsdGlMaW5lU3RyaW5nIGZyb20gJy4uL2dlb20vTXVsdGlMaW5lU3RyaW5nLmpzJztcbmltcG9ydCBNdWx0aVBvaW50IGZyb20gJy4uL2dlb20vTXVsdGlQb2ludC5qcyc7XG5pbXBvcnQgTXVsdGlQb2x5Z29uIGZyb20gJy4uL2dlb20vTXVsdGlQb2x5Z29uLmpzJztcbmltcG9ydCBQQkYgZnJvbSAncGJmJztcbmltcG9ydCBQb2ludCBmcm9tICcuLi9nZW9tL1BvaW50LmpzJztcbmltcG9ydCBQb2x5Z29uIGZyb20gJy4uL2dlb20vUG9seWdvbi5qcyc7XG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuLi9wcm9qL1Byb2plY3Rpb24uanMnO1xuaW1wb3J0IFJlbmRlckZlYXR1cmUgZnJvbSAnLi4vcmVuZGVyL0ZlYXR1cmUuanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4uL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBnZXQgfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IGxpbmVhclJpbmdJc0Nsb2Nrd2lzZSB9IGZyb20gJy4uL2dlb20vZmxhdC9vcmllbnQuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUNsYXNzfSBbZmVhdHVyZUNsYXNzXSBDbGFzcyBmb3IgZmVhdHVyZXMgcmV0dXJuZWQgYnlcbiAqIHtAbGluayBtb2R1bGU6b2wvZm9ybWF0L01WVCNyZWFkRmVhdHVyZXN9LiBTZXQgdG8ge0BsaW5rIG1vZHVsZTpvbC9GZWF0dXJlfkZlYXR1cmV9IHRvIGdldCBmdWxsIGVkaXRpbmcgYW5kIGdlb21ldHJ5XG4gKiBzdXBwb3J0IGF0IHRoZSBjb3N0IG9mIGRlY3JlYXNlZCByZW5kZXJpbmcgcGVyZm9ybWFuY2UuIFRoZSBkZWZhdWx0IGlzXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3JlbmRlci9GZWF0dXJlflJlbmRlckZlYXR1cmV9LCB3aGljaCBpcyBvcHRpbWl6ZWQgZm9yIHJlbmRlcmluZyBhbmQgaGl0IGRldGVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZ2VvbWV0cnlOYW1lPSdnZW9tZXRyeSddIEdlb21ldHJ5IG5hbWUgdG8gdXNlIHdoZW4gY3JlYXRpbmcgZmVhdHVyZXMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2xheWVyTmFtZT0nbGF5ZXInXSBOYW1lIG9mIHRoZSBmZWF0dXJlIGF0dHJpYnV0ZSB0aGF0IGhvbGRzIHRoZSBsYXllciBuYW1lLlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbbGF5ZXJzXSBMYXllcnMgdG8gcmVhZCBmZWF0dXJlcyBmcm9tLiBJZiBub3QgcHJvdmlkZWQsIGZlYXR1cmVzIHdpbGwgYmUgcmVhZCBmcm9tIGFsbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtpZFByb3BlcnR5XSBPcHRpb25hbCBwcm9wZXJ0eSB0aGF0IHdpbGwgYmUgYXNzaWduZWQgYXMgdGhlIGZlYXR1cmUgaWQgYW5kIHJlbW92ZWQgZnJvbSB0aGUgcHJvcGVydGllcy5cbiAqIGxheWVycy5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIEZlYXR1cmUgZm9ybWF0IGZvciByZWFkaW5nIGRhdGEgaW4gdGhlIE1hcGJveCBNVlQgZm9ybWF0LlxuICpcbiAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIE9wdGlvbnMuXG4gKiBAYXBpXG4gKi9cblxudmFyIE1WVCA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhNVlQsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIE1WVChvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMpIHx8IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7UHJvamVjdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRhdGFQcm9qZWN0aW9uID0gbmV3IFByb2plY3Rpb24oe1xuICAgICAgY29kZTogJycsXG4gICAgICB1bml0czogVW5pdHMuVElMRV9QSVhFTFNcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVDbGFzc31cbiAgICAgKi9cblxuICAgIF90aGlzLmZlYXR1cmVDbGFzc18gPSBvcHRpb25zLmZlYXR1cmVDbGFzcyA/IG9wdGlvbnMuZmVhdHVyZUNsYXNzIDogUmVuZGVyRmVhdHVyZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgX3RoaXMuZ2VvbWV0cnlOYW1lXyA9IG9wdGlvbnMuZ2VvbWV0cnlOYW1lO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLmxheWVyTmFtZV8gPSBvcHRpb25zLmxheWVyTmFtZSA/IG9wdGlvbnMubGF5ZXJOYW1lIDogJ2xheWVyJztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuXG4gICAgX3RoaXMubGF5ZXJzXyA9IG9wdGlvbnMubGF5ZXJzID8gb3B0aW9ucy5sYXllcnMgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLmlkUHJvcGVydHlfID0gb3B0aW9ucy5pZFByb3BlcnR5O1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogUmVhZCB0aGUgcmF3IGdlb21ldHJ5IGZyb20gdGhlIHBiZiBvZmZzZXQgc3RvcmVkIGluIGEgcmF3IGZlYXR1cmUncyBnZW9tZXRyeVxuICAgKiBwcm9wZXJ0eS5cbiAgICogQHBhcmFtIHtQQkZ9IHBiZiBQQkYuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBmZWF0dXJlIFJhdyBmZWF0dXJlLlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGZsYXRDb29yZGluYXRlcyBBcnJheSB0byBzdG9yZSBmbGF0IGNvb3JkaW5hdGVzIGluLlxuICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGVuZHMgQXJyYXkgdG8gc3RvcmUgZW5kcyBpbi5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBNVlQucHJvdG90eXBlLnJlYWRSYXdHZW9tZXRyeV8gPSBmdW5jdGlvbiAocGJmLCBmZWF0dXJlLCBmbGF0Q29vcmRpbmF0ZXMsIGVuZHMpIHtcbiAgICBwYmYucG9zID0gZmVhdHVyZS5nZW9tZXRyeTtcbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG4gICAgdmFyIGNtZCA9IDE7XG4gICAgdmFyIGxlbmd0aCA9IDA7XG4gICAgdmFyIHggPSAwO1xuICAgIHZhciB5ID0gMDtcbiAgICB2YXIgY29vcmRzTGVuID0gMDtcbiAgICB2YXIgY3VycmVudEVuZCA9IDA7XG5cbiAgICB3aGlsZSAocGJmLnBvcyA8IGVuZCkge1xuICAgICAgaWYgKCFsZW5ndGgpIHtcbiAgICAgICAgdmFyIGNtZExlbiA9IHBiZi5yZWFkVmFyaW50KCk7XG4gICAgICAgIGNtZCA9IGNtZExlbiAmIDB4NztcbiAgICAgICAgbGVuZ3RoID0gY21kTGVuID4+IDM7XG4gICAgICB9XG5cbiAgICAgIGxlbmd0aC0tO1xuXG4gICAgICBpZiAoY21kID09PSAxIHx8IGNtZCA9PT0gMikge1xuICAgICAgICB4ICs9IHBiZi5yZWFkU1ZhcmludCgpO1xuICAgICAgICB5ICs9IHBiZi5yZWFkU1ZhcmludCgpO1xuXG4gICAgICAgIGlmIChjbWQgPT09IDEpIHtcbiAgICAgICAgICAvLyBtb3ZlVG9cbiAgICAgICAgICBpZiAoY29vcmRzTGVuID4gY3VycmVudEVuZCkge1xuICAgICAgICAgICAgZW5kcy5wdXNoKGNvb3Jkc0xlbik7XG4gICAgICAgICAgICBjdXJyZW50RW5kID0gY29vcmRzTGVuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGZsYXRDb29yZGluYXRlcy5wdXNoKHgsIHkpO1xuICAgICAgICBjb29yZHNMZW4gKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoY21kID09PSA3KSB7XG4gICAgICAgIGlmIChjb29yZHNMZW4gPiBjdXJyZW50RW5kKSB7XG4gICAgICAgICAgLy8gY2xvc2UgcG9seWdvblxuICAgICAgICAgIGZsYXRDb29yZGluYXRlcy5wdXNoKGZsYXRDb29yZGluYXRlc1tjdXJyZW50RW5kXSwgZmxhdENvb3JkaW5hdGVzW2N1cnJlbnRFbmQgKyAxXSk7XG4gICAgICAgICAgY29vcmRzTGVuICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFzc2VydChmYWxzZSwgNTkpOyAvLyBJbnZhbGlkIGNvbW1hbmQgZm91bmQgaW4gdGhlIFBCRlxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjb29yZHNMZW4gPiBjdXJyZW50RW5kKSB7XG4gICAgICBlbmRzLnB1c2goY29vcmRzTGVuKTtcbiAgICAgIGN1cnJlbnRFbmQgPSBjb29yZHNMZW47XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtQQkZ9IHBiZiBQQkZcbiAgICogQHBhcmFtIHtPYmplY3R9IHJhd0ZlYXR1cmUgUmF3IE1hcGJveCBmZWF0dXJlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5SZWFkT3B0aW9uc30gb3B0aW9ucyBSZWFkIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuRmVhdHVyZUxpa2V9IEZlYXR1cmUuXG4gICAqL1xuXG5cbiAgTVZULnByb3RvdHlwZS5jcmVhdGVGZWF0dXJlXyA9IGZ1bmN0aW9uIChwYmYsIHJhd0ZlYXR1cmUsIG9wdGlvbnMpIHtcbiAgICB2YXIgdHlwZSA9IHJhd0ZlYXR1cmUudHlwZTtcblxuICAgIGlmICh0eXBlID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgZmVhdHVyZTtcbiAgICB2YXIgdmFsdWVzID0gcmF3RmVhdHVyZS5wcm9wZXJ0aWVzO1xuICAgIHZhciBpZDtcblxuICAgIGlmICghdGhpcy5pZFByb3BlcnR5Xykge1xuICAgICAgaWQgPSByYXdGZWF0dXJlLmlkO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZCA9IHZhbHVlc1t0aGlzLmlkUHJvcGVydHlfXTtcbiAgICAgIGRlbGV0ZSB2YWx1ZXNbdGhpcy5pZFByb3BlcnR5X107XG4gICAgfVxuXG4gICAgdmFsdWVzW3RoaXMubGF5ZXJOYW1lX10gPSByYXdGZWF0dXJlLmxheWVyLm5hbWU7XG4gICAgdmFyIGZsYXRDb29yZGluYXRlcyA9IFtdO1xuICAgIHZhciBlbmRzID0gW107XG4gICAgdGhpcy5yZWFkUmF3R2VvbWV0cnlfKHBiZiwgcmF3RmVhdHVyZSwgZmxhdENvb3JkaW5hdGVzLCBlbmRzKTtcbiAgICB2YXIgZ2VvbWV0cnlUeXBlID0gZ2V0R2VvbWV0cnlUeXBlKHR5cGUsIGVuZHMubGVuZ3RoKTtcblxuICAgIGlmICh0aGlzLmZlYXR1cmVDbGFzc18gPT09IFJlbmRlckZlYXR1cmUpIHtcbiAgICAgIGZlYXR1cmUgPSBuZXcgdGhpcy5mZWF0dXJlQ2xhc3NfKGdlb21ldHJ5VHlwZSwgZmxhdENvb3JkaW5hdGVzLCBlbmRzLCB2YWx1ZXMsIGlkKTtcbiAgICAgIGZlYXR1cmUudHJhbnNmb3JtKG9wdGlvbnMuZGF0YVByb2plY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZ2VvbSA9IHZvaWQgMDtcblxuICAgICAgaWYgKGdlb21ldHJ5VHlwZSA9PSBHZW9tZXRyeVR5cGUuUE9MWUdPTikge1xuICAgICAgICB2YXIgZW5kc3MgPSBbXTtcbiAgICAgICAgdmFyIG9mZnNldCA9IDA7XG4gICAgICAgIHZhciBwcmV2RW5kSW5kZXggPSAwO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGVuZHMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICAgIHZhciBlbmQgPSBlbmRzW2ldOyAvLyBjbGFzc2lmaWVzIGFuIGFycmF5IG9mIHJpbmdzIGludG8gcG9seWdvbnMgd2l0aCBvdXRlciByaW5ncyBhbmQgaG9sZXNcblxuICAgICAgICAgIGlmICghbGluZWFyUmluZ0lzQ2xvY2t3aXNlKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIDIpKSB7XG4gICAgICAgICAgICBlbmRzcy5wdXNoKGVuZHMuc2xpY2UocHJldkVuZEluZGV4LCBpICsgMSkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZW5kc3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlbmRzc1tlbmRzcy5sZW5ndGggLSAxXS5wdXNoKGVuZHNbcHJldkVuZEluZGV4XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcHJldkVuZEluZGV4ID0gaSArIDE7XG4gICAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVuZHNzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBnZW9tID0gbmV3IE11bHRpUG9seWdvbihmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBlbmRzcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZ2VvbSA9IG5ldyBQb2x5Z29uKGZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFksIGVuZHMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZW9tID0gZ2VvbWV0cnlUeXBlID09PSBHZW9tZXRyeVR5cGUuUE9JTlQgPyBuZXcgUG9pbnQoZmxhdENvb3JkaW5hdGVzLCBHZW9tZXRyeUxheW91dC5YWSkgOiBnZW9tZXRyeVR5cGUgPT09IEdlb21ldHJ5VHlwZS5MSU5FX1NUUklORyA/IG5ldyBMaW5lU3RyaW5nKGZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFkpIDogZ2VvbWV0cnlUeXBlID09PSBHZW9tZXRyeVR5cGUuUE9MWUdPTiA/IG5ldyBQb2x5Z29uKGZsYXRDb29yZGluYXRlcywgR2VvbWV0cnlMYXlvdXQuWFksIGVuZHMpIDogZ2VvbWV0cnlUeXBlID09PSBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQgPyBuZXcgTXVsdGlQb2ludChmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZKSA6IGdlb21ldHJ5VHlwZSA9PT0gR2VvbWV0cnlUeXBlLk1VTFRJX0xJTkVfU1RSSU5HID8gbmV3IE11bHRpTGluZVN0cmluZyhmbGF0Q29vcmRpbmF0ZXMsIEdlb21ldHJ5TGF5b3V0LlhZLCBlbmRzKSA6IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciBjdG9yID1cbiAgICAgIC8qKiBAdHlwZSB7dHlwZW9mIGltcG9ydChcIi4uL0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIHRoaXMuZmVhdHVyZUNsYXNzXztcbiAgICAgIGZlYXR1cmUgPSBuZXcgY3RvcigpO1xuXG4gICAgICBpZiAodGhpcy5nZW9tZXRyeU5hbWVfKSB7XG4gICAgICAgIGZlYXR1cmUuc2V0R2VvbWV0cnlOYW1lKHRoaXMuZ2VvbWV0cnlOYW1lXyk7XG4gICAgICB9XG5cbiAgICAgIHZhciBnZW9tZXRyeSA9IHRyYW5zZm9ybUdlb21ldHJ5V2l0aE9wdGlvbnMoZ2VvbSwgZmFsc2UsIG9wdGlvbnMpO1xuICAgICAgZmVhdHVyZS5zZXRHZW9tZXRyeShnZW9tZXRyeSk7XG4gICAgICBmZWF0dXJlLnNldElkKGlkKTtcbiAgICAgIGZlYXR1cmUuc2V0UHJvcGVydGllcyh2YWx1ZXMsIHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiBmZWF0dXJlO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9Gb3JtYXRUeXBlLmpzXCIpLmRlZmF1bHR9IEZvcm1hdC5cbiAgICovXG5cblxuICBNVlQucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIEZvcm1hdFR5cGUuQVJSQVlfQlVGRkVSO1xuICB9O1xuICAvKipcbiAgICogUmVhZCBhbGwgZmVhdHVyZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IHNvdXJjZSBTb3VyY2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLlJlYWRPcHRpb25zPX0gb3B0X29wdGlvbnMgUmVhZCBvcHRpb25zLlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBNVlQucHJvdG90eXBlLnJlYWRGZWF0dXJlcyA9IGZ1bmN0aW9uIChzb3VyY2UsIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIGxheWVycyA9IHRoaXMubGF5ZXJzXztcbiAgICB2YXIgb3B0aW9ucyA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL0ZlYXR1cmUuanNcIikuUmVhZE9wdGlvbnN9ICovXG4gICAgdGhpcy5hZGFwdE9wdGlvbnMob3B0X29wdGlvbnMpO1xuICAgIHZhciBkYXRhUHJvamVjdGlvbiA9IGdldChvcHRpb25zLmRhdGFQcm9qZWN0aW9uKTtcbiAgICBkYXRhUHJvamVjdGlvbi5zZXRXb3JsZEV4dGVudChvcHRpb25zLmV4dGVudCk7XG4gICAgb3B0aW9ucy5kYXRhUHJvamVjdGlvbiA9IGRhdGFQcm9qZWN0aW9uO1xuICAgIHZhciBwYmYgPSBuZXcgUEJGKFxuICAgIC8qKiBAdHlwZSB7QXJyYXlCdWZmZXJ9ICovXG4gICAgc291cmNlKTtcbiAgICB2YXIgcGJmTGF5ZXJzID0gcGJmLnJlYWRGaWVsZHMobGF5ZXJzUEJGUmVhZGVyLCB7fSk7XG4gICAgdmFyIGZlYXR1cmVzID0gW107XG5cbiAgICBmb3IgKHZhciBuYW1lXzEgaW4gcGJmTGF5ZXJzKSB7XG4gICAgICBpZiAobGF5ZXJzICYmIGxheWVycy5pbmRleE9mKG5hbWVfMSkgPT0gLTEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBwYmZMYXllciA9IHBiZkxheWVyc1tuYW1lXzFdO1xuICAgICAgdmFyIGV4dGVudCA9IHBiZkxheWVyID8gWzAsIDAsIHBiZkxheWVyLmV4dGVudCwgcGJmTGF5ZXIuZXh0ZW50XSA6IG51bGw7XG4gICAgICBkYXRhUHJvamVjdGlvbi5zZXRFeHRlbnQoZXh0ZW50KTtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIGlpID0gcGJmTGF5ZXIubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICB2YXIgcmF3RmVhdHVyZSA9IHJlYWRSYXdGZWF0dXJlKHBiZiwgcGJmTGF5ZXIsIGkpO1xuICAgICAgICBmZWF0dXJlcy5wdXNoKHRoaXMuY3JlYXRlRmVhdHVyZV8ocGJmLCByYXdGZWF0dXJlLCBvcHRpb25zKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZlYXR1cmVzO1xuICB9O1xuICAvKipcbiAgICogUmVhZCB0aGUgcHJvamVjdGlvbiBmcm9tIHRoZSBzb3VyY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7RG9jdW1lbnR8RWxlbWVudHxPYmplY3R8c3RyaW5nfSBzb3VyY2UgU291cmNlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gUHJvamVjdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE1WVC5wcm90b3R5cGUucmVhZFByb2plY3Rpb24gPSBmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVByb2plY3Rpb247XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBsYXllcnMgdGhhdCBmZWF0dXJlcyB3aWxsIGJlIHJlYWQgZnJvbS5cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBsYXllcnMgTGF5ZXJzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgTVZULnByb3RvdHlwZS5zZXRMYXllcnMgPSBmdW5jdGlvbiAobGF5ZXJzKSB7XG4gICAgdGhpcy5sYXllcnNfID0gbGF5ZXJzO1xuICB9O1xuXG4gIHJldHVybiBNVlQ7XG59KEZlYXR1cmVGb3JtYXQpO1xuLyoqXG4gKiBSZWFkZXIgY2FsbGJhY2sgZm9yIHBhcnNpbmcgbGF5ZXJzLlxuICogQHBhcmFtIHtudW1iZXJ9IHRhZyBUaGUgdGFnLlxuICogQHBhcmFtIHtPYmplY3R9IGxheWVycyBUaGUgbGF5ZXJzIG9iamVjdC5cbiAqIEBwYXJhbSB7UEJGfSBwYmYgVGhlIFBCRi5cbiAqL1xuXG5cbmZ1bmN0aW9uIGxheWVyc1BCRlJlYWRlcih0YWcsIGxheWVycywgcGJmKSB7XG4gIGlmICh0YWcgPT09IDMpIHtcbiAgICB2YXIgbGF5ZXIgPSB7XG4gICAgICBrZXlzOiBbXSxcbiAgICAgIHZhbHVlczogW10sXG4gICAgICBmZWF0dXJlczogW11cbiAgICB9O1xuICAgIHZhciBlbmQgPSBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcztcbiAgICBwYmYucmVhZEZpZWxkcyhsYXllclBCRlJlYWRlciwgbGF5ZXIsIGVuZCk7XG4gICAgbGF5ZXIubGVuZ3RoID0gbGF5ZXIuZmVhdHVyZXMubGVuZ3RoO1xuXG4gICAgaWYgKGxheWVyLmxlbmd0aCkge1xuICAgICAgbGF5ZXJzW2xheWVyLm5hbWVdID0gbGF5ZXI7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIFJlYWRlciBjYWxsYmFjayBmb3IgcGFyc2luZyBsYXllci5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0YWcgVGhlIHRhZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBsYXllciBUaGUgbGF5ZXIgb2JqZWN0LlxuICogQHBhcmFtIHtQQkZ9IHBiZiBUaGUgUEJGLlxuICovXG5cblxuZnVuY3Rpb24gbGF5ZXJQQkZSZWFkZXIodGFnLCBsYXllciwgcGJmKSB7XG4gIGlmICh0YWcgPT09IDE1KSB7XG4gICAgbGF5ZXIudmVyc2lvbiA9IHBiZi5yZWFkVmFyaW50KCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSAxKSB7XG4gICAgbGF5ZXIubmFtZSA9IHBiZi5yZWFkU3RyaW5nKCk7XG4gIH0gZWxzZSBpZiAodGFnID09PSA1KSB7XG4gICAgbGF5ZXIuZXh0ZW50ID0gcGJmLnJlYWRWYXJpbnQoKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09IDIpIHtcbiAgICBsYXllci5mZWF0dXJlcy5wdXNoKHBiZi5wb3MpO1xuICB9IGVsc2UgaWYgKHRhZyA9PT0gMykge1xuICAgIGxheWVyLmtleXMucHVzaChwYmYucmVhZFN0cmluZygpKTtcbiAgfSBlbHNlIGlmICh0YWcgPT09IDQpIHtcbiAgICB2YXIgdmFsdWUgPSBudWxsO1xuICAgIHZhciBlbmQgPSBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcztcblxuICAgIHdoaWxlIChwYmYucG9zIDwgZW5kKSB7XG4gICAgICB0YWcgPSBwYmYucmVhZFZhcmludCgpID4+IDM7XG4gICAgICB2YWx1ZSA9IHRhZyA9PT0gMSA/IHBiZi5yZWFkU3RyaW5nKCkgOiB0YWcgPT09IDIgPyBwYmYucmVhZEZsb2F0KCkgOiB0YWcgPT09IDMgPyBwYmYucmVhZERvdWJsZSgpIDogdGFnID09PSA0ID8gcGJmLnJlYWRWYXJpbnQ2NCgpIDogdGFnID09PSA1ID8gcGJmLnJlYWRWYXJpbnQoKSA6IHRhZyA9PT0gNiA/IHBiZi5yZWFkU1ZhcmludCgpIDogdGFnID09PSA3ID8gcGJmLnJlYWRCb29sZWFuKCkgOiBudWxsO1xuICAgIH1cblxuICAgIGxheWVyLnZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgfVxufVxuLyoqXG4gKiBSZWFkZXIgY2FsbGJhY2sgZm9yIHBhcnNpbmcgZmVhdHVyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0YWcgVGhlIHRhZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBmZWF0dXJlIFRoZSBmZWF0dXJlIG9iamVjdC5cbiAqIEBwYXJhbSB7UEJGfSBwYmYgVGhlIFBCRi5cbiAqL1xuXG5cbmZ1bmN0aW9uIGZlYXR1cmVQQkZSZWFkZXIodGFnLCBmZWF0dXJlLCBwYmYpIHtcbiAgaWYgKHRhZyA9PSAxKSB7XG4gICAgZmVhdHVyZS5pZCA9IHBiZi5yZWFkVmFyaW50KCk7XG4gIH0gZWxzZSBpZiAodGFnID09IDIpIHtcbiAgICB2YXIgZW5kID0gcGJmLnJlYWRWYXJpbnQoKSArIHBiZi5wb3M7XG5cbiAgICB3aGlsZSAocGJmLnBvcyA8IGVuZCkge1xuICAgICAgdmFyIGtleSA9IGZlYXR1cmUubGF5ZXIua2V5c1twYmYucmVhZFZhcmludCgpXTtcbiAgICAgIHZhciB2YWx1ZSA9IGZlYXR1cmUubGF5ZXIudmFsdWVzW3BiZi5yZWFkVmFyaW50KCldO1xuICAgICAgZmVhdHVyZS5wcm9wZXJ0aWVzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGFnID09IDMpIHtcbiAgICBmZWF0dXJlLnR5cGUgPSBwYmYucmVhZFZhcmludCgpO1xuICB9IGVsc2UgaWYgKHRhZyA9PSA0KSB7XG4gICAgZmVhdHVyZS5nZW9tZXRyeSA9IHBiZi5wb3M7XG4gIH1cbn1cbi8qKlxuICogUmVhZCBhIHJhdyBmZWF0dXJlIGZyb20gdGhlIHBiZiBvZmZzZXQgc3RvcmVkIGF0IGluZGV4IGBpYCBpbiB0aGUgcmF3IGxheWVyLlxuICogQHBhcmFtIHtQQkZ9IHBiZiBQQkYuXG4gKiBAcGFyYW0ge09iamVjdH0gbGF5ZXIgUmF3IGxheWVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGkgSW5kZXggb2YgdGhlIGZlYXR1cmUgaW4gdGhlIHJhdyBsYXllcidzIGBmZWF0dXJlc2AgYXJyYXkuXG4gKiBAcmV0dXJuIHtPYmplY3R9IFJhdyBmZWF0dXJlLlxuICovXG5cblxuZnVuY3Rpb24gcmVhZFJhd0ZlYXR1cmUocGJmLCBsYXllciwgaSkge1xuICBwYmYucG9zID0gbGF5ZXIuZmVhdHVyZXNbaV07XG4gIHZhciBlbmQgPSBwYmYucmVhZFZhcmludCgpICsgcGJmLnBvcztcbiAgdmFyIGZlYXR1cmUgPSB7XG4gICAgbGF5ZXI6IGxheWVyLFxuICAgIHR5cGU6IDAsXG4gICAgcHJvcGVydGllczoge31cbiAgfTtcbiAgcGJmLnJlYWRGaWVsZHMoZmVhdHVyZVBCRlJlYWRlciwgZmVhdHVyZSwgZW5kKTtcbiAgcmV0dXJuIGZlYXR1cmU7XG59XG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB0eXBlIFRoZSByYXcgZmVhdHVyZSdzIGdlb21ldHJ5IHR5cGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1FbmRzIE51bWJlciBvZiBlbmRzIG9mIHRoZSBmbGF0IGNvb3JkaW5hdGVzIG9mIHRoZVxuICogZ2VvbWV0cnkuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9nZW9tL0dlb21ldHJ5VHlwZS5qc1wiKS5kZWZhdWx0fSBUaGUgZ2VvbWV0cnkgdHlwZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGdldEdlb21ldHJ5VHlwZSh0eXBlLCBudW1FbmRzKSB7XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZ2VvbS9HZW9tZXRyeVR5cGUuanNcIikuZGVmYXVsdH0gKi9cbiAgdmFyIGdlb21ldHJ5VHlwZTtcblxuICBpZiAodHlwZSA9PT0gMSkge1xuICAgIGdlb21ldHJ5VHlwZSA9IG51bUVuZHMgPT09IDEgPyBHZW9tZXRyeVR5cGUuUE9JTlQgOiBHZW9tZXRyeVR5cGUuTVVMVElfUE9JTlQ7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gMikge1xuICAgIGdlb21ldHJ5VHlwZSA9IG51bUVuZHMgPT09IDEgPyBHZW9tZXRyeVR5cGUuTElORV9TVFJJTkcgOiBHZW9tZXRyeVR5cGUuTVVMVElfTElORV9TVFJJTkc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gMykge1xuICAgIGdlb21ldHJ5VHlwZSA9IEdlb21ldHJ5VHlwZS5QT0xZR09OOyAvLyBNdWx0aVBvbHlnb24gbm90IHJlbGV2YW50IGZvciByZW5kZXJpbmcgLSB3aW5kaW5nIG9yZGVyIGRldGVybWluZXNcbiAgICAvLyBvdXRlciByaW5ncyBvZiBwb2x5Z29ucy5cbiAgfVxuXG4gIHJldHVybiBnZW9tZXRyeVR5cGU7XG59XG5cbmV4cG9ydCBkZWZhdWx0IE1WVDsiLCIvKipcbiAqIEBtb2R1bGUgb2wvbGF5ZXIvVGlsZVByb3BlcnR5XG4gKi9cblxuLyoqXG4gKiBAZW51bSB7c3RyaW5nfVxuICovXG5leHBvcnQgZGVmYXVsdCB7XG4gIFBSRUxPQUQ6ICdwcmVsb2FkJyxcbiAgVVNFX0lOVEVSSU1fVElMRVNfT05fRVJST1I6ICd1c2VJbnRlcmltVGlsZXNPbkVycm9yJ1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL0Jhc2VUaWxlXG4gKi9cblxuXG5pbXBvcnQgTGF5ZXIgZnJvbSAnLi9MYXllci5qcyc7XG5pbXBvcnQgVGlsZVByb3BlcnR5IGZyb20gJy4vVGlsZVByb3BlcnR5LmpzJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJy4uL29iai5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY2xhc3NOYW1lPSdvbC1sYXllciddIEEgQ1NTIGNsYXNzIG5hbWUgdG8gc2V0IHRvIHRoZSBsYXllciBlbGVtZW50LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtvcGFjaXR5PTFdIE9wYWNpdHkgKDAsIDEpLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdmlzaWJsZT10cnVlXSBWaXNpYmlsaXR5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBUaGUgYm91bmRpbmcgZXh0ZW50IGZvciBsYXllciByZW5kZXJpbmcuICBUaGUgbGF5ZXIgd2lsbCBub3QgYmVcbiAqIHJlbmRlcmVkIG91dHNpZGUgb2YgdGhpcyBleHRlbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pJbmRleF0gVGhlIHotaW5kZXggZm9yIGxheWVyIHJlbmRlcmluZy4gIEF0IHJlbmRlcmluZyB0aW1lLCB0aGUgbGF5ZXJzXG4gKiB3aWxsIGJlIG9yZGVyZWQsIGZpcnN0IGJ5IFotaW5kZXggYW5kIHRoZW4gYnkgcG9zaXRpb24uIFdoZW4gYHVuZGVmaW5lZGAsIGEgYHpJbmRleGAgb2YgMCBpcyBhc3N1bWVkXG4gKiBmb3IgbGF5ZXJzIHRoYXQgYXJlIGFkZGVkIHRvIHRoZSBtYXAncyBgbGF5ZXJzYCBjb2xsZWN0aW9uLCBvciBgSW5maW5pdHlgIHdoZW4gdGhlIGxheWVyJ3MgYHNldE1hcCgpYFxuICogbWV0aG9kIHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttaW5SZXNvbHV0aW9uXSBUaGUgbWluaW11bSByZXNvbHV0aW9uIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4UmVzb2x1dGlvbl0gVGhlIG1heGltdW0gcmVzb2x1dGlvbiAoZXhjbHVzaXZlKSBiZWxvdyB3aGljaCB0aGlzIGxheWVyIHdpbGxcbiAqIGJlIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblpvb21dIFRoZSBtaW5pbXVtIHZpZXcgem9vbSBsZXZlbCAoZXhjbHVzaXZlKSBhYm92ZSB3aGljaCB0aGlzIGxheWVyIHdpbGwgYmVcbiAqIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21heFpvb21dIFRoZSBtYXhpbXVtIHZpZXcgem9vbSBsZXZlbCAoaW5jbHVzaXZlKSBhdCB3aGljaCB0aGlzIGxheWVyIHdpbGxcbiAqIGJlIHZpc2libGUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3ByZWxvYWQ9MF0gUHJlbG9hZC4gTG9hZCBsb3ctcmVzb2x1dGlvbiB0aWxlcyB1cCB0byBgcHJlbG9hZGAgbGV2ZWxzLiBgMGBcbiAqIG1lYW5zIG5vIHByZWxvYWRpbmcuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NvdXJjZS9UaWxlLmpzXCIpLmRlZmF1bHR9IFtzb3VyY2VdIFNvdXJjZSBmb3IgdGhpcyBsYXllci5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IFttYXBdIFNldHMgdGhlIGxheWVyIGFzIG92ZXJsYXkgb24gYSBtYXAuIFRoZSBtYXAgd2lsbCBub3QgbWFuYWdlXG4gKiB0aGlzIGxheWVyIGluIGl0cyBsYXllcnMgY29sbGVjdGlvbiwgYW5kIHRoZSBsYXllciB3aWxsIGJlIHJlbmRlcmVkIG9uIHRvcC4gVGhpcyBpcyB1c2VmdWwgZm9yXG4gKiB0ZW1wb3JhcnkgbGF5ZXJzLiBUaGUgc3RhbmRhcmQgd2F5IHRvIGFkZCBhIGxheWVyIHRvIGEgbWFwIGFuZCBoYXZlIGl0IG1hbmFnZWQgYnkgdGhlIG1hcCBpcyB0b1xuICogdXNlIHtAbGluayBtb2R1bGU6b2wvTWFwI2FkZExheWVyfS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VzZUludGVyaW1UaWxlc09uRXJyb3I9dHJ1ZV0gVXNlIGludGVyaW0gdGlsZXMgb24gZXJyb3IuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBGb3IgbGF5ZXIgc291cmNlcyB0aGF0IHByb3ZpZGUgcHJlLXJlbmRlcmVkLCB0aWxlZCBpbWFnZXMgaW4gZ3JpZHMgdGhhdCBhcmVcbiAqIG9yZ2FuaXplZCBieSB6b29tIGxldmVscyBmb3Igc3BlY2lmaWMgcmVzb2x1dGlvbnMuXG4gKiBOb3RlIHRoYXQgYW55IHByb3BlcnR5IHNldCBpbiB0aGUgb3B0aW9ucyBpcyBzZXQgYXMgYSB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH5CYXNlT2JqZWN0fVxuICogcHJvcGVydHkgb24gdGhlIGxheWVyIG9iamVjdDsgZm9yIGV4YW1wbGUsIHNldHRpbmcgYHRpdGxlOiAnTXkgVGl0bGUnYCBpbiB0aGVcbiAqIG9wdGlvbnMgbWVhbnMgdGhhdCBgdGl0bGVgIGlzIG9ic2VydmFibGUsIGFuZCBoYXMgZ2V0L3NldCBhY2Nlc3NvcnMuXG4gKlxuICogQGV4dGVuZHMge0xheWVyPGltcG9ydChcIi4uL3NvdXJjZS9UaWxlLmpzXCIpLmRlZmF1bHQ+fVxuICogQGFwaVxuICovXG5cbnZhciBCYXNlVGlsZUxheWVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKEJhc2VUaWxlTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBUaWxlIGxheWVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQmFzZVRpbGVMYXllcihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgYmFzZU9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMpO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy5wcmVsb2FkO1xuICAgIGRlbGV0ZSBiYXNlT3B0aW9ucy51c2VJbnRlcmltVGlsZXNPbkVycm9yO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgYmFzZU9wdGlvbnMpIHx8IHRoaXM7XG5cbiAgICBfdGhpcy5zZXRQcmVsb2FkKG9wdGlvbnMucHJlbG9hZCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5wcmVsb2FkIDogMCk7XG5cbiAgICBfdGhpcy5zZXRVc2VJbnRlcmltVGlsZXNPbkVycm9yKG9wdGlvbnMudXNlSW50ZXJpbVRpbGVzT25FcnJvciAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy51c2VJbnRlcmltVGlsZXNPbkVycm9yIDogdHJ1ZSk7XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGV2ZWwgYXMgbnVtYmVyIHRvIHdoaWNoIHdlIHdpbGwgcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbGV2ZWwgdG8gcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VUaWxlTGF5ZXIucHJvdG90eXBlLmdldFByZWxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgdGhpcy5nZXQoVGlsZVByb3BlcnR5LlBSRUxPQUQpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgbGV2ZWwgYXMgbnVtYmVyIHRvIHdoaWNoIHdlIHdpbGwgcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHByZWxvYWQgVGhlIGxldmVsIHRvIHByZWxvYWQgdGlsZXMgdXAgdG8uXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBCYXNlVGlsZUxheWVyLnByb3RvdHlwZS5zZXRQcmVsb2FkID0gZnVuY3Rpb24gKHByZWxvYWQpIHtcbiAgICB0aGlzLnNldChUaWxlUHJvcGVydHkuUFJFTE9BRCwgcHJlbG9hZCk7XG4gIH07XG4gIC8qKlxuICAgKiBXaGV0aGVyIHdlIHVzZSBpbnRlcmltIHRpbGVzIG9uIGVycm9yLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VUaWxlTGF5ZXIucHJvdG90eXBlLmdldFVzZUludGVyaW1UaWxlc09uRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgIHRoaXMuZ2V0KFRpbGVQcm9wZXJ0eS5VU0VfSU5URVJJTV9USUxFU19PTl9FUlJPUilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHdoZXRoZXIgd2UgdXNlIGludGVyaW0gdGlsZXMgb24gZXJyb3IuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlSW50ZXJpbVRpbGVzT25FcnJvciBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEJhc2VUaWxlTGF5ZXIucHJvdG90eXBlLnNldFVzZUludGVyaW1UaWxlc09uRXJyb3IgPSBmdW5jdGlvbiAodXNlSW50ZXJpbVRpbGVzT25FcnJvcikge1xuICAgIHRoaXMuc2V0KFRpbGVQcm9wZXJ0eS5VU0VfSU5URVJJTV9USUxFU19PTl9FUlJPUiwgdXNlSW50ZXJpbVRpbGVzT25FcnJvcik7XG4gIH07XG5cbiAgcmV0dXJuIEJhc2VUaWxlTGF5ZXI7XG59KExheWVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQmFzZVRpbGVMYXllcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlbmRlcmVyL2NhbnZhcy9UaWxlTGF5ZXJcbiAqL1xuXG5cbmltcG9ydCBDYW52YXNMYXllclJlbmRlcmVyIGZyb20gJy4vTGF5ZXIuanMnO1xuaW1wb3J0IFRpbGVSYW5nZSBmcm9tICcuLi8uLi9UaWxlUmFuZ2UuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuLi8uLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IHsgYXBwbHkgYXMgYXBwbHlUcmFuc2Zvcm0sIGNvbXBvc2UgYXMgY29tcG9zZVRyYW5zZm9ybSwgbWFrZUludmVyc2UgfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi4vLi4vb2JqLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVtcHR5LCBlcXVhbHMsIGdldEludGVyc2VjdGlvbiwgZ2V0VG9wTGVmdCB9IGZyb20gJy4uLy4uL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjcmVhdGVUcmFuc2Zvcm1TdHJpbmcgfSBmcm9tICcuLi8uLi9yZW5kZXIvY2FudmFzLmpzJztcbmltcG9ydCB7IGZyb21Vc2VyRXh0ZW50IH0gZnJvbSAnLi4vLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuLi8uLi91dGlsLmpzJztcbmltcG9ydCB7IG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24gfSBmcm9tICcuLi8uLi9hcnJheS5qcyc7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENhbnZhcyByZW5kZXJlciBmb3IgdGlsZSBsYXllcnMuXG4gKiBAYXBpXG4gKi9cblxudmFyIENhbnZhc1RpbGVMYXllclJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc1RpbGVMYXllclJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9sYXllci9UaWxlLmpzXCIpLmRlZmF1bHR8aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlTGF5ZXIgVGlsZSBsYXllci5cbiAgICovXG5cblxuICBmdW5jdGlvbiBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlcih0aWxlTGF5ZXIpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlTGF5ZXIpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogUmVuZGVyZWQgZXh0ZW50IGhhcyBjaGFuZ2VkIHNpbmNlIHRoZSBwcmV2aW91cyBgcmVuZGVyRnJhbWUoKWAgY2FsbFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5leHRlbnRDaGFuZ2VkID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkRXh0ZW50XyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFBpeGVsUmF0aW87XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlbmRlcmVkUHJvamVjdGlvbiA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFJldmlzaW9uO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7IUFycmF5PGltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdD59XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFRpbGVzID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIF90aGlzLm5ld1RpbGVzXyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcEV4dGVudCA9IGNyZWF0ZUVtcHR5KCk7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50bXBUaWxlUmFuZ2VfID0gbmV3IFRpbGVSYW5nZSgwLCAwLCAwLCAwKTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGlsZSBpcyBkcmF3YWJsZS5cbiAgICovXG5cblxuICBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaXNEcmF3YWJsZVRpbGUgPSBmdW5jdGlvbiAodGlsZSkge1xuICAgIHZhciB0aWxlTGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG4gICAgdmFyIHRpbGVTdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcbiAgICB2YXIgdXNlSW50ZXJpbVRpbGVzT25FcnJvciA9IHRpbGVMYXllci5nZXRVc2VJbnRlcmltVGlsZXNPbkVycm9yKCk7XG4gICAgcmV0dXJuIHRpbGVTdGF0ZSA9PSBUaWxlU3RhdGUuTE9BREVEIHx8IHRpbGVTdGF0ZSA9PSBUaWxlU3RhdGUuRU1QVFkgfHwgdGlsZVN0YXRlID09IFRpbGVTdGF0ZS5FUlJPUiAmJiAhdXNlSW50ZXJpbVRpbGVzT25FcnJvcjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFRpbGUgY29vcmRpbmF0ZSB6LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHR9IFRpbGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldFRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSwgZnJhbWVTdGF0ZSkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciBwcm9qZWN0aW9uID0gZnJhbWVTdGF0ZS52aWV3U3RhdGUucHJvamVjdGlvbjtcbiAgICB2YXIgdGlsZUxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciB0aWxlU291cmNlID0gdGlsZUxheWVyLmdldFNvdXJjZSgpO1xuICAgIHZhciB0aWxlID0gdGlsZVNvdXJjZS5nZXRUaWxlKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuRVJST1IpIHtcbiAgICAgIGlmICghdGlsZUxheWVyLmdldFVzZUludGVyaW1UaWxlc09uRXJyb3IoKSkge1xuICAgICAgICAvLyBXaGVuIHVzZUludGVyaW1UaWxlc09uRXJyb3IgaXMgZmFsc2UsIHdlIGNvbnNpZGVyIHRoZSBlcnJvciB0aWxlIGFzIGxvYWRlZC5cbiAgICAgICAgdGlsZS5zZXRTdGF0ZShUaWxlU3RhdGUuTE9BREVEKTtcbiAgICAgIH0gZWxzZSBpZiAodGlsZUxheWVyLmdldFByZWxvYWQoKSA+IDApIHtcbiAgICAgICAgLy8gUHJlbG9hZGVkIHRpbGVzIGZvciBsb3dlciByZXNvbHV0aW9ucyBtaWdodCBoYXZlIGZpbmlzaGVkIGxvYWRpbmcuXG4gICAgICAgIHRoaXMubmV3VGlsZXNfID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaXNEcmF3YWJsZVRpbGUodGlsZSkpIHtcbiAgICAgIHRpbGUgPSB0aWxlLmdldEludGVyaW1UaWxlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRpbGU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdDxudW1iZXIsIE9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uLy4uL1RpbGUuanNcIikuZGVmYXVsdD4+fSB0aWxlcyBMb29rdXAgb2YgbG9hZGVkIHRpbGVzIGJ5IHpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6b29tIFpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW58dm9pZH0gSWYgYGZhbHNlYCwgdGhlIHRpbGUgd2lsbCBub3QgYmUgY29uc2lkZXJlZCBsb2FkZWQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmxvYWRlZFRpbGVDYWxsYmFjayA9IGZ1bmN0aW9uICh0aWxlcywgem9vbSwgdGlsZSkge1xuICAgIGlmICh0aGlzLmlzRHJhd2FibGVUaWxlKHRpbGUpKSB7XG4gICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5sb2FkZWRUaWxlQ2FsbGJhY2suY2FsbCh0aGlzLCB0aWxlcywgem9vbSwgdGlsZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgcmVuZGVyIHNob3VsZCBiZSBjYWxsZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IExheWVyIGlzIHJlYWR5IHRvIGJlIHJlbmRlcmVkLlxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5wcmVwYXJlRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHJldHVybiAhIXRoaXMuZ2V0TGF5ZXIoKS5nZXRTb3VyY2UoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbmRlciB0aGUgbGF5ZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHRhcmdldCBUYXJnZXQgdGhhdCBtYXkgYmUgdXNlZCB0byByZW5kZXIgY29udGVudCB0by5cbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSByZW5kZXJlZCBlbGVtZW50LlxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0YXJnZXQpIHtcbiAgICB2YXIgbGF5ZXJTdGF0ZSA9IGZyYW1lU3RhdGUubGF5ZXJTdGF0ZXNBcnJheVtmcmFtZVN0YXRlLmxheWVySW5kZXhdO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgcHJvamVjdGlvbiA9IHZpZXdTdGF0ZS5wcm9qZWN0aW9uO1xuICAgIHZhciB2aWV3UmVzb2x1dGlvbiA9IHZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciB2aWV3Q2VudGVyID0gdmlld1N0YXRlLmNlbnRlcjtcbiAgICB2YXIgcm90YXRpb24gPSB2aWV3U3RhdGUucm90YXRpb247XG4gICAgdmFyIHBpeGVsUmF0aW8gPSBmcmFtZVN0YXRlLnBpeGVsUmF0aW87XG4gICAgdmFyIHRpbGVMYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgdGlsZVNvdXJjZSA9IHRpbGVMYXllci5nZXRTb3VyY2UoKTtcbiAgICB2YXIgc291cmNlUmV2aXNpb24gPSB0aWxlU291cmNlLmdldFJldmlzaW9uKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gdGlsZVNvdXJjZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdmFyIHogPSB0aWxlR3JpZC5nZXRaRm9yUmVzb2x1dGlvbih2aWV3UmVzb2x1dGlvbiwgdGlsZVNvdXJjZS56RGlyZWN0aW9uKTtcbiAgICB2YXIgdGlsZVJlc29sdXRpb24gPSB0aWxlR3JpZC5nZXRSZXNvbHV0aW9uKHopO1xuICAgIHZhciBleHRlbnQgPSBmcmFtZVN0YXRlLmV4dGVudDtcbiAgICB2YXIgbGF5ZXJFeHRlbnQgPSBsYXllclN0YXRlLmV4dGVudCAmJiBmcm9tVXNlckV4dGVudChsYXllclN0YXRlLmV4dGVudCwgcHJvamVjdGlvbik7XG5cbiAgICBpZiAobGF5ZXJFeHRlbnQpIHtcbiAgICAgIGV4dGVudCA9IGdldEludGVyc2VjdGlvbihleHRlbnQsIGZyb21Vc2VyRXh0ZW50KGxheWVyU3RhdGUuZXh0ZW50LCBwcm9qZWN0aW9uKSk7XG4gICAgfVxuXG4gICAgdmFyIHRpbGVQaXhlbFJhdGlvID0gdGlsZVNvdXJjZS5nZXRUaWxlUGl4ZWxSYXRpbyhwaXhlbFJhdGlvKTsgLy8gZGVzaXJlZCBkaW1lbnNpb25zIG9mIHRoZSBjYW52YXMgaW4gcGl4ZWxzXG5cbiAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKGZyYW1lU3RhdGUuc2l6ZVswXSAqIHRpbGVQaXhlbFJhdGlvKTtcbiAgICB2YXIgaGVpZ2h0ID0gTWF0aC5yb3VuZChmcmFtZVN0YXRlLnNpemVbMV0gKiB0aWxlUGl4ZWxSYXRpbyk7XG5cbiAgICBpZiAocm90YXRpb24pIHtcbiAgICAgIHZhciBzaXplID0gTWF0aC5yb3VuZChNYXRoLnNxcnQod2lkdGggKiB3aWR0aCArIGhlaWdodCAqIGhlaWdodCkpO1xuICAgICAgd2lkdGggPSBzaXplO1xuICAgICAgaGVpZ2h0ID0gc2l6ZTtcbiAgICB9XG5cbiAgICB2YXIgZHggPSB0aWxlUmVzb2x1dGlvbiAqIHdpZHRoIC8gMiAvIHRpbGVQaXhlbFJhdGlvO1xuICAgIHZhciBkeSA9IHRpbGVSZXNvbHV0aW9uICogaGVpZ2h0IC8gMiAvIHRpbGVQaXhlbFJhdGlvO1xuICAgIHZhciBjYW52YXNFeHRlbnQgPSBbdmlld0NlbnRlclswXSAtIGR4LCB2aWV3Q2VudGVyWzFdIC0gZHksIHZpZXdDZW50ZXJbMF0gKyBkeCwgdmlld0NlbnRlclsxXSArIGR5XTtcbiAgICB2YXIgdGlsZVJhbmdlID0gdGlsZUdyaWQuZ2V0VGlsZVJhbmdlRm9yRXh0ZW50QW5kWihleHRlbnQsIHopO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3Q8bnVtYmVyLCBPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICAgKi9cblxuICAgIHZhciB0aWxlc1RvRHJhd0J5WiA9IHt9O1xuICAgIHRpbGVzVG9EcmF3QnlaW3pdID0ge307XG4gICAgdmFyIGZpbmRMb2FkZWRUaWxlcyA9IHRoaXMuY3JlYXRlTG9hZGVkVGlsZUZpbmRlcih0aWxlU291cmNlLCBwcm9qZWN0aW9uLCB0aWxlc1RvRHJhd0J5Wik7XG4gICAgdmFyIHRtcEV4dGVudCA9IHRoaXMudG1wRXh0ZW50O1xuICAgIHZhciB0bXBUaWxlUmFuZ2UgPSB0aGlzLnRtcFRpbGVSYW5nZV87XG4gICAgdGhpcy5uZXdUaWxlc18gPSBmYWxzZTtcblxuICAgIGZvciAodmFyIHggPSB0aWxlUmFuZ2UubWluWDsgeCA8PSB0aWxlUmFuZ2UubWF4WDsgKyt4KSB7XG4gICAgICBmb3IgKHZhciB5ID0gdGlsZVJhbmdlLm1pblk7IHkgPD0gdGlsZVJhbmdlLm1heFk7ICsreSkge1xuICAgICAgICB2YXIgdGlsZSA9IHRoaXMuZ2V0VGlsZSh6LCB4LCB5LCBmcmFtZVN0YXRlKTtcblxuICAgICAgICBpZiAodGhpcy5pc0RyYXdhYmxlVGlsZSh0aWxlKSkge1xuICAgICAgICAgIHZhciB1aWQgPSBnZXRVaWQodGhpcyk7XG5cbiAgICAgICAgICBpZiAodGlsZS5nZXRTdGF0ZSgpID09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgICAgIHRpbGVzVG9EcmF3QnlaW3pdW3RpbGUudGlsZUNvb3JkLnRvU3RyaW5nKCldID0gdGlsZTtcbiAgICAgICAgICAgIHZhciBpblRyYW5zaXRpb24gPSB0aWxlLmluVHJhbnNpdGlvbih1aWQpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMubmV3VGlsZXNfICYmIChpblRyYW5zaXRpb24gfHwgdGhpcy5yZW5kZXJlZFRpbGVzLmluZGV4T2YodGlsZSkgPT09IC0xKSkge1xuICAgICAgICAgICAgICB0aGlzLm5ld1RpbGVzXyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRpbGUuZ2V0QWxwaGEodWlkLCBmcmFtZVN0YXRlLnRpbWUpID09PSAxKSB7XG4gICAgICAgICAgICAvLyBkb24ndCBsb29rIGZvciBhbHQgdGlsZXMgaWYgYWxwaGEgaXMgMVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNoaWxkVGlsZVJhbmdlID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkQ2hpbGRUaWxlUmFuZ2UodGlsZS50aWxlQ29vcmQsIHRtcFRpbGVSYW5nZSwgdG1wRXh0ZW50KTtcbiAgICAgICAgdmFyIGNvdmVyZWQgPSBmYWxzZTtcblxuICAgICAgICBpZiAoY2hpbGRUaWxlUmFuZ2UpIHtcbiAgICAgICAgICBjb3ZlcmVkID0gZmluZExvYWRlZFRpbGVzKHogKyAxLCBjaGlsZFRpbGVSYW5nZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNvdmVyZWQpIHtcbiAgICAgICAgICB0aWxlR3JpZC5mb3JFYWNoVGlsZUNvb3JkUGFyZW50VGlsZVJhbmdlKHRpbGUudGlsZUNvb3JkLCBmaW5kTG9hZGVkVGlsZXMsIHRtcFRpbGVSYW5nZSwgdG1wRXh0ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBjYW52YXNTY2FsZSA9IHRpbGVSZXNvbHV0aW9uIC8gdmlld1Jlc29sdXRpb247IC8vIHNldCBmb3J3YXJkIGFuZCBpbnZlcnNlIHBpeGVsIHRyYW5zZm9ybXNcblxuICAgIGNvbXBvc2VUcmFuc2Zvcm0odGhpcy5waXhlbFRyYW5zZm9ybSwgZnJhbWVTdGF0ZS5zaXplWzBdIC8gMiwgZnJhbWVTdGF0ZS5zaXplWzFdIC8gMiwgMSAvIHRpbGVQaXhlbFJhdGlvLCAxIC8gdGlsZVBpeGVsUmF0aW8sIHJvdGF0aW9uLCAtd2lkdGggLyAyLCAtaGVpZ2h0IC8gMik7XG4gICAgdmFyIGNhbnZhc1RyYW5zZm9ybSA9IGNyZWF0ZVRyYW5zZm9ybVN0cmluZyh0aGlzLnBpeGVsVHJhbnNmb3JtKTtcbiAgICB0aGlzLnVzZUNvbnRhaW5lcih0YXJnZXQsIGNhbnZhc1RyYW5zZm9ybSwgbGF5ZXJTdGF0ZS5vcGFjaXR5KTtcbiAgICB2YXIgY29udGV4dCA9IHRoaXMuY29udGV4dDtcbiAgICB2YXIgY2FudmFzID0gY29udGV4dC5jYW52YXM7XG4gICAgbWFrZUludmVyc2UodGhpcy5pbnZlcnNlUGl4ZWxUcmFuc2Zvcm0sIHRoaXMucGl4ZWxUcmFuc2Zvcm0pOyAvLyBzZXQgc2NhbGUgdHJhbnNmb3JtIGZvciBjYWxjdWxhdGluZyB0aWxlIHBvc2l0aW9ucyBvbiB0aGUgY2FudmFzXG5cbiAgICBjb21wb3NlVHJhbnNmb3JtKHRoaXMudGVtcFRyYW5zZm9ybSwgd2lkdGggLyAyLCBoZWlnaHQgLyAyLCBjYW52YXNTY2FsZSwgY2FudmFzU2NhbGUsIDAsIC13aWR0aCAvIDIsIC1oZWlnaHQgLyAyKTtcblxuICAgIGlmIChjYW52YXMud2lkdGggIT0gd2lkdGggfHwgY2FudmFzLmhlaWdodCAhPSBoZWlnaHQpIHtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgY2FudmFzLmhlaWdodCA9IGhlaWdodDtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLmNvbnRhaW5lclJldXNlZCkge1xuICAgICAgY29udGV4dC5jbGVhclJlY3QoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgfVxuXG4gICAgaWYgKGxheWVyRXh0ZW50KSB7XG4gICAgICB0aGlzLmNsaXBVbnJvdGF0ZWQoY29udGV4dCwgZnJhbWVTdGF0ZSwgbGF5ZXJFeHRlbnQpO1xuICAgIH1cblxuICAgIGFzc2lnbihjb250ZXh0LCB0aWxlU291cmNlLmdldENvbnRleHRPcHRpb25zKCkpO1xuICAgIHRoaXMucHJlUmVuZGVyKGNvbnRleHQsIGZyYW1lU3RhdGUpO1xuICAgIHRoaXMucmVuZGVyZWRUaWxlcy5sZW5ndGggPSAwO1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyPn0gKi9cblxuICAgIHZhciB6cyA9IE9iamVjdC5rZXlzKHRpbGVzVG9EcmF3QnlaKS5tYXAoTnVtYmVyKTtcbiAgICB6cy5zb3J0KG51bWJlclNhZmVDb21wYXJlRnVuY3Rpb24pO1xuICAgIHZhciBjbGlwcywgY2xpcFpzLCBjdXJyZW50Q2xpcDtcblxuICAgIGlmIChsYXllclN0YXRlLm9wYWNpdHkgPT09IDEgJiYgKCF0aGlzLmNvbnRhaW5lclJldXNlZCB8fCB0aWxlU291cmNlLmdldE9wYXF1ZShmcmFtZVN0YXRlLnZpZXdTdGF0ZS5wcm9qZWN0aW9uKSkpIHtcbiAgICAgIHpzID0genMucmV2ZXJzZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbGlwcyA9IFtdO1xuICAgICAgY2xpcFpzID0gW107XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IHpzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB2YXIgY3VycmVudFogPSB6c1tpXTtcbiAgICAgIHZhciBjdXJyZW50VGlsZVBpeGVsU2l6ZSA9IHRpbGVTb3VyY2UuZ2V0VGlsZVBpeGVsU2l6ZShjdXJyZW50WiwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbik7XG4gICAgICB2YXIgY3VycmVudFJlc29sdXRpb24gPSB0aWxlR3JpZC5nZXRSZXNvbHV0aW9uKGN1cnJlbnRaKTtcbiAgICAgIHZhciBjdXJyZW50U2NhbGUgPSBjdXJyZW50UmVzb2x1dGlvbiAvIHRpbGVSZXNvbHV0aW9uO1xuICAgICAgdmFyIGR4XzEgPSBjdXJyZW50VGlsZVBpeGVsU2l6ZVswXSAqIGN1cnJlbnRTY2FsZSAqIGNhbnZhc1NjYWxlO1xuICAgICAgdmFyIGR5XzEgPSBjdXJyZW50VGlsZVBpeGVsU2l6ZVsxXSAqIGN1cnJlbnRTY2FsZSAqIGNhbnZhc1NjYWxlO1xuICAgICAgdmFyIG9yaWdpblRpbGVDb29yZCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEZvckNvb3JkQW5kWihnZXRUb3BMZWZ0KGNhbnZhc0V4dGVudCksIGN1cnJlbnRaKTtcbiAgICAgIHZhciBvcmlnaW5UaWxlRXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KG9yaWdpblRpbGVDb29yZCk7XG4gICAgICB2YXIgb3JpZ2luXzEgPSBhcHBseVRyYW5zZm9ybSh0aGlzLnRlbXBUcmFuc2Zvcm0sIFt0aWxlUGl4ZWxSYXRpbyAqIChvcmlnaW5UaWxlRXh0ZW50WzBdIC0gY2FudmFzRXh0ZW50WzBdKSAvIHRpbGVSZXNvbHV0aW9uLCB0aWxlUGl4ZWxSYXRpbyAqIChjYW52YXNFeHRlbnRbM10gLSBvcmlnaW5UaWxlRXh0ZW50WzNdKSAvIHRpbGVSZXNvbHV0aW9uXSk7XG4gICAgICB2YXIgdGlsZUd1dHRlciA9IHRpbGVQaXhlbFJhdGlvICogdGlsZVNvdXJjZS5nZXRHdXR0ZXJGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgICAgdmFyIHRpbGVzVG9EcmF3ID0gdGlsZXNUb0RyYXdCeVpbY3VycmVudFpdO1xuXG4gICAgICBmb3IgKHZhciB0aWxlQ29vcmRLZXkgaW4gdGlsZXNUb0RyYXcpIHtcbiAgICAgICAgdmFyIHRpbGUgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL0ltYWdlVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICB0aWxlc1RvRHJhd1t0aWxlQ29vcmRLZXldO1xuICAgICAgICB2YXIgdGlsZUNvb3JkID0gdGlsZS50aWxlQ29vcmQ7IC8vIENhbGN1bGF0ZSBpbnRlZ2VyIHBvc2l0aW9ucyBhbmQgc2l6ZXMgc28gdGhhdCB0aWxlcyBhbGlnblxuXG4gICAgICAgIHZhciBmbG9hdFggPSBvcmlnaW5fMVswXSAtIChvcmlnaW5UaWxlQ29vcmRbMV0gLSB0aWxlQ29vcmRbMV0pICogZHhfMTtcbiAgICAgICAgdmFyIG5leHRYID0gTWF0aC5yb3VuZChmbG9hdFggKyBkeF8xKTtcbiAgICAgICAgdmFyIGZsb2F0WSA9IG9yaWdpbl8xWzFdIC0gKG9yaWdpblRpbGVDb29yZFsyXSAtIHRpbGVDb29yZFsyXSkgKiBkeV8xO1xuICAgICAgICB2YXIgbmV4dFkgPSBNYXRoLnJvdW5kKGZsb2F0WSArIGR5XzEpO1xuICAgICAgICB2YXIgeCA9IE1hdGgucm91bmQoZmxvYXRYKTtcbiAgICAgICAgdmFyIHkgPSBNYXRoLnJvdW5kKGZsb2F0WSk7XG4gICAgICAgIHZhciB3ID0gbmV4dFggLSB4O1xuICAgICAgICB2YXIgaCA9IG5leHRZIC0geTtcbiAgICAgICAgdmFyIHRyYW5zaXRpb24gPSB6ID09PSBjdXJyZW50WjtcbiAgICAgICAgdmFyIGluVHJhbnNpdGlvbiA9IHRyYW5zaXRpb24gJiYgdGlsZS5nZXRBbHBoYShnZXRVaWQodGhpcyksIGZyYW1lU3RhdGUudGltZSkgIT09IDE7XG5cbiAgICAgICAgaWYgKCFpblRyYW5zaXRpb24pIHtcbiAgICAgICAgICBpZiAoY2xpcHMpIHtcbiAgICAgICAgICAgIC8vIENsaXAgbWFzayBmb3IgcmVnaW9ucyBpbiB0aGlzIHRpbGUgdGhhdCBhbHJlYWR5IGZpbGxlZCBieSBhIGhpZ2hlciB6IHRpbGVcbiAgICAgICAgICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgICAgICAgICAgY3VycmVudENsaXAgPSBbeCwgeSwgeCArIHcsIHksIHggKyB3LCB5ICsgaCwgeCwgeSArIGhdO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpXzEgPSAwLCBpaSA9IGNsaXBzLmxlbmd0aDsgaV8xIDwgaWk7ICsraV8xKSB7XG4gICAgICAgICAgICAgIGlmICh6ICE9PSBjdXJyZW50WiAmJiBjdXJyZW50WiA8IGNsaXBac1tpXzFdKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNsaXAgPSBjbGlwc1tpXzFdO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7IC8vIGNvdW50ZXItY2xvY2t3aXNlIChvdXRlciByaW5nKSBmb3IgY3VycmVudCB0aWxlXG5cbiAgICAgICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyhjdXJyZW50Q2xpcFswXSwgY3VycmVudENsaXBbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGN1cnJlbnRDbGlwWzJdLCBjdXJyZW50Q2xpcFszXSk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8oY3VycmVudENsaXBbNF0sIGN1cnJlbnRDbGlwWzVdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjdXJyZW50Q2xpcFs2XSwgY3VycmVudENsaXBbN10pOyAvLyBjbG9ja3dpc2UgKGlubmVyIHJpbmcpIGZvciBoaWdoZXIgeiB0aWxlXG5cbiAgICAgICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyhjbGlwWzZdLCBjbGlwWzddKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzRdLCBjbGlwWzVdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzJdLCBjbGlwWzNdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzBdLCBjbGlwWzFdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmNsaXAoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjbGlwcy5wdXNoKGN1cnJlbnRDbGlwKTtcbiAgICAgICAgICAgIGNsaXBacy5wdXNoKGN1cnJlbnRaKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGV4dC5jbGVhclJlY3QoeCwgeSwgdywgaCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kcmF3VGlsZUltYWdlKHRpbGUsIGZyYW1lU3RhdGUsIHgsIHksIHcsIGgsIHRpbGVHdXR0ZXIsIHRyYW5zaXRpb24sIGxheWVyU3RhdGUub3BhY2l0eSk7XG5cbiAgICAgICAgaWYgKGNsaXBzICYmICFpblRyYW5zaXRpb24pIHtcbiAgICAgICAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVuZGVyZWRUaWxlcy5wdXNoKHRpbGUpO1xuICAgICAgICB0aGlzLnVwZGF0ZVVzZWRUaWxlcyhmcmFtZVN0YXRlLnVzZWRUaWxlcywgdGlsZVNvdXJjZSwgdGlsZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJlZFJldmlzaW9uID0gc291cmNlUmV2aXNpb247XG4gICAgdGhpcy5yZW5kZXJlZFJlc29sdXRpb24gPSB0aWxlUmVzb2x1dGlvbjtcbiAgICB0aGlzLmV4dGVudENoYW5nZWQgPSAhdGhpcy5yZW5kZXJlZEV4dGVudF8gfHwgIWVxdWFscyh0aGlzLnJlbmRlcmVkRXh0ZW50XywgY2FudmFzRXh0ZW50KTtcbiAgICB0aGlzLnJlbmRlcmVkRXh0ZW50XyA9IGNhbnZhc0V4dGVudDtcbiAgICB0aGlzLnJlbmRlcmVkUGl4ZWxSYXRpbyA9IHBpeGVsUmF0aW87XG4gICAgdGhpcy5yZW5kZXJlZFByb2plY3Rpb24gPSBwcm9qZWN0aW9uO1xuICAgIHRoaXMubWFuYWdlVGlsZVB5cmFtaWQoZnJhbWVTdGF0ZSwgdGlsZVNvdXJjZSwgdGlsZUdyaWQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIGV4dGVudCwgeiwgdGlsZUxheWVyLmdldFByZWxvYWQoKSk7XG4gICAgdGhpcy5zY2hlZHVsZUV4cGlyZUNhY2hlKGZyYW1lU3RhdGUsIHRpbGVTb3VyY2UpO1xuICAgIHRoaXMucG9zdFJlbmRlcihjb250ZXh0LCBmcmFtZVN0YXRlKTtcblxuICAgIGlmIChsYXllclN0YXRlLmV4dGVudCkge1xuICAgICAgY29udGV4dC5yZXN0b3JlKCk7XG4gICAgfVxuXG4gICAgaWYgKGNhbnZhc1RyYW5zZm9ybSAhPT0gY2FudmFzLnN0eWxlLnRyYW5zZm9ybSkge1xuICAgICAgY2FudmFzLnN0eWxlLnRyYW5zZm9ybSA9IGNhbnZhc1RyYW5zZm9ybTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb250YWluZXI7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL0ltYWdlVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRpbGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IExlZnQgb2YgdGhlIHRpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRvcCBvZiB0aGUgdGlsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHcgV2lkdGggb2YgdGhlIHRpbGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBoIEhlaWdodCBvZiB0aGUgdGlsZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGd1dHRlciBUaWxlIGd1dHRlci5cbiAgICogQHBhcmFtIHtib29sZWFufSB0cmFuc2l0aW9uIEFwcGx5IGFuIGFscGhhIHRyYW5zaXRpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGFjaXR5IE9wYWNpdHkuXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmRyYXdUaWxlSW1hZ2UgPSBmdW5jdGlvbiAodGlsZSwgZnJhbWVTdGF0ZSwgeCwgeSwgdywgaCwgZ3V0dGVyLCB0cmFuc2l0aW9uLCBvcGFjaXR5KSB7XG4gICAgdmFyIGltYWdlID0gdGhpcy5nZXRUaWxlSW1hZ2UodGlsZSk7XG5cbiAgICBpZiAoIWltYWdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHVpZCA9IGdldFVpZCh0aGlzKTtcbiAgICB2YXIgdGlsZUFscGhhID0gdHJhbnNpdGlvbiA/IHRpbGUuZ2V0QWxwaGEodWlkLCBmcmFtZVN0YXRlLnRpbWUpIDogMTtcbiAgICB2YXIgYWxwaGEgPSBvcGFjaXR5ICogdGlsZUFscGhhO1xuICAgIHZhciBhbHBoYUNoYW5nZWQgPSBhbHBoYSAhPT0gdGhpcy5jb250ZXh0Lmdsb2JhbEFscGhhO1xuXG4gICAgaWYgKGFscGhhQ2hhbmdlZCkge1xuICAgICAgdGhpcy5jb250ZXh0LnNhdmUoKTtcbiAgICAgIHRoaXMuY29udGV4dC5nbG9iYWxBbHBoYSA9IGFscGhhO1xuICAgIH1cblxuICAgIHRoaXMuY29udGV4dC5kcmF3SW1hZ2UoaW1hZ2UsIGd1dHRlciwgZ3V0dGVyLCBpbWFnZS53aWR0aCAtIDIgKiBndXR0ZXIsIGltYWdlLmhlaWdodCAtIDIgKiBndXR0ZXIsIHgsIHksIHcsIGgpO1xuXG4gICAgaWYgKGFscGhhQ2hhbmdlZCkge1xuICAgICAgdGhpcy5jb250ZXh0LnJlc3RvcmUoKTtcbiAgICB9XG5cbiAgICBpZiAodGlsZUFscGhhICE9PSAxKSB7XG4gICAgICBmcmFtZVN0YXRlLmFuaW1hdGUgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAodHJhbnNpdGlvbikge1xuICAgICAgdGlsZS5lbmRUcmFuc2l0aW9uKHVpZCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IEltYWdlXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuICAgIHJldHVybiBjb250ZXh0ID8gY29udGV4dC5jYW52YXMgOiBudWxsO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBpbWFnZSBmcm9tIGEgdGlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9JbWFnZVRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnR9IEltYWdlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldFRpbGVJbWFnZSA9IGZ1bmN0aW9uICh0aWxlKSB7XG4gICAgcmV0dXJuIHRpbGUuZ2V0SW1hZ2UoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc291cmNlL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZVNvdXJjZSBUaWxlIHNvdXJjZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5zY2hlZHVsZUV4cGlyZUNhY2hlID0gZnVuY3Rpb24gKGZyYW1lU3RhdGUsIHRpbGVTb3VyY2UpIHtcbiAgICBpZiAodGlsZVNvdXJjZS5jYW5FeHBpcmVDYWNoZSgpKSB7XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vc291cmNlL1RpbGUuanNcIikuZGVmYXVsdH0gdGlsZVNvdXJjZSBUaWxlIHNvdXJjZS5cbiAgICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR9IG1hcCBNYXAuXG4gICAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgICAgICovXG4gICAgICB2YXIgcG9zdFJlbmRlckZ1bmN0aW9uID0gZnVuY3Rpb24gKHRpbGVTb3VyY2UsIG1hcCwgZnJhbWVTdGF0ZSkge1xuICAgICAgICB2YXIgdGlsZVNvdXJjZUtleSA9IGdldFVpZCh0aWxlU291cmNlKTtcblxuICAgICAgICBpZiAodGlsZVNvdXJjZUtleSBpbiBmcmFtZVN0YXRlLnVzZWRUaWxlcykge1xuICAgICAgICAgIHRpbGVTb3VyY2UuZXhwaXJlQ2FjaGUoZnJhbWVTdGF0ZS52aWV3U3RhdGUucHJvamVjdGlvbiwgZnJhbWVTdGF0ZS51c2VkVGlsZXNbdGlsZVNvdXJjZUtleV0pO1xuICAgICAgICB9XG4gICAgICB9LmJpbmQobnVsbCwgdGlsZVNvdXJjZSk7XG5cbiAgICAgIGZyYW1lU3RhdGUucG9zdFJlbmRlckZ1bmN0aW9ucy5wdXNoKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuUG9zdFJlbmRlckZ1bmN0aW9ufSAqL1xuICAgICAgcG9zdFJlbmRlckZ1bmN0aW9uKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0geyFPYmplY3Q8c3RyaW5nLCAhT2JqZWN0PHN0cmluZywgYm9vbGVhbj4+fSB1c2VkVGlsZXMgVXNlZCB0aWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zb3VyY2UvVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlU291cmNlIFRpbGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydCgnLi4vLi4vVGlsZS5qcycpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS51cGRhdGVVc2VkVGlsZXMgPSBmdW5jdGlvbiAodXNlZFRpbGVzLCB0aWxlU291cmNlLCB0aWxlKSB7XG4gICAgLy8gRklYTUUgc2hvdWxkIHdlIHVzZSB0aWxlc1RvRHJhd0J5WiBpbnN0ZWFkP1xuICAgIHZhciB0aWxlU291cmNlS2V5ID0gZ2V0VWlkKHRpbGVTb3VyY2UpO1xuXG4gICAgaWYgKCEodGlsZVNvdXJjZUtleSBpbiB1c2VkVGlsZXMpKSB7XG4gICAgICB1c2VkVGlsZXNbdGlsZVNvdXJjZUtleV0gPSB7fTtcbiAgICB9XG5cbiAgICB1c2VkVGlsZXNbdGlsZVNvdXJjZUtleV1bdGlsZS5nZXRLZXkoKV0gPSB0cnVlO1xuICB9O1xuICAvKipcbiAgICogTWFuYWdlIHRpbGUgcHlyYW1pZC5cbiAgICogVGhpcyBmdW5jdGlvbiBwZXJmb3JtcyBhIG51bWJlciBvZiBmdW5jdGlvbnMgcmVsYXRlZCB0byB0aGUgdGlsZXMgYXQgdGhlXG4gICAqIGN1cnJlbnQgem9vbSBhbmQgbG93ZXIgem9vbSBsZXZlbHM6XG4gICAqIC0gcmVnaXN0ZXJzIGlkbGUgdGlsZXMgaW4gZnJhbWVTdGF0ZS53YW50ZWRUaWxlcyBzbyB0aGF0IHRoZXkgYXJlIG5vdFxuICAgKiAgIGRpc2NhcmRlZCBieSB0aGUgdGlsZSBxdWV1ZVxuICAgKiAtIGVucXVldWVzIG1pc3NpbmcgdGlsZXNcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zb3VyY2UvVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlU291cmNlIFRpbGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHRpbGVHcmlkIFRpbGUgZ3JpZC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcGFyYW0ge251bWJlcn0gY3VycmVudFogQ3VycmVudCBaLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcHJlbG9hZCBMb2FkIGxvdyByZXNvbHV0aW9uIHRpbGVzIHVwIHRvICdwcmVsb2FkJyBsZXZlbHMuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vLi4vVGlsZS5qc1wiKS5kZWZhdWx0KT19IG9wdF90aWxlQ2FsbGJhY2sgVGlsZSBjYWxsYmFjay5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIENhbnZhc1RpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5tYW5hZ2VUaWxlUHlyYW1pZCA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlLCB0aWxlU291cmNlLCB0aWxlR3JpZCwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwgZXh0ZW50LCBjdXJyZW50WiwgcHJlbG9hZCwgb3B0X3RpbGVDYWxsYmFjaykge1xuICAgIHZhciB0aWxlU291cmNlS2V5ID0gZ2V0VWlkKHRpbGVTb3VyY2UpO1xuXG4gICAgaWYgKCEodGlsZVNvdXJjZUtleSBpbiBmcmFtZVN0YXRlLndhbnRlZFRpbGVzKSkge1xuICAgICAgZnJhbWVTdGF0ZS53YW50ZWRUaWxlc1t0aWxlU291cmNlS2V5XSA9IHt9O1xuICAgIH1cblxuICAgIHZhciB3YW50ZWRUaWxlcyA9IGZyYW1lU3RhdGUud2FudGVkVGlsZXNbdGlsZVNvdXJjZUtleV07XG4gICAgdmFyIHRpbGVRdWV1ZSA9IGZyYW1lU3RhdGUudGlsZVF1ZXVlO1xuICAgIHZhciBtaW5ab29tID0gdGlsZUdyaWQuZ2V0TWluWm9vbSgpO1xuICAgIHZhciB0aWxlQ291bnQgPSAwO1xuICAgIHZhciB0aWxlLCB0aWxlUmFuZ2UsIHRpbGVSZXNvbHV0aW9uLCB4LCB5LCB6O1xuXG4gICAgZm9yICh6ID0gbWluWm9vbTsgeiA8PSBjdXJyZW50WjsgKyt6KSB7XG4gICAgICB0aWxlUmFuZ2UgPSB0aWxlR3JpZC5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKGV4dGVudCwgeiwgdGlsZVJhbmdlKTtcbiAgICAgIHRpbGVSZXNvbHV0aW9uID0gdGlsZUdyaWQuZ2V0UmVzb2x1dGlvbih6KTtcblxuICAgICAgZm9yICh4ID0gdGlsZVJhbmdlLm1pblg7IHggPD0gdGlsZVJhbmdlLm1heFg7ICsreCkge1xuICAgICAgICBmb3IgKHkgPSB0aWxlUmFuZ2UubWluWTsgeSA8PSB0aWxlUmFuZ2UubWF4WTsgKyt5KSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRaIC0geiA8PSBwcmVsb2FkKSB7XG4gICAgICAgICAgICArK3RpbGVDb3VudDtcbiAgICAgICAgICAgIHRpbGUgPSB0aWxlU291cmNlLmdldFRpbGUoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbik7XG5cbiAgICAgICAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLklETEUpIHtcbiAgICAgICAgICAgICAgd2FudGVkVGlsZXNbdGlsZS5nZXRLZXkoKV0gPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGlmICghdGlsZVF1ZXVlLmlzS2V5UXVldWVkKHRpbGUuZ2V0S2V5KCkpKSB7XG4gICAgICAgICAgICAgICAgdGlsZVF1ZXVlLmVucXVldWUoW3RpbGUsIHRpbGVTb3VyY2VLZXksIHRpbGVHcmlkLmdldFRpbGVDb29yZENlbnRlcih0aWxlLnRpbGVDb29yZCksIHRpbGVSZXNvbHV0aW9uXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9wdF90aWxlQ2FsbGJhY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBvcHRfdGlsZUNhbGxiYWNrKHRpbGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aWxlU291cmNlLnVzZVRpbGUoeiwgeCwgeSwgcHJvamVjdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGlsZVNvdXJjZS51cGRhdGVDYWNoZVNpemUodGlsZUNvdW50LCBwcm9qZWN0aW9uKTtcbiAgfTtcblxuICByZXR1cm4gQ2FudmFzVGlsZUxheWVyUmVuZGVyZXI7XG59KENhbnZhc0xheWVyUmVuZGVyZXIpO1xuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4uLy4uL2xheWVyL1RpbGUuanNcIikuZGVmYXVsdHxpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9XG4gKi9cblxuXG5DYW52YXNUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0TGF5ZXI7XG5leHBvcnQgZGVmYXVsdCBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlcjsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL2xheWVyL1RpbGVcbiAqL1xuXG5cbmltcG9ydCBCYXNlVGlsZUxheWVyIGZyb20gJy4vQmFzZVRpbGUuanMnO1xuaW1wb3J0IENhbnZhc1RpbGVMYXllclJlbmRlcmVyIGZyb20gJy4uL3JlbmRlcmVyL2NhbnZhcy9UaWxlTGF5ZXIuanMnO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBGb3IgbGF5ZXIgc291cmNlcyB0aGF0IHByb3ZpZGUgcHJlLXJlbmRlcmVkLCB0aWxlZCBpbWFnZXMgaW4gZ3JpZHMgdGhhdCBhcmVcbiAqIG9yZ2FuaXplZCBieSB6b29tIGxldmVscyBmb3Igc3BlY2lmaWMgcmVzb2x1dGlvbnMuXG4gKiBOb3RlIHRoYXQgYW55IHByb3BlcnR5IHNldCBpbiB0aGUgb3B0aW9ucyBpcyBzZXQgYXMgYSB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH5CYXNlT2JqZWN0fVxuICogcHJvcGVydHkgb24gdGhlIGxheWVyIG9iamVjdDsgZm9yIGV4YW1wbGUsIHNldHRpbmcgYHRpdGxlOiAnTXkgVGl0bGUnYCBpbiB0aGVcbiAqIG9wdGlvbnMgbWVhbnMgdGhhdCBgdGl0bGVgIGlzIG9ic2VydmFibGUsIGFuZCBoYXMgZ2V0L3NldCBhY2Nlc3NvcnMuXG4gKlxuICogQGFwaVxuICovXG5cbnZhciBUaWxlTGF5ZXIgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZUxheWVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL0Jhc2VUaWxlLmpzXCIpLk9wdGlvbnM9fSBvcHRfb3B0aW9ucyBUaWxlIGxheWVyIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVGlsZUxheWVyKG9wdF9vcHRpb25zKSB7XG4gICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIG9wdF9vcHRpb25zKSB8fCB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDcmVhdGUgYSByZW5kZXJlciBmb3IgdGhpcyBsYXllci5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vcmVuZGVyZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gQSBsYXllciByZW5kZXJlci5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVMYXllci5wcm90b3R5cGUuY3JlYXRlUmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBDYW52YXNUaWxlTGF5ZXJSZW5kZXJlcih0aGlzKTtcbiAgfTtcblxuICByZXR1cm4gVGlsZUxheWVyO1xufShCYXNlVGlsZUxheWVyKTtcblxuZXhwb3J0IGRlZmF1bHQgVGlsZUxheWVyOyIsIi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9WZWN0b3JUaWxlUmVuZGVyVHlwZVxuICovXG5cbi8qKlxuICogQGVudW0ge3N0cmluZ31cbiAqIFJlbmRlciBtb2RlIGZvciB2ZWN0b3IgdGlsZXM6XG4gKiAgKiBgJ2ltYWdlJ2A6IFZlY3RvciB0aWxlcyBhcmUgcmVuZGVyZWQgYXMgaW1hZ2VzLiBHcmVhdCBwZXJmb3JtYW5jZSwgYnV0XG4gKiAgICBwb2ludCBzeW1ib2xzIGFuZCB0ZXh0cyBhcmUgYWx3YXlzIHJvdGF0ZWQgd2l0aCB0aGUgdmlldyBhbmQgcGl4ZWxzIGFyZVxuICogICAgc2NhbGVkIGR1cmluZyB6b29tIGFuaW1hdGlvbnMuXG4gKiAgKiBgJ2h5YnJpZCdgOiBQb2x5Z29uIGFuZCBsaW5lIGVsZW1lbnRzIGFyZSByZW5kZXJlZCBhcyBpbWFnZXMsIHNvIHBpeGVsc1xuICogICAgYXJlIHNjYWxlZCBkdXJpbmcgem9vbSBhbmltYXRpb25zLiBQb2ludCBzeW1ib2xzIGFuZCB0ZXh0cyBhcmUgYWNjdXJhdGVseVxuICogICAgcmVuZGVyZWQgYXMgdmVjdG9ycyBhbmQgY2FuIHN0YXkgdXByaWdodCBvbiByb3RhdGVkIHZpZXdzLlxuICogICogYCd2ZWN0b3InYDogRXZlcnl0aGluZyBpcyByZW5kZXJlZCBhcyB2ZWN0b3JzLiBVc2UgdGhpcyBtb2RlIGZvciBpbXByb3ZlZFxuICogICAgcGVyZm9ybWFuY2Ugb24gdmVjdG9yIHRpbGUgbGF5ZXJzIHdpdGggb25seSBhIGZldyByZW5kZXJlZCBmZWF0dXJlcyAoZS5nLlxuICogICAgZm9yIGhpZ2hsaWdodGluZyBhIHN1YnNldCBvZiBmZWF0dXJlcyBvZiBhbm90aGVyIGxheWVyIHdpdGggdGhlIHNhbWVcbiAqICAgIHNvdXJjZSkuXG4gKiBAYXBpXG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgSU1BR0U6ICdpbWFnZScsXG4gIEhZQlJJRDogJ2h5YnJpZCcsXG4gIFZFQ1RPUjogJ3ZlY3Rvcidcbn07IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9yZW5kZXJlci9jYW52YXMvVmVjdG9yVGlsZUxheWVyXG4gKi9cblxuXG5pbXBvcnQgQ2FudmFzQnVpbGRlckdyb3VwIGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzJztcbmltcG9ydCBDYW52YXNFeGVjdXRvckdyb3VwIGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMvRXhlY3V0b3JHcm91cC5qcyc7XG5pbXBvcnQgQ2FudmFzVGlsZUxheWVyUmVuZGVyZXIgZnJvbSAnLi9UaWxlTGF5ZXIuanMnO1xuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi8uLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBSZXBsYXlUeXBlIGZyb20gJy4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlclR5cGUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuLi8uLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IFZlY3RvclRpbGVSZW5kZXJUeXBlIGZyb20gJy4uLy4uL2xheWVyL1ZlY3RvclRpbGVSZW5kZXJUeXBlLmpzJztcbmltcG9ydCBWaWV3SGludCBmcm9tICcuLi8uLi9WaWV3SGludC5qcyc7XG5pbXBvcnQgeyBhcHBseSBhcyBhcHBseVRyYW5zZm9ybSwgY3JlYXRlIGFzIGNyZWF0ZVRyYW5zZm9ybSwgbXVsdGlwbHksIHJlc2V0IGFzIHJlc2V0VHJhbnNmb3JtLCBzY2FsZSwgc2NhbGUgYXMgc2NhbGVUcmFuc2Zvcm0sIHRyYW5zbGF0ZSBhcyB0cmFuc2xhdGVUcmFuc2Zvcm0gfSBmcm9tICcuLi8uLi90cmFuc2Zvcm0uanMnO1xuaW1wb3J0IHsgYm91bmRpbmdFeHRlbnQsIGJ1ZmZlciwgY29udGFpbnNFeHRlbnQsIGVxdWFscywgZ2V0SW50ZXJzZWN0aW9uLCBnZXRUb3BMZWZ0LCBpbnRlcnNlY3RzIH0gZnJvbSAnLi4vLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGNsZWFyIH0gZnJvbSAnLi4vLi4vb2JqLmpzJztcbmltcG9ydCB7IGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YSwgaGl0RGV0ZWN0IH0gZnJvbSAnLi4vLi4vcmVuZGVyL2NhbnZhcy9oaXRkZXRlY3QuanMnO1xuaW1wb3J0IHsgZ2V0U3F1YXJlZFRvbGVyYW5jZSBhcyBnZXRTcXVhcmVkUmVuZGVyVG9sZXJhbmNlLCByZW5kZXJGZWF0dXJlIH0gZnJvbSAnLi4vdmVjdG9yLmpzJztcbmltcG9ydCB7IGdldFVpZCB9IGZyb20gJy4uLy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vLi4vZXZlbnRzLmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4uLy4uL3NpemUuanMnO1xuaW1wb3J0IHsgd3JhcFggfSBmcm9tICcuLi8uLi9jb29yZGluYXRlLmpzJztcbi8qKlxuICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuLi8uLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJUeXBlLmpzXCIpLmRlZmF1bHQ+Pn1cbiAqL1xuXG52YXIgSU1BR0VfUkVQTEFZUyA9IHtcbiAgJ2ltYWdlJzogW1JlcGxheVR5cGUuUE9MWUdPTiwgUmVwbGF5VHlwZS5DSVJDTEUsIFJlcGxheVR5cGUuTElORV9TVFJJTkcsIFJlcGxheVR5cGUuSU1BR0UsIFJlcGxheVR5cGUuVEVYVF0sXG4gICdoeWJyaWQnOiBbUmVwbGF5VHlwZS5QT0xZR09OLCBSZXBsYXlUeXBlLkxJTkVfU1RSSU5HXSxcbiAgJ3ZlY3Rvcic6IFtdXG59O1xuLyoqXG4gKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIEFycmF5PGltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlclR5cGUuanNcIikuZGVmYXVsdD4+fVxuICovXG5cbnZhciBWRUNUT1JfUkVQTEFZUyA9IHtcbiAgJ2ltYWdlJzogW1JlcGxheVR5cGUuREVGQVVMVF0sXG4gICdoeWJyaWQnOiBbUmVwbGF5VHlwZS5JTUFHRSwgUmVwbGF5VHlwZS5URVhULCBSZXBsYXlUeXBlLkRFRkFVTFRdLFxuICAndmVjdG9yJzogW1JlcGxheVR5cGUuUE9MWUdPTiwgUmVwbGF5VHlwZS5DSVJDTEUsIFJlcGxheVR5cGUuTElORV9TVFJJTkcsIFJlcGxheVR5cGUuSU1BR0UsIFJlcGxheVR5cGUuVEVYVCwgUmVwbGF5VHlwZS5ERUZBVUxUXVxufTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2FudmFzIHJlbmRlcmVyIGZvciB2ZWN0b3IgdGlsZSBsYXllcnMuXG4gKiBAYXBpXG4gKi9cblxudmFyIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9sYXllci9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IGxheWVyIFZlY3RvclRpbGUgbGF5ZXIuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIobGF5ZXIpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBsYXllcikgfHwgdGhpcztcbiAgICAvKiogQHByaXZhdGUgKi9cblxuXG4gICAgX3RoaXMuYm91bmRIYW5kbGVTdHlsZUltYWdlQ2hhbmdlXyA9IF90aGlzLmhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfLmJpbmQoX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5kaXJ0eV8gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZExheWVyUmV2aXNpb25fO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybVwiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJlZFBpeGVsVG9Db29yZGluYXRlVHJhbnNmb3JtXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWRSb3RhdGlvbl87XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdD59XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi4vLi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleT59XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlTGlzdGVuZXJLZXlzXyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uLy4uL3RyYW5zZm9ybS5qc1wiKS5UcmFuc2Zvcm19XG4gICAgICovXG5cbiAgICBfdGhpcy50bXBUcmFuc2Zvcm1fID0gY3JlYXRlVHJhbnNmb3JtKCk7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb25cIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHF1ZXVlIFF1ZXVlIHRpbGUgZm9yIHJlbmRlcmluZy5cbiAgICogQHJldHVybiB7Ym9vbGVhbnx1bmRlZmluZWR9IFRpbGUgbmVlZHMgdG8gYmUgcmVuZGVyZWQuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnByZXBhcmVUaWxlID0gZnVuY3Rpb24gKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIHF1ZXVlKSB7XG4gICAgdmFyIHJlbmRlcjtcbiAgICB2YXIgdGlsZVVpZCA9IGdldFVpZCh0aWxlKTtcbiAgICB2YXIgc3RhdGUgPSB0aWxlLmdldFN0YXRlKCk7XG5cbiAgICBpZiAoKHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEICYmIHRpbGUuaGlmaSB8fCBzdGF0ZSA9PT0gVGlsZVN0YXRlLkVSUk9SKSAmJiB0aWxlVWlkIGluIHRoaXMudGlsZUxpc3RlbmVyS2V5c18pIHtcbiAgICAgIHVubGlzdGVuQnlLZXkodGhpcy50aWxlTGlzdGVuZXJLZXlzX1t0aWxlVWlkXSk7XG4gICAgICBkZWxldGUgdGhpcy50aWxlTGlzdGVuZXJLZXlzX1t0aWxlVWlkXTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUgPT09IFRpbGVTdGF0ZS5MT0FERUQgfHwgc3RhdGUgPT09IFRpbGVTdGF0ZS5FUlJPUikge1xuICAgICAgdGhpcy51cGRhdGVFeGVjdXRvckdyb3VwXyh0aWxlLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcblxuICAgICAgaWYgKHRoaXMudGlsZUltYWdlTmVlZHNSZW5kZXJfKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pKSB7XG4gICAgICAgIHJlbmRlciA9IHRydWU7XG5cbiAgICAgICAgaWYgKHF1ZXVlKSB7XG4gICAgICAgICAgdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV9bdGlsZVVpZF0gPSB0aWxlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlbmRlcjtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFRpbGUgY29vcmRpbmF0ZSB6LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi8uLi9UaWxlLmpzXCIpLmRlZmF1bHR9IFRpbGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldFRpbGUgPSBmdW5jdGlvbiAoeiwgeCwgeSwgZnJhbWVTdGF0ZSkge1xuICAgIHZhciBwaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvO1xuICAgIHZhciB2aWV3U3RhdGUgPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciBwcm9qZWN0aW9uID0gdmlld1N0YXRlLnByb2plY3Rpb247XG4gICAgdmFyIGxheWVyID0gdGhpcy5nZXRMYXllcigpO1xuICAgIHZhciB0aWxlID0gbGF5ZXIuZ2V0U291cmNlKCkuZ2V0VGlsZSh6LCB4LCB5LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcblxuICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPCBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICB0aWxlLndhbnRlZFJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICAgICAgdmFyIHRpbGVVaWQgPSBnZXRVaWQodGlsZSk7XG5cbiAgICAgIGlmICghKHRpbGVVaWQgaW4gdGhpcy50aWxlTGlzdGVuZXJLZXlzXykpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVyS2V5ID0gbGlzdGVuKHRpbGUsIEV2ZW50VHlwZS5DSEFOR0UsIHRoaXMucHJlcGFyZVRpbGUuYmluZCh0aGlzLCB0aWxlLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uLCB0cnVlKSk7XG4gICAgICAgIHRoaXMudGlsZUxpc3RlbmVyS2V5c19bdGlsZVVpZF0gPSBsaXN0ZW5lcktleTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHZpZXdIaW50cyA9IGZyYW1lU3RhdGUudmlld0hpbnRzO1xuICAgICAgdmFyIGhpZmkgPSAhKHZpZXdIaW50c1tWaWV3SGludC5BTklNQVRJTkddIHx8IHZpZXdIaW50c1tWaWV3SGludC5JTlRFUkFDVElOR10pO1xuXG4gICAgICBpZiAoaGlmaSB8fCAhdGlsZS53YW50ZWRSZXNvbHV0aW9uKSB7XG4gICAgICAgIHRpbGUud2FudGVkUmVzb2x1dGlvbiA9IHJlc29sdXRpb247XG4gICAgICB9XG5cbiAgICAgIHZhciByZW5kZXIgPSB0aGlzLnByZXBhcmVUaWxlKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIGZhbHNlKTtcblxuICAgICAgaWYgKHJlbmRlciAmJiBsYXllci5nZXRSZW5kZXJNb2RlKCkgIT09IFZlY3RvclRpbGVSZW5kZXJUeXBlLlZFQ1RPUikge1xuICAgICAgICB0aGlzLnJlbmRlclRpbGVJbWFnZV8odGlsZSwgZnJhbWVTdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZ2V0VGlsZS5jYWxsKHRoaXMsIHosIHgsIHksIGZyYW1lU3RhdGUpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9WZWN0b3JSZW5kZXJUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGlsZSBpcyBkcmF3YWJsZS5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaXNEcmF3YWJsZVRpbGUgPSBmdW5jdGlvbiAodGlsZSkge1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5pc0RyYXdhYmxlVGlsZS5jYWxsKHRoaXMsIHRpbGUpICYmIChsYXllci5nZXRSZW5kZXJNb2RlKCkgPT09IFZlY3RvclRpbGVSZW5kZXJUeXBlLlZFQ1RPUiA/IGdldFVpZChsYXllcikgaW4gdGlsZS5leGVjdXRvckdyb3VwcyA6IHRpbGUuaGFzQ29udGV4dChsYXllcikpO1xuICB9O1xuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuZ2V0VGlsZUltYWdlID0gZnVuY3Rpb24gKHRpbGUpIHtcbiAgICByZXR1cm4gdGlsZS5nZXRJbWFnZSh0aGlzLmdldExheWVyKCkpO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgcmVuZGVyIHNob3VsZCBiZSBjYWxsZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IExheWVyIGlzIHJlYWR5IHRvIGJlIHJlbmRlcmVkLlxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5wcmVwYXJlRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSkge1xuICAgIHZhciBsYXllclJldmlzaW9uID0gdGhpcy5nZXRMYXllcigpLmdldFJldmlzaW9uKCk7XG5cbiAgICBpZiAodGhpcy5yZW5kZXJlZExheWVyUmV2aXNpb25fICE9IGxheWVyUmV2aXNpb24pIHtcbiAgICAgIHRoaXMucmVuZGVyZWRUaWxlcy5sZW5ndGggPSAwO1xuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWRMYXllclJldmlzaW9uXyA9IGxheWVyUmV2aXNpb247XG4gICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUucHJlcGFyZUZyYW1lLmNhbGwodGhpcywgZnJhbWVTdGF0ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS51cGRhdGVFeGVjdXRvckdyb3VwXyA9IGZ1bmN0aW9uICh0aWxlLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gICAgdmFyIGxheWVyID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICB0aGlzLmdldExheWVyKCk7XG4gICAgdmFyIHJldmlzaW9uID0gbGF5ZXIuZ2V0UmV2aXNpb24oKTtcbiAgICB2YXIgcmVuZGVyT3JkZXIgPSBsYXllci5nZXRSZW5kZXJPcmRlcigpIHx8IG51bGw7XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aWxlLndhbnRlZFJlc29sdXRpb247XG4gICAgdmFyIGJ1aWxkZXJTdGF0ZSA9IHRpbGUuZ2V0UmVwbGF5U3RhdGUobGF5ZXIpO1xuXG4gICAgaWYgKCFidWlsZGVyU3RhdGUuZGlydHkgJiYgYnVpbGRlclN0YXRlLnJlbmRlcmVkUmVzb2x1dGlvbiA9PT0gcmVzb2x1dGlvbiAmJiBidWlsZGVyU3RhdGUucmVuZGVyZWRSZXZpc2lvbiA9PSByZXZpc2lvbiAmJiBidWlsZGVyU3RhdGUucmVuZGVyZWRSZW5kZXJPcmRlciA9PSByZW5kZXJPcmRlciAmJiBidWlsZGVyU3RhdGUucmVuZGVyZWRaID09PSB0aWxlLnNvdXJjZVopIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc291cmNlID0gbGF5ZXIuZ2V0U291cmNlKCk7XG4gICAgdmFyIGRlY2x1dHRlciA9IGxheWVyLmdldERlY2x1dHRlcigpO1xuICAgIHZhciBzb3VyY2VUaWxlR3JpZCA9IHNvdXJjZS5nZXRUaWxlR3JpZCgpO1xuICAgIHZhciB0aWxlR3JpZCA9IHNvdXJjZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdmFyIHRpbGVFeHRlbnQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZS53cmFwcGVkVGlsZUNvb3JkKTtcbiAgICB2YXIgc291cmNlVGlsZXMgPSBzb3VyY2UuZ2V0U291cmNlVGlsZXMocGl4ZWxSYXRpbywgcHJvamVjdGlvbiwgdGlsZSk7XG4gICAgdmFyIGxheWVyVWlkID0gZ2V0VWlkKGxheWVyKTtcbiAgICBkZWxldGUgdGlsZS5oaXREZXRlY3Rpb25JbWFnZURhdGFbbGF5ZXJVaWRdO1xuICAgIHRpbGUuZXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdID0gW107XG5cbiAgICBpZiAoZGVjbHV0dGVyKSB7XG4gICAgICB0aWxlLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzW2xheWVyVWlkXSA9IFtdO1xuICAgIH1cblxuICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gX2xvb3BfMSh0LCB0dCkge1xuICAgICAgdmFyIHNvdXJjZVRpbGUgPSBzb3VyY2VUaWxlc1t0XTtcblxuICAgICAgaWYgKHNvdXJjZVRpbGUuZ2V0U3RhdGUoKSAhPSBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICAgIHJldHVybiBcImNvbnRpbnVlXCI7XG4gICAgICB9XG5cbiAgICAgIHZhciBzb3VyY2VUaWxlQ29vcmQgPSBzb3VyY2VUaWxlLnRpbGVDb29yZDtcbiAgICAgIHZhciBzb3VyY2VUaWxlRXh0ZW50ID0gc291cmNlVGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHNvdXJjZVRpbGVDb29yZCk7XG4gICAgICB2YXIgc2hhcmVkRXh0ZW50ID0gZ2V0SW50ZXJzZWN0aW9uKHRpbGVFeHRlbnQsIHNvdXJjZVRpbGVFeHRlbnQpO1xuICAgICAgdmFyIGJ1ZmZlcmVkRXh0ZW50ID0gZXF1YWxzKHNvdXJjZVRpbGVFeHRlbnQsIHNoYXJlZEV4dGVudCkgPyBudWxsIDogYnVmZmVyKHNoYXJlZEV4dGVudCwgbGF5ZXIuZ2V0UmVuZGVyQnVmZmVyKCkgKiByZXNvbHV0aW9uLCB0aGlzXzEudG1wRXh0ZW50KTtcbiAgICAgIGJ1aWxkZXJTdGF0ZS5kaXJ0eSA9IGZhbHNlO1xuICAgICAgdmFyIGJ1aWxkZXJHcm91cCA9IG5ldyBDYW52YXNCdWlsZGVyR3JvdXAoMCwgc2hhcmVkRXh0ZW50LCByZXNvbHV0aW9uLCBwaXhlbFJhdGlvKTtcbiAgICAgIHZhciBkZWNsdXR0ZXJCdWlsZGVyR3JvdXAgPSBkZWNsdXR0ZXIgPyBuZXcgQ2FudmFzQnVpbGRlckdyb3VwKDAsIHNoYXJlZEV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbykgOiB1bmRlZmluZWQ7XG4gICAgICB2YXIgc3F1YXJlZFRvbGVyYW5jZSA9IGdldFNxdWFyZWRSZW5kZXJUb2xlcmFuY2UocmVzb2x1dGlvbiwgcGl4ZWxSYXRpbyk7XG4gICAgICAvKipcbiAgICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAgICogQHRoaXMge0NhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyfVxuICAgICAgICovXG5cbiAgICAgIHZhciByZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoZmVhdHVyZSkge1xuICAgICAgICB2YXIgc3R5bGVzO1xuICAgICAgICB2YXIgc3R5bGVGdW5jdGlvbiA9IGZlYXR1cmUuZ2V0U3R5bGVGdW5jdGlvbigpIHx8IGxheWVyLmdldFN0eWxlRnVuY3Rpb24oKTtcblxuICAgICAgICBpZiAoc3R5bGVGdW5jdGlvbikge1xuICAgICAgICAgIHN0eWxlcyA9IHN0eWxlRnVuY3Rpb24oZmVhdHVyZSwgcmVzb2x1dGlvbik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3R5bGVzKSB7XG4gICAgICAgICAgdmFyIGRpcnR5ID0gdGhpcy5yZW5kZXJGZWF0dXJlKGZlYXR1cmUsIHNxdWFyZWRUb2xlcmFuY2UsIHN0eWxlcywgYnVpbGRlckdyb3VwLCBkZWNsdXR0ZXJCdWlsZGVyR3JvdXApO1xuICAgICAgICAgIHRoaXMuZGlydHlfID0gdGhpcy5kaXJ0eV8gfHwgZGlydHk7XG4gICAgICAgICAgYnVpbGRlclN0YXRlLmRpcnR5ID0gYnVpbGRlclN0YXRlLmRpcnR5IHx8IGRpcnR5O1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICB2YXIgZmVhdHVyZXMgPSBzb3VyY2VUaWxlLmdldEZlYXR1cmVzKCk7XG5cbiAgICAgIGlmIChyZW5kZXJPcmRlciAmJiByZW5kZXJPcmRlciAhPT0gYnVpbGRlclN0YXRlLnJlbmRlcmVkUmVuZGVyT3JkZXIpIHtcbiAgICAgICAgZmVhdHVyZXMuc29ydChyZW5kZXJPcmRlcik7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGZlYXR1cmVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIGZlYXR1cmUgPSBmZWF0dXJlc1tpXTtcblxuICAgICAgICBpZiAoIWJ1ZmZlcmVkRXh0ZW50IHx8IGludGVyc2VjdHMoYnVmZmVyZWRFeHRlbnQsIGZlYXR1cmUuZ2V0R2VvbWV0cnkoKS5nZXRFeHRlbnQoKSkpIHtcbiAgICAgICAgICByZW5kZXIuY2FsbCh0aGlzXzEsIGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBleGVjdXRvckdyb3VwSW5zdHJ1Y3Rpb25zID0gYnVpbGRlckdyb3VwLmZpbmlzaCgpOyAvLyBubyBuZWVkIHRvIGNsaXAgd2hlbiB0aGUgcmVuZGVyIHRpbGUgaXMgY292ZXJlZCBieSBhIHNpbmdsZSBzb3VyY2UgdGlsZVxuXG4gICAgICB2YXIgcmVwbGF5RXh0ZW50ID0gbGF5ZXIuZ2V0UmVuZGVyTW9kZSgpICE9PSBWZWN0b3JUaWxlUmVuZGVyVHlwZS5WRUNUT1IgJiYgZGVjbHV0dGVyICYmIHNvdXJjZVRpbGVzLmxlbmd0aCA9PT0gMSA/IG51bGwgOiBzaGFyZWRFeHRlbnQ7XG4gICAgICB2YXIgcmVuZGVyaW5nUmVwbGF5R3JvdXAgPSBuZXcgQ2FudmFzRXhlY3V0b3JHcm91cChyZXBsYXlFeHRlbnQsIHJlc29sdXRpb24sIHBpeGVsUmF0aW8sIHNvdXJjZS5nZXRPdmVybGFwcygpLCBleGVjdXRvckdyb3VwSW5zdHJ1Y3Rpb25zLCBsYXllci5nZXRSZW5kZXJCdWZmZXIoKSk7XG4gICAgICB0aWxlLmV4ZWN1dG9yR3JvdXBzW2xheWVyVWlkXS5wdXNoKHJlbmRlcmluZ1JlcGxheUdyb3VwKTtcblxuICAgICAgaWYgKGRlY2x1dHRlckJ1aWxkZXJHcm91cCkge1xuICAgICAgICB2YXIgZGVjbHV0dGVyRXhlY3V0b3JHcm91cCA9IG5ldyBDYW52YXNFeGVjdXRvckdyb3VwKHJlcGxheUV4dGVudCwgcmVzb2x1dGlvbiwgcGl4ZWxSYXRpbywgc291cmNlLmdldE92ZXJsYXBzKCksIGRlY2x1dHRlckJ1aWxkZXJHcm91cC5maW5pc2goKSwgbGF5ZXIuZ2V0UmVuZGVyQnVmZmVyKCkpO1xuICAgICAgICB0aWxlLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzW2xheWVyVWlkXS5wdXNoKGRlY2x1dHRlckV4ZWN1dG9yR3JvdXApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgdGhpc18xID0gdGhpcztcblxuICAgIGZvciAodmFyIHQgPSAwLCB0dCA9IHNvdXJjZVRpbGVzLmxlbmd0aDsgdCA8IHR0OyArK3QpIHtcbiAgICAgIF9sb29wXzEodCwgdHQpO1xuICAgIH1cblxuICAgIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFJldmlzaW9uID0gcmV2aXNpb247XG4gICAgYnVpbGRlclN0YXRlLnJlbmRlcmVkWiA9IHRpbGUuc291cmNlWjtcbiAgICBidWlsZGVyU3RhdGUucmVuZGVyZWRSZW5kZXJPcmRlciA9IHJlbmRlck9yZGVyO1xuICAgIGJ1aWxkZXJTdGF0ZS5yZW5kZXJlZFJlc29sdXRpb24gPSByZXNvbHV0aW9uO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXAuanNcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGhpdFRvbGVyYW5jZSBIaXQgdG9sZXJhbmNlIGluIHBpeGVscy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi92ZWN0b3IuanNcIikuRmVhdHVyZUNhbGxiYWNrPFQ+fSBjYWxsYmFjayBGZWF0dXJlIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge0FycmF5PGltcG9ydChcIi4uL01hcC5qc1wiKS5IaXRNYXRjaDxUPj59IG1hdGNoZXMgVGhlIGhpdCBkZXRlY3RlZCBtYXRjaGVzIHdpdGggdG9sZXJhbmNlLlxuICAgKiBAcmV0dXJuIHtUfHVuZGVmaW5lZH0gQ2FsbGJhY2sgcmVzdWx0LlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKi9cblxuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5mb3JFYWNoRmVhdHVyZUF0Q29vcmRpbmF0ZSA9IGZ1bmN0aW9uIChjb29yZGluYXRlLCBmcmFtZVN0YXRlLCBoaXRUb2xlcmFuY2UsIGNhbGxiYWNrLCBtYXRjaGVzKSB7XG4gICAgdmFyIHJlc29sdXRpb24gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yZXNvbHV0aW9uO1xuICAgIHZhciByb3RhdGlvbiA9IGZyYW1lU3RhdGUudmlld1N0YXRlLnJvdGF0aW9uO1xuICAgIGhpdFRvbGVyYW5jZSA9IGhpdFRvbGVyYW5jZSA9PSB1bmRlZmluZWQgPyAwIDogaGl0VG9sZXJhbmNlO1xuICAgIHZhciBsYXllciA9IHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgc291cmNlID0gbGF5ZXIuZ2V0U291cmNlKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihmcmFtZVN0YXRlLnZpZXdTdGF0ZS5wcm9qZWN0aW9uKTtcbiAgICB2YXIgaGl0RXh0ZW50ID0gYm91bmRpbmdFeHRlbnQoW2Nvb3JkaW5hdGVdKTtcbiAgICBidWZmZXIoaGl0RXh0ZW50LCByZXNvbHV0aW9uICogaGl0VG9sZXJhbmNlLCBoaXRFeHRlbnQpO1xuICAgIC8qKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL01hcC5qc1wiKS5IaXRNYXRjaDxUPnx0cnVlPn0gKi9cblxuICAgIHZhciBmZWF0dXJlcyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZ2VvbS9TaW1wbGVHZW9tZXRyeS5qc1wiKS5kZWZhdWx0fSBnZW9tZXRyeSBHZW9tZXRyeS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZGlzdGFuY2VTcSBUaGUgc3F1YXJlZCBkaXN0YW5jZSB0byB0aGUgY2xpY2sgcG9zaXRpb24uXG4gICAgICogQHJldHVybiB7VHx1bmRlZmluZWR9IENhbGxiYWNrIHJlc3VsdC5cbiAgICAgKi9cblxuICAgIHZhciBmZWF0dXJlQ2FsbGJhY2sgPSBmdW5jdGlvbiBmZWF0dXJlQ2FsbGJhY2soZmVhdHVyZSwgZ2VvbWV0cnksIGRpc3RhbmNlU3EpIHtcbiAgICAgIHZhciBrZXkgPSBmZWF0dXJlLmdldElkKCk7XG5cbiAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBrZXkgPSBnZXRVaWQoZmVhdHVyZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBtYXRjaCA9IGZlYXR1cmVzW2tleV07XG5cbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgaWYgKGRpc3RhbmNlU3EgPT09IDApIHtcbiAgICAgICAgICBmZWF0dXJlc1trZXldID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZmVhdHVyZSwgbGF5ZXIsIGdlb21ldHJ5KTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1hdGNoZXMucHVzaChmZWF0dXJlc1trZXldID0ge1xuICAgICAgICAgIGZlYXR1cmU6IGZlYXR1cmUsXG4gICAgICAgICAgbGF5ZXI6IGxheWVyLFxuICAgICAgICAgIGdlb21ldHJ5OiBnZW9tZXRyeSxcbiAgICAgICAgICBkaXN0YW5jZVNxOiBkaXN0YW5jZVNxLFxuICAgICAgICAgIGNhbGxiYWNrOiBjYWxsYmFja1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobWF0Y2ggIT09IHRydWUgJiYgZGlzdGFuY2VTcSA8IG1hdGNoLmRpc3RhbmNlU3EpIHtcbiAgICAgICAgaWYgKGRpc3RhbmNlU3EgPT09IDApIHtcbiAgICAgICAgICBmZWF0dXJlc1trZXldID0gdHJ1ZTtcbiAgICAgICAgICBtYXRjaGVzLnNwbGljZShtYXRjaGVzLmxhc3RJbmRleE9mKG1hdGNoKSwgMSk7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGZlYXR1cmUsIGxheWVyLCBnZW9tZXRyeSk7XG4gICAgICAgIH1cblxuICAgICAgICBtYXRjaC5nZW9tZXRyeSA9IGdlb21ldHJ5O1xuICAgICAgICBtYXRjaC5kaXN0YW5jZVNxID0gZGlzdGFuY2VTcTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9O1xuXG4gICAgdmFyIHJlbmRlcmVkVGlsZXMgPVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICB0aGlzLnJlbmRlcmVkVGlsZXM7XG4gICAgdmFyIGZvdW5kO1xuXG4gICAgdmFyIF9sb29wXzIgPSBmdW5jdGlvbiBfbG9vcF8yKGksIGlpKSB7XG4gICAgICB2YXIgdGlsZSA9IHJlbmRlcmVkVGlsZXNbaV07XG4gICAgICB2YXIgdGlsZUV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlLndyYXBwZWRUaWxlQ29vcmQpO1xuXG4gICAgICBpZiAoIWludGVyc2VjdHModGlsZUV4dGVudCwgaGl0RXh0ZW50KSkge1xuICAgICAgICByZXR1cm4gXCJjb250aW51ZVwiO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGF5ZXJVaWQgPSBnZXRVaWQobGF5ZXIpO1xuICAgICAgdmFyIGV4ZWN1dG9yR3JvdXBzID0gW3RpbGUuZXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdXTtcbiAgICAgIHZhciBkZWNsdXR0ZXJFeGVjdXRvckdyb3VwcyA9IHRpbGUuZGVjbHV0dGVyRXhlY3V0b3JHcm91cHNbbGF5ZXJVaWRdO1xuXG4gICAgICBpZiAoZGVjbHV0dGVyRXhlY3V0b3JHcm91cHMpIHtcbiAgICAgICAgZXhlY3V0b3JHcm91cHMucHVzaChkZWNsdXR0ZXJFeGVjdXRvckdyb3Vwcyk7XG4gICAgICB9XG5cbiAgICAgIGV4ZWN1dG9yR3JvdXBzLnNvbWUoZnVuY3Rpb24gKGV4ZWN1dG9yR3JvdXBzKSB7XG4gICAgICAgIHZhciBkZWNsdXR0ZXJlZEZlYXR1cmVzID0gZXhlY3V0b3JHcm91cHMgPT09IGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzID8gZnJhbWVTdGF0ZS5kZWNsdXR0ZXJUcmVlLmFsbCgpLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICAgICAgICB9KSA6IG51bGw7XG5cbiAgICAgICAgZm9yICh2YXIgdCA9IDAsIHR0ID0gZXhlY3V0b3JHcm91cHMubGVuZ3RoOyB0IDwgdHQ7ICsrdCkge1xuICAgICAgICAgIHZhciBleGVjdXRvckdyb3VwID0gZXhlY3V0b3JHcm91cHNbdF07XG4gICAgICAgICAgZm91bmQgPSBleGVjdXRvckdyb3VwLmZvckVhY2hGZWF0dXJlQXRDb29yZGluYXRlKGNvb3JkaW5hdGUsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBoaXRUb2xlcmFuY2UsIGZlYXR1cmVDYWxsYmFjaywgZGVjbHV0dGVyZWRGZWF0dXJlcyk7XG5cbiAgICAgICAgICBpZiAoZm91bmQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHJlbmRlcmVkVGlsZXMubGVuZ3RoOyAhZm91bmQgJiYgaSA8IGlpOyArK2kpIHtcbiAgICAgIF9sb29wXzIoaSwgaWkpO1xuICAgIH1cblxuICAgIHJldHVybiBmb3VuZDtcbiAgfTtcbiAgLyoqXG4gICAqIEFzeW5jaHJvbm91cyBsYXllciBsZXZlbCBoaXQgZGV0ZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3BpeGVsLmpzXCIpLlBpeGVsfSBwaXhlbCBQaXhlbC5cbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxpbXBvcnQoXCIuLi8uLi9GZWF0dXJlXCIpLmRlZmF1bHQ+Pn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggYW4gYXJyYXkgb2YgZmVhdHVyZXMuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLmdldEZlYXR1cmVzID0gZnVuY3Rpb24gKHBpeGVsKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciBsYXllciA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICAgIHZhciBsYXllclVpZCA9IGdldFVpZChsYXllcik7XG4gICAgICB2YXIgc291cmNlID0gbGF5ZXIuZ2V0U291cmNlKCk7XG4gICAgICB2YXIgcHJvamVjdGlvbiA9IHRoaXMucmVuZGVyZWRQcm9qZWN0aW9uO1xuICAgICAgdmFyIHByb2plY3Rpb25FeHRlbnQgPSBwcm9qZWN0aW9uLmdldEV4dGVudCgpO1xuICAgICAgdmFyIHJlc29sdXRpb24gPSB0aGlzLnJlbmRlcmVkUmVzb2x1dGlvbjtcbiAgICAgIHZhciB0aWxlR3JpZCA9IHNvdXJjZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgICB2YXIgY29vcmRpbmF0ZSA9IGFwcGx5VHJhbnNmb3JtKHRoaXMucmVuZGVyZWRQaXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybV8sIHBpeGVsLnNsaWNlKCkpO1xuICAgICAgdmFyIHRpbGVDb29yZCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEZvckNvb3JkQW5kUmVzb2x1dGlvbihjb29yZGluYXRlLCByZXNvbHV0aW9uKTtcbiAgICAgIHZhciB0aWxlO1xuXG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSB0aGlzLnJlbmRlcmVkVGlsZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBpZiAodGlsZUNvb3JkLnRvU3RyaW5nKCkgPT09IHRoaXMucmVuZGVyZWRUaWxlc1tpXS50aWxlQ29vcmQudG9TdHJpbmcoKSkge1xuICAgICAgICAgIHRpbGUgPSB0aGlzLnJlbmRlcmVkVGlsZXNbaV07XG5cbiAgICAgICAgICBpZiAodGlsZS5nZXRTdGF0ZSgpID09PSBUaWxlU3RhdGUuTE9BREVEICYmIHRpbGUuaGlmaSkge1xuICAgICAgICAgICAgdmFyIGV4dGVudF8xID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGUudGlsZUNvb3JkKTtcblxuICAgICAgICAgICAgaWYgKHNvdXJjZS5nZXRXcmFwWCgpICYmIHByb2plY3Rpb24uY2FuV3JhcFgoKSAmJiAhY29udGFpbnNFeHRlbnQocHJvamVjdGlvbkV4dGVudCwgZXh0ZW50XzEpKSB7XG4gICAgICAgICAgICAgIHdyYXBYKGNvb3JkaW5hdGUsIHByb2plY3Rpb24pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aWxlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghdGlsZSB8fCB0aWxlLmxvYWRpbmdTb3VyY2VUaWxlcyA+IDApIHtcbiAgICAgICAgcmVzb2x2ZShbXSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlLndyYXBwZWRUaWxlQ29vcmQpO1xuICAgICAgdmFyIGNvcm5lciA9IGdldFRvcExlZnQoZXh0ZW50KTtcbiAgICAgIHZhciB0aWxlUGl4ZWwgPSBbKGNvb3JkaW5hdGVbMF0gLSBjb3JuZXJbMF0pIC8gcmVzb2x1dGlvbiwgKGNvcm5lclsxXSAtIGNvb3JkaW5hdGVbMV0pIC8gcmVzb2x1dGlvbl07XG4gICAgICB2YXIgZmVhdHVyZXMgPSB0aWxlLmdldFNvdXJjZVRpbGVzKCkucmVkdWNlKGZ1bmN0aW9uIChhY2N1bXVsYXRvciwgc291cmNlVGlsZSkge1xuICAgICAgICByZXR1cm4gYWNjdW11bGF0b3IuY29uY2F0KHNvdXJjZVRpbGUuZ2V0RmVhdHVyZXMoKSk7XG4gICAgICB9LCBbXSk7XG4gICAgICB2YXIgaGl0RGV0ZWN0aW9uSW1hZ2VEYXRhID0gdGlsZS5oaXREZXRlY3Rpb25JbWFnZURhdGFbbGF5ZXJVaWRdO1xuXG4gICAgICBpZiAoIWhpdERldGVjdGlvbkltYWdlRGF0YSAmJiAhdGhpcy5hbmltYXRpbmdPckludGVyYWN0aW5nXykge1xuICAgICAgICB2YXIgdGlsZVNpemUgPSB0b1NpemUodGlsZUdyaWQuZ2V0VGlsZVNpemUodGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbikpKTtcbiAgICAgICAgdmFyIHNpemUgPSBbdGlsZVNpemVbMF0gLyAyLCB0aWxlU2l6ZVsxXSAvIDJdO1xuICAgICAgICB2YXIgcm90YXRpb24gPSB0aGlzLnJlbmRlcmVkUm90YXRpb25fO1xuICAgICAgICB2YXIgdHJhbnNmb3JtcyA9IFt0aGlzLmdldFJlbmRlclRyYW5zZm9ybSh0aWxlR3JpZC5nZXRUaWxlQ29vcmRDZW50ZXIodGlsZS53cmFwcGVkVGlsZUNvb3JkKSwgcmVzb2x1dGlvbiwgMCwgMC41LCBzaXplWzBdLCBzaXplWzFdLCAwKV07XG4gICAgICAgIGhpdERldGVjdGlvbkltYWdlRGF0YSA9IGNyZWF0ZUhpdERldGVjdGlvbkltYWdlRGF0YSh0aWxlU2l6ZSwgdHJhbnNmb3JtcywgZmVhdHVyZXMsIGxheWVyLmdldFN0eWxlRnVuY3Rpb24oKSwgdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGUud3JhcHBlZFRpbGVDb29yZCksIHRpbGUuZ2V0UmVwbGF5U3RhdGUobGF5ZXIpLnJlbmRlcmVkUmVzb2x1dGlvbiwgcm90YXRpb24pO1xuICAgICAgICB0aWxlLmhpdERldGVjdGlvbkltYWdlRGF0YVtsYXllclVpZF0gPSBoaXREZXRlY3Rpb25JbWFnZURhdGE7XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmUoaGl0RGV0ZWN0KHRpbGVQaXhlbCwgZmVhdHVyZXMsIGhpdERldGVjdGlvbkltYWdlRGF0YSkpO1xuICAgIH0uYmluZCh0aGlzKSk7XG4gIH07XG4gIC8qKlxuICAgKiBQZXJmb3JtIGFjdGlvbiBuZWNlc3NhcnkgdG8gZ2V0IHRoZSBsYXllciByZW5kZXJlZCBhZnRlciBuZXcgZm9udHMgaGF2ZSBsb2FkZWRcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaGFuZGxlRm9udHNDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIGNsZWFyKHRoaXMucmVuZGVyVGlsZUltYWdlUXVldWVfKTtcbiAgICB2YXIgbGF5ZXIgPSB0aGlzLmdldExheWVyKCk7XG5cbiAgICBpZiAobGF5ZXIuZ2V0VmlzaWJsZSgpICYmIHRoaXMucmVuZGVyZWRMYXllclJldmlzaW9uXyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBsYXllci5jaGFuZ2VkKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlIGNoYW5nZXMgaW4gaW1hZ2Ugc3R5bGUgc3RhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vZXZlbnRzL0V2ZW50LmpzXCIpLmRlZmF1bHR9IGV2ZW50IEltYWdlIHN0eWxlIGNoYW5nZSBldmVudC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUuaGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB0aGlzLnJlbmRlcklmUmVhZHlBbmRWaXNpYmxlKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgZGVjbHV0dGVyIGl0ZW1zIGZvciB0aGlzIGxheWVyXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vUGx1Z2dhYmxlTWFwLmpzXCIpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckRlY2x1dHRlciA9IGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgdmFyIHZpZXdIaW50cyA9IGZyYW1lU3RhdGUudmlld0hpbnRzO1xuICAgIHZhciBoaWZpID0gISh2aWV3SGludHNbVmlld0hpbnQuQU5JTUFUSU5HXSB8fCB2aWV3SGludHNbVmlld0hpbnQuSU5URVJBQ1RJTkddKTtcbiAgICB2YXIgdGlsZXMgPVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi4vLi4vVmVjdG9yUmVuZGVyVGlsZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICB0aGlzLnJlbmRlcmVkVGlsZXM7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSB0aWxlcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgdGlsZSA9IHRpbGVzW2ldO1xuICAgICAgdmFyIGRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzID0gdGlsZS5kZWNsdXR0ZXJFeGVjdXRvckdyb3Vwc1tnZXRVaWQodGhpcy5nZXRMYXllcigpKV07XG5cbiAgICAgIGlmIChkZWNsdXR0ZXJFeGVjdXRvckdyb3Vwcykge1xuICAgICAgICBmb3IgKHZhciBqID0gZGVjbHV0dGVyRXhlY3V0b3JHcm91cHMubGVuZ3RoIC0gMTsgaiA+PSAwOyAtLWopIHtcbiAgICAgICAgICBkZWNsdXR0ZXJFeGVjdXRvckdyb3Vwc1tqXS5leGVjdXRlKHRoaXMuY29udGV4dCwgMSwgdGhpcy5nZXRUaWxlUmVuZGVyVHJhbnNmb3JtKHRpbGUsIGZyYW1lU3RhdGUpLCBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yb3RhdGlvbiwgaGlmaSwgdW5kZWZpbmVkLCBmcmFtZVN0YXRlLmRlY2x1dHRlclRyZWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIENhbnZhc1ZlY3RvclRpbGVMYXllclJlbmRlcmVyLnByb3RvdHlwZS5nZXRUaWxlUmVuZGVyVHJhbnNmb3JtID0gZnVuY3Rpb24gKHRpbGUsIGZyYW1lU3RhdGUpIHtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdmFyIGNlbnRlciA9IHZpZXdTdGF0ZS5jZW50ZXI7XG4gICAgdmFyIHJlc29sdXRpb24gPSB2aWV3U3RhdGUucmVzb2x1dGlvbjtcbiAgICB2YXIgcm90YXRpb24gPSB2aWV3U3RhdGUucm90YXRpb247XG4gICAgdmFyIHNpemUgPSBmcmFtZVN0YXRlLnNpemU7XG4gICAgdmFyIHdpZHRoID0gTWF0aC5yb3VuZChzaXplWzBdICogcGl4ZWxSYXRpbyk7XG4gICAgdmFyIGhlaWdodCA9IE1hdGgucm91bmQoc2l6ZVsxXSAqIHBpeGVsUmF0aW8pO1xuICAgIHZhciBzb3VyY2UgPSB0aGlzLmdldExheWVyKCkuZ2V0U291cmNlKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihmcmFtZVN0YXRlLnZpZXdTdGF0ZS5wcm9qZWN0aW9uKTtcbiAgICB2YXIgdGlsZUNvb3JkID0gdGlsZS50aWxlQ29vcmQ7XG4gICAgdmFyIHRpbGVFeHRlbnQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZS53cmFwcGVkVGlsZUNvb3JkKTtcbiAgICB2YXIgd29ybGRPZmZzZXQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZUNvb3JkLCB0aGlzLnRtcEV4dGVudClbMF0gLSB0aWxlRXh0ZW50WzBdO1xuICAgIHZhciB0cmFuc2Zvcm0gPSBtdWx0aXBseShzY2FsZSh0aGlzLmludmVyc2VQaXhlbFRyYW5zZm9ybS5zbGljZSgpLCAxIC8gcGl4ZWxSYXRpbywgMSAvIHBpeGVsUmF0aW8pLCB0aGlzLmdldFJlbmRlclRyYW5zZm9ybShjZW50ZXIsIHJlc29sdXRpb24sIHJvdGF0aW9uLCBwaXhlbFJhdGlvLCB3aWR0aCwgaGVpZ2h0LCB3b3JsZE9mZnNldCkpO1xuICAgIHJldHVybiB0cmFuc2Zvcm07XG4gIH07XG4gIC8qKlxuICAgKiBSZW5kZXIgdGhlIGxheWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1BsdWdnYWJsZU1hcC5qc1wiKS5GcmFtZVN0YXRlfSBmcmFtZVN0YXRlIEZyYW1lIHN0YXRlLlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YXJnZXQgVGFyZ2V0IHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVuZGVyIGNvbnRlbnQgdG8uXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgcmVuZGVyZWQgZWxlbWVudC5cbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyRnJhbWUgPSBmdW5jdGlvbiAoZnJhbWVTdGF0ZSwgdGFyZ2V0KSB7XG4gICAgdmFyIHZpZXdIaW50cyA9IGZyYW1lU3RhdGUudmlld0hpbnRzO1xuICAgIHZhciBoaWZpID0gISh2aWV3SGludHNbVmlld0hpbnQuQU5JTUFUSU5HXSB8fCB2aWV3SGludHNbVmlld0hpbnQuSU5URVJBQ1RJTkddKTtcbiAgICB0aGlzLnJlbmRlclF1ZXVlZFRpbGVJbWFnZXNfKGhpZmksIGZyYW1lU3RhdGUpO1xuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5yZW5kZXJGcmFtZS5jYWxsKHRoaXMsIGZyYW1lU3RhdGUsIHRhcmdldCk7XG5cbiAgICB0aGlzLnJlbmRlcmVkUGl4ZWxUb0Nvb3JkaW5hdGVUcmFuc2Zvcm1fID0gZnJhbWVTdGF0ZS5waXhlbFRvQ29vcmRpbmF0ZVRyYW5zZm9ybS5zbGljZSgpO1xuICAgIHRoaXMucmVuZGVyZWRSb3RhdGlvbl8gPSBmcmFtZVN0YXRlLnZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgcmVuZGVyTW9kZSA9IGxheWVyLmdldFJlbmRlck1vZGUoKTtcblxuICAgIGlmIChyZW5kZXJNb2RlID09PSBWZWN0b3JUaWxlUmVuZGVyVHlwZS5JTUFHRSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTsgLy8gVW5xdWV1ZSB0aWxlcyBmcm9tIHRoZSBpbWFnZSBxdWV1ZSB3aGVuIHdlIGRvbid0IG5lZWQgYW55IG1vcmVcblxuICAgIHZhciB1c2VkVGlsZXMgPSBmcmFtZVN0YXRlLnVzZWRUaWxlc1tnZXRVaWQoc291cmNlKV07XG5cbiAgICBmb3IgKHZhciB0aWxlVWlkIGluIHRoaXMucmVuZGVyVGlsZUltYWdlUXVldWVfKSB7XG4gICAgICBpZiAoIXVzZWRUaWxlcyB8fCAhKHRpbGVVaWQgaW4gdXNlZFRpbGVzKSkge1xuICAgICAgICBkZWxldGUgdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV9bdGlsZVVpZF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG4gICAgdmFyIHJlcGxheVR5cGVzID0gVkVDVE9SX1JFUExBWVNbcmVuZGVyTW9kZV07XG4gICAgdmFyIHZpZXdTdGF0ZSA9IGZyYW1lU3RhdGUudmlld1N0YXRlO1xuICAgIHZhciByb3RhdGlvbiA9IHZpZXdTdGF0ZS5yb3RhdGlvbjtcbiAgICB2YXIgdGlsZXMgPSB0aGlzLnJlbmRlcmVkVGlsZXM7XG4gICAgdmFyIGNsaXBzID0gW107XG4gICAgdmFyIGNsaXBacyA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IHRpbGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICB2YXIgdGlsZSA9XG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICAgIHRpbGVzW2ldO1xuICAgICAgdmFyIHRyYW5zZm9ybSA9IHRoaXMuZ2V0VGlsZVJlbmRlclRyYW5zZm9ybSh0aWxlLCBmcmFtZVN0YXRlKTtcbiAgICAgIHZhciBleGVjdXRvckdyb3VwcyA9IHRpbGUuZXhlY3V0b3JHcm91cHNbZ2V0VWlkKGxheWVyKV07XG4gICAgICB2YXIgY2xpcHBlZCA9IGZhbHNlO1xuXG4gICAgICBmb3IgKHZhciB0ID0gMCwgdHQgPSBleGVjdXRvckdyb3Vwcy5sZW5ndGg7IHQgPCB0dDsgKyt0KSB7XG4gICAgICAgIHZhciBleGVjdXRvckdyb3VwID0gZXhlY3V0b3JHcm91cHNbdF07XG5cbiAgICAgICAgaWYgKCFleGVjdXRvckdyb3VwLmhhc0V4ZWN1dG9ycyhyZXBsYXlUeXBlcykpIHtcbiAgICAgICAgICAvLyBzb3VyY2VUaWxlIGhhcyBubyBpbnN0cnVjdGlvbnMgb2YgdGhlIHR5cGVzIHdlIHdhbnQgdG8gcmVuZGVyXG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY3VycmVudFogPSB0aWxlLnRpbGVDb29yZFswXTtcbiAgICAgICAgdmFyIGN1cnJlbnRDbGlwID0gdm9pZCAwO1xuXG4gICAgICAgIGlmICghY2xpcHBlZCkge1xuICAgICAgICAgIGN1cnJlbnRDbGlwID0gZXhlY3V0b3JHcm91cC5nZXRDbGlwQ29vcmRzKHRyYW5zZm9ybSk7XG5cbiAgICAgICAgICBpZiAoY3VycmVudENsaXApIHtcbiAgICAgICAgICAgIGNvbnRleHQuc2F2ZSgpOyAvLyBDcmVhdGUgYSBjbGlwIG1hc2sgZm9yIHJlZ2lvbnMgaW4gdGhpcyBsb3cgcmVzb2x1dGlvbiB0aWxlIHRoYXQgYXJlXG4gICAgICAgICAgICAvLyBhbHJlYWR5IGZpbGxlZCBieSBhIGhpZ2hlciByZXNvbHV0aW9uIHRpbGVcblxuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gY2xpcHMubGVuZ3RoOyBqIDwgamo7ICsraikge1xuICAgICAgICAgICAgICB2YXIgY2xpcCA9IGNsaXBzW2pdO1xuXG4gICAgICAgICAgICAgIGlmIChjdXJyZW50WiA8IGNsaXBac1tqXSkge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7IC8vIGNvdW50ZXItY2xvY2t3aXNlIChvdXRlciByaW5nKSBmb3IgY3VycmVudCB0aWxlXG5cbiAgICAgICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyhjdXJyZW50Q2xpcFswXSwgY3VycmVudENsaXBbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnRleHQubGluZVRvKGN1cnJlbnRDbGlwWzJdLCBjdXJyZW50Q2xpcFszXSk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5saW5lVG8oY3VycmVudENsaXBbNF0sIGN1cnJlbnRDbGlwWzVdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjdXJyZW50Q2xpcFs2XSwgY3VycmVudENsaXBbN10pOyAvLyBjbG9ja3dpc2UgKGlubmVyIHJpbmcpIGZvciBoaWdoZXIgcmVzb2x1dGlvbiB0aWxlXG5cbiAgICAgICAgICAgICAgICBjb250ZXh0Lm1vdmVUbyhjbGlwWzZdLCBjbGlwWzddKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzRdLCBjbGlwWzVdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzJdLCBjbGlwWzNdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmxpbmVUbyhjbGlwWzBdLCBjbGlwWzFdKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmNsaXAoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGV4ZWN1dG9yR3JvdXAuZXhlY3V0ZShjb250ZXh0LCAxLCB0cmFuc2Zvcm0sIHJvdGF0aW9uLCBoaWZpLCByZXBsYXlUeXBlcyk7XG5cbiAgICAgICAgaWYgKCFjbGlwcGVkICYmIGN1cnJlbnRDbGlwKSB7XG4gICAgICAgICAgY29udGV4dC5yZXN0b3JlKCk7XG4gICAgICAgICAgY2xpcHMucHVzaChjdXJyZW50Q2xpcCk7XG4gICAgICAgICAgY2xpcFpzLnB1c2goY3VycmVudFopO1xuICAgICAgICAgIGNsaXBwZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29udGFpbmVyO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtib29sZWFufSBoaWZpIFdlIGhhdmUgdGltZSB0byByZW5kZXIgYSBoaWdoIGZpZGVsaXR5IG1hcCBpbWFnZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoJy4uLy4uL1BsdWdnYWJsZU1hcC5qcycpLkZyYW1lU3RhdGV9IGZyYW1lU3RhdGUgRnJhbWUgc3RhdGUuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlclF1ZXVlZFRpbGVJbWFnZXNfID0gZnVuY3Rpb24gKGhpZmksIGZyYW1lU3RhdGUpIHtcbiAgICAvLyBXaGVuIHdlIGRvbid0IGhhdmUgdGltZSB0byByZW5kZXIgaGlmaSwgb25seSByZW5kZXIgdGlsZXMgdW50aWwgd2UgaGF2ZSB1c2VkIHVwXG4gICAgLy8gaGFsZiBvZiB0aGUgZnJhbWUgYnVkZ2V0IG9mIDE2IG1zXG4gICAgZm9yICh2YXIgdWlkIGluIHRoaXMucmVuZGVyVGlsZUltYWdlUXVldWVfKSB7XG4gICAgICBpZiAoIWhpZmkgJiYgRGF0ZS5ub3coKSAtIGZyYW1lU3RhdGUudGltZSA+IDgpIHtcbiAgICAgICAgZnJhbWVTdGF0ZS5hbmltYXRlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHZhciB0aWxlID0gdGhpcy5yZW5kZXJUaWxlSW1hZ2VRdWV1ZV9bdWlkXTtcbiAgICAgIGRlbGV0ZSB0aGlzLnJlbmRlclRpbGVJbWFnZVF1ZXVlX1t1aWRdO1xuICAgICAgdGhpcy5yZW5kZXJUaWxlSW1hZ2VfKHRpbGUsIGZyYW1lU3RhdGUpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZX0gZmVhdHVyZSBGZWF0dXJlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gc3F1YXJlZFRvbGVyYW5jZSBTcXVhcmVkIHRvbGVyYW5jZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9zdHlsZS9TdHlsZS5qc1wiKS5kZWZhdWx0fEFycmF5PGltcG9ydChcIi4uLy4uL3N0eWxlL1N0eWxlLmpzXCIpLmRlZmF1bHQ+fSBzdHlsZXMgVGhlIHN0eWxlIG9yIGFycmF5IG9mIHN0eWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9yZW5kZXIvY2FudmFzL0J1aWxkZXJHcm91cC5qc1wiKS5kZWZhdWx0fSBidWlsZGVyR3JvdXAgUmVwbGF5IGdyb3VwLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3JlbmRlci9jYW52YXMvQnVpbGRlckdyb3VwLmpzXCIpLmRlZmF1bHQ9fSBvcHRfZGVjbHV0dGVyQnVpbGRlckdyb3VwIEJ1aWxkZXIgZ3JvdXAgZm9yIGRlY2x1dHRlcmluZy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIGFuIGltYWdlIGlzIGxvYWRpbmcuXG4gICAqL1xuXG5cbiAgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlckZlYXR1cmUgPSBmdW5jdGlvbiAoZmVhdHVyZSwgc3F1YXJlZFRvbGVyYW5jZSwgc3R5bGVzLCBidWlsZGVyR3JvdXAsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHtcbiAgICBpZiAoIXN0eWxlcykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBsb2FkaW5nID0gZmFsc2U7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzdHlsZXMpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBzdHlsZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgICAgICBsb2FkaW5nID0gcmVuZGVyRmVhdHVyZShidWlsZGVyR3JvdXAsIGZlYXR1cmUsIHN0eWxlc1tpXSwgc3F1YXJlZFRvbGVyYW5jZSwgdGhpcy5ib3VuZEhhbmRsZVN0eWxlSW1hZ2VDaGFuZ2VfLCB1bmRlZmluZWQsIG9wdF9kZWNsdXR0ZXJCdWlsZGVyR3JvdXApIHx8IGxvYWRpbmc7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvYWRpbmcgPSByZW5kZXJGZWF0dXJlKGJ1aWxkZXJHcm91cCwgZmVhdHVyZSwgc3R5bGVzLCBzcXVhcmVkVG9sZXJhbmNlLCB0aGlzLmJvdW5kSGFuZGxlU3R5bGVJbWFnZUNoYW5nZV8sIHVuZGVmaW5lZCwgb3B0X2RlY2x1dHRlckJ1aWxkZXJHcm91cCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvYWRpbmc7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL1ZlY3RvclJlbmRlclRpbGUuanNcIikuZGVmYXVsdH0gdGlsZSBUaWxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBBIG5ldyB0aWxlIGltYWdlIHdhcyByZW5kZXJlZC5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUudGlsZUltYWdlTmVlZHNSZW5kZXJfID0gZnVuY3Rpb24gKHRpbGUsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICB2YXIgbGF5ZXIgPVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vLi4vbGF5ZXIvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIHRoaXMuZ2V0TGF5ZXIoKTtcbiAgICB2YXIgcmVwbGF5U3RhdGUgPSB0aWxlLmdldFJlcGxheVN0YXRlKGxheWVyKTtcbiAgICB2YXIgcmV2aXNpb24gPSBsYXllci5nZXRSZXZpc2lvbigpO1xuICAgIHZhciBzb3VyY2VaID0gdGlsZS5zb3VyY2VaO1xuICAgIHZhciByZXNvbHV0aW9uID0gdGlsZS53YW50ZWRSZXNvbHV0aW9uO1xuICAgIHJldHVybiByZXBsYXlTdGF0ZS5yZW5kZXJlZFRpbGVSZXNvbHV0aW9uICE9PSByZXNvbHV0aW9uIHx8IHJlcGxheVN0YXRlLnJlbmRlcmVkVGlsZVJldmlzaW9uICE9PSByZXZpc2lvbiB8fCByZXBsYXlTdGF0ZS5yZW5kZXJlZFRpbGVaICE9PSBzb3VyY2VaO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9WZWN0b3JSZW5kZXJUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVGlsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9QbHVnZ2FibGVNYXBcIikuRnJhbWVTdGF0ZX0gZnJhbWVTdGF0ZSBGcmFtZSBzdGF0ZS5cbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBDYW52YXNWZWN0b3JUaWxlTGF5ZXJSZW5kZXJlci5wcm90b3R5cGUucmVuZGVyVGlsZUltYWdlXyA9IGZ1bmN0aW9uICh0aWxlLCBmcmFtZVN0YXRlKSB7XG4gICAgdmFyIGxheWVyID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uLy4uL2xheWVyL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdH0gKi9cbiAgICB0aGlzLmdldExheWVyKCk7XG4gICAgdmFyIHJlcGxheVN0YXRlID0gdGlsZS5nZXRSZXBsYXlTdGF0ZShsYXllcik7XG4gICAgdmFyIHJldmlzaW9uID0gbGF5ZXIuZ2V0UmV2aXNpb24oKTtcbiAgICB2YXIgZXhlY3V0b3JHcm91cHMgPSB0aWxlLmV4ZWN1dG9yR3JvdXBzW2dldFVpZChsYXllcildO1xuICAgIHJlcGxheVN0YXRlLnJlbmRlcmVkVGlsZVJldmlzaW9uID0gcmV2aXNpb247XG4gICAgcmVwbGF5U3RhdGUucmVuZGVyZWRUaWxlWiA9IHRpbGUuc291cmNlWjtcbiAgICB2YXIgdGlsZUNvb3JkID0gdGlsZS53cmFwcGVkVGlsZUNvb3JkO1xuICAgIHZhciB6ID0gdGlsZUNvb3JkWzBdO1xuICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcbiAgICB2YXIgcGl4ZWxSYXRpbyA9IGZyYW1lU3RhdGUucGl4ZWxSYXRpbztcbiAgICB2YXIgdmlld1N0YXRlID0gZnJhbWVTdGF0ZS52aWV3U3RhdGU7XG4gICAgdmFyIHByb2plY3Rpb24gPSB2aWV3U3RhdGUucHJvamVjdGlvbjtcbiAgICB2YXIgdGlsZUdyaWQgPSBzb3VyY2UuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlUmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24odGlsZS50aWxlQ29vcmRbMF0pO1xuICAgIHZhciByZW5kZXJQaXhlbFJhdGlvID0gZnJhbWVTdGF0ZS5waXhlbFJhdGlvIC8gdGlsZS53YW50ZWRSZXNvbHV0aW9uICogdGlsZVJlc29sdXRpb247XG4gICAgdmFyIHJlc29sdXRpb24gPSB0aWxlR3JpZC5nZXRSZXNvbHV0aW9uKHopO1xuICAgIHZhciBjb250ZXh0ID0gdGlsZS5nZXRDb250ZXh0KGxheWVyKTsgLy8gSW5jcmVhc2UgdGlsZSBzaXplIHdoZW4gb3Zlcnpvb21pbmcgZm9yIGxvdyBwaXhlbCByYXRpbywgdG8gYXZvaWQgYmx1cnJ5IHRpbGVzXG5cbiAgICBwaXhlbFJhdGlvID0gTWF0aC5yb3VuZChNYXRoLm1heChwaXhlbFJhdGlvLCByZW5kZXJQaXhlbFJhdGlvIC8gcGl4ZWxSYXRpbykpO1xuICAgIHZhciBzaXplID0gc291cmNlLmdldFRpbGVQaXhlbFNpemUoeiwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbik7XG4gICAgY29udGV4dC5jYW52YXMud2lkdGggPSBzaXplWzBdO1xuICAgIGNvbnRleHQuY2FudmFzLmhlaWdodCA9IHNpemVbMV07XG4gICAgdmFyIHJlbmRlclNjYWxlID0gcGl4ZWxSYXRpbyAvIHJlbmRlclBpeGVsUmF0aW87XG5cbiAgICBpZiAocmVuZGVyU2NhbGUgIT09IDEpIHtcbiAgICAgIHZhciBjYW52YXNUcmFuc2Zvcm0gPSByZXNldFRyYW5zZm9ybSh0aGlzLnRtcFRyYW5zZm9ybV8pO1xuICAgICAgc2NhbGVUcmFuc2Zvcm0oY2FudmFzVHJhbnNmb3JtLCByZW5kZXJTY2FsZSwgcmVuZGVyU2NhbGUpO1xuICAgICAgY29udGV4dC5zZXRUcmFuc2Zvcm0uYXBwbHkoY29udGV4dCwgY2FudmFzVHJhbnNmb3JtKTtcbiAgICB9XG5cbiAgICB2YXIgdGlsZUV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh0aWxlQ29vcmQsIHRoaXMudG1wRXh0ZW50KTtcbiAgICB2YXIgcGl4ZWxTY2FsZSA9IHJlbmRlclBpeGVsUmF0aW8gLyByZXNvbHV0aW9uO1xuICAgIHZhciB0cmFuc2Zvcm0gPSByZXNldFRyYW5zZm9ybSh0aGlzLnRtcFRyYW5zZm9ybV8pO1xuICAgIHNjYWxlVHJhbnNmb3JtKHRyYW5zZm9ybSwgcGl4ZWxTY2FsZSwgLXBpeGVsU2NhbGUpO1xuICAgIHRyYW5zbGF0ZVRyYW5zZm9ybSh0cmFuc2Zvcm0sIC10aWxlRXh0ZW50WzBdLCAtdGlsZUV4dGVudFszXSk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBleGVjdXRvckdyb3Vwcy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgZXhlY3V0b3JHcm91cCA9IGV4ZWN1dG9yR3JvdXBzW2ldO1xuICAgICAgZXhlY3V0b3JHcm91cC5leGVjdXRlKGNvbnRleHQsIHJlbmRlclNjYWxlLCB0cmFuc2Zvcm0sIDAsIHRydWUsIElNQUdFX1JFUExBWVNbbGF5ZXIuZ2V0UmVuZGVyTW9kZSgpXSk7XG4gICAgfVxuXG4gICAgcmVwbGF5U3RhdGUucmVuZGVyZWRUaWxlUmVzb2x1dGlvbiA9IHRpbGUud2FudGVkUmVzb2x1dGlvbjtcbiAgfTtcblxuICByZXR1cm4gQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXI7XG59KENhbnZhc1RpbGVMYXllclJlbmRlcmVyKTtcblxuZXhwb3J0IGRlZmF1bHQgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXI7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9sYXllci9WZWN0b3JUaWxlXG4gKi9cblxuXG5pbXBvcnQgQmFzZVZlY3RvckxheWVyIGZyb20gJy4vQmFzZVZlY3Rvci5qcyc7XG5pbXBvcnQgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIgZnJvbSAnLi4vcmVuZGVyZXIvY2FudmFzL1ZlY3RvclRpbGVMYXllci5qcyc7XG5pbXBvcnQgVGlsZVByb3BlcnR5IGZyb20gJy4vVGlsZVByb3BlcnR5LmpzJztcbmltcG9ydCBWZWN0b3JUaWxlUmVuZGVyVHlwZSBmcm9tICcuL1ZlY3RvclRpbGVSZW5kZXJUeXBlLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnLi4vb2JqLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtjbGFzc05hbWU9J29sLWxheWVyJ10gQSBDU1MgY2xhc3MgbmFtZSB0byBzZXQgdG8gdGhlIGxheWVyIGVsZW1lbnQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW29wYWNpdHk9MV0gT3BhY2l0eSAoMCwgMSkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt2aXNpYmxlPXRydWVdIFZpc2liaWxpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IFtleHRlbnRdIFRoZSBib3VuZGluZyBleHRlbnQgZm9yIGxheWVyIHJlbmRlcmluZy4gIFRoZSBsYXllciB3aWxsIG5vdCBiZVxuICogcmVuZGVyZWQgb3V0c2lkZSBvZiB0aGlzIGV4dGVudC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekluZGV4XSBUaGUgei1pbmRleCBmb3IgbGF5ZXIgcmVuZGVyaW5nLiAgQXQgcmVuZGVyaW5nIHRpbWUsIHRoZSBsYXllcnNcbiAqIHdpbGwgYmUgb3JkZXJlZCwgZmlyc3QgYnkgWi1pbmRleCBhbmQgdGhlbiBieSBwb3NpdGlvbi4gV2hlbiBgdW5kZWZpbmVkYCwgYSBgekluZGV4YCBvZiAwIGlzIGFzc3VtZWRcbiAqIGZvciBsYXllcnMgdGhhdCBhcmUgYWRkZWQgdG8gdGhlIG1hcCdzIGBsYXllcnNgIGNvbGxlY3Rpb24sIG9yIGBJbmZpbml0eWAgd2hlbiB0aGUgbGF5ZXIncyBgc2V0TWFwKClgXG4gKiBtZXRob2Qgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW21pblJlc29sdXRpb25dIFRoZSBtaW5pbXVtIHJlc29sdXRpb24gKGluY2x1c2l2ZSkgYXQgd2hpY2ggdGhpcyBsYXllciB3aWxsIGJlXG4gKiB2aXNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhSZXNvbHV0aW9uXSBUaGUgbWF4aW11bSByZXNvbHV0aW9uIChleGNsdXNpdmUpIGJlbG93IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gVGhlIG1pbmltdW0gdmlldyB6b29tIGxldmVsIChleGNsdXNpdmUpIGFib3ZlIHdoaWNoIHRoaXMgbGF5ZXIgd2lsbCBiZVxuICogdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4Wm9vbV0gVGhlIG1heGltdW0gdmlldyB6b29tIGxldmVsIChpbmNsdXNpdmUpIGF0IHdoaWNoIHRoaXMgbGF5ZXIgd2lsbFxuICogYmUgdmlzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vcmVuZGVyLmpzXCIpLk9yZGVyRnVuY3Rpb259IFtyZW5kZXJPcmRlcl0gUmVuZGVyIG9yZGVyLiBGdW5jdGlvbiB0byBiZSB1c2VkIHdoZW4gc29ydGluZ1xuICogZmVhdHVyZXMgYmVmb3JlIHJlbmRlcmluZy4gQnkgZGVmYXVsdCBmZWF0dXJlcyBhcmUgZHJhd24gaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUgY3JlYXRlZC4gVXNlXG4gKiBgbnVsbGAgdG8gYXZvaWQgdGhlIHNvcnQsIGJ1dCBnZXQgYW4gdW5kZWZpbmVkIGRyYXcgb3JkZXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JlbmRlckJ1ZmZlcj0xMDBdIFRoZSBidWZmZXIgaW4gcGl4ZWxzIGFyb3VuZCB0aGUgdGlsZSBleHRlbnQgdXNlZCBieSB0aGVcbiAqIHJlbmRlcmVyIHdoZW4gZ2V0dGluZyBmZWF0dXJlcyBmcm9tIHRoZSB2ZWN0b3IgdGlsZSBmb3IgdGhlIHJlbmRlcmluZyBvciBoaXQtZGV0ZWN0aW9uLlxuICogUmVjb21tZW5kZWQgdmFsdWU6IFZlY3RvciB0aWxlcyBhcmUgdXN1YWxseSBnZW5lcmF0ZWQgd2l0aCBhIGJ1ZmZlciwgc28gdGhpcyB2YWx1ZSBzaG91bGQgbWF0Y2hcbiAqIHRoZSBsYXJnZXN0IHBvc3NpYmxlIGJ1ZmZlciBvZiB0aGUgdXNlZCB0aWxlcy4gSXQgc2hvdWxkIGJlIGF0IGxlYXN0IHRoZSBzaXplIG9mIHRoZSBsYXJnZXN0XG4gKiBwb2ludCBzeW1ib2wgb3IgbGluZSB3aWR0aC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9WZWN0b3JUaWxlUmVuZGVyVHlwZS5qc1wiKS5kZWZhdWx0fHN0cmluZ30gW3JlbmRlck1vZGU9J2h5YnJpZCddIFJlbmRlciBtb2RlIGZvciB2ZWN0b3IgdGlsZXM6XG4gKiAgKiBgJ2ltYWdlJ2A6IFZlY3RvciB0aWxlcyBhcmUgcmVuZGVyZWQgYXMgaW1hZ2VzLiBPbmx5IGF2YWlsYWJsZSB3aGVuIGBkZWNsdXR0ZXJgIGlzIHNldCB0byBgZmFsc2VgIChkZWZhdWx0KS5cbiAqICAgIE90aGVyd2lzZSwgYCdoeWJyaWQnYCBtb2RlIHdpbGwgdXNlZCBpbnN0ZWFkLiBHcmVhdCBwZXJmb3JtYW5jZSwgYnV0IHBvaW50IHN5bWJvbHMgYW5kIHRleHRzXG4gKiAgICBhcmUgYWx3YXlzIHJvdGF0ZWQgd2l0aCB0aGUgdmlldyBhbmQgcGl4ZWxzIGFyZSBzY2FsZWQgZHVyaW5nIHpvb20gYW5pbWF0aW9ucy4gTGFiZWxzIGFuZCBwb2ludCBzeW1ib2xzIHdpbGxcbiAqICAgIGdldCBjdXQgb2ZmIGF0IHRpbGUgYm91bmRhcmllcy5cbiAqICAqIGAnaHlicmlkJ2A6IFBvbHlnb24gYW5kIGxpbmUgZWxlbWVudHMgYXJlIHJlbmRlcmVkIGFzIGltYWdlcywgc28gcGl4ZWxzIGFyZSBzY2FsZWQgZHVyaW5nIHpvb21cbiAqICAgIGFuaW1hdGlvbnMuIFBvaW50IHN5bWJvbHMgYW5kIHRleHRzIGFyZSBhY2N1cmF0ZWx5IHJlbmRlcmVkIGFzIHZlY3RvcnMgYW5kIGNhbiBzdGF5IHVwcmlnaHQgb25cbiAqICAgIHJvdGF0ZWQgdmlld3MuXG4gKiAgKiBgJ3ZlY3RvcidgOiBFdmVyeXRoaW5nIGlzIHJlbmRlcmVkIGFzIHZlY3RvcnMuIFVzZSB0aGlzIG1vZGUgZm9yIGltcHJvdmVkIHBlcmZvcm1hbmNlIG9uIHZlY3RvclxuICogICAgdGlsZSBsYXllcnMgd2l0aCBvbmx5IGEgZmV3IHJlbmRlcmVkIGZlYXR1cmVzIChlLmcuIGZvciBoaWdobGlnaHRpbmcgYSBzdWJzZXQgb2YgZmVhdHVyZXMgb2ZcbiAqICAgIGFub3RoZXIgbGF5ZXIgd2l0aCB0aGUgc2FtZSBzb3VyY2UpLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zb3VyY2UvVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSBbc291cmNlXSBTb3VyY2UuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fSBbbWFwXSBTZXRzIHRoZSBsYXllciBhcyBvdmVybGF5IG9uIGEgbWFwLiBUaGUgbWFwIHdpbGwgbm90IG1hbmFnZVxuICogdGhpcyBsYXllciBpbiBpdHMgbGF5ZXJzIGNvbGxlY3Rpb24sIGFuZCB0aGUgbGF5ZXIgd2lsbCBiZSByZW5kZXJlZCBvbiB0b3AuIFRoaXMgaXMgdXNlZnVsIGZvclxuICogdGVtcG9yYXJ5IGxheWVycy4gVGhlIHN0YW5kYXJkIHdheSB0byBhZGQgYSBsYXllciB0byBhIG1hcCBhbmQgaGF2ZSBpdCBtYW5hZ2VkIGJ5IHRoZSBtYXAgaXMgdG9cbiAqIHVzZSB7QGxpbmsgbW9kdWxlOm9sL01hcCNhZGRMYXllcn0uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkZWNsdXR0ZXI9ZmFsc2VdIERlY2x1dHRlciBpbWFnZXMgYW5kIHRleHQuIERlY2x1dHRlcmluZyBpcyBhcHBsaWVkIHRvIGFsbFxuICogaW1hZ2UgYW5kIHRleHQgc3R5bGVzIG9mIGFsbCBWZWN0b3IgYW5kIFZlY3RvclRpbGUgbGF5ZXJzIHRoYXQgaGF2ZSBzZXQgdGhpcyB0byBgdHJ1ZWAuIFRoZSBwcmlvcml0eVxuICogaXMgZGVmaW5lZCBieSB0aGUgei1pbmRleCBvZiB0aGUgbGF5ZXIsIHRoZSBgekluZGV4YCBvZiB0aGUgc3R5bGUgYW5kIHRoZSByZW5kZXIgb3JkZXIgb2YgZmVhdHVyZXMuXG4gKiBIaWdoZXIgei1pbmRleCBtZWFucyBoaWdoZXIgcHJpb3JpdHkuIFdpdGhpbiB0aGUgc2FtZSB6LWluZGV4LCBhIGZlYXR1cmUgcmVuZGVyZWQgYmVmb3JlIGFub3RoZXIgaGFzXG4gKiBoaWdoZXIgcHJpb3JpdHkuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3N0eWxlL1N0eWxlLmpzXCIpLlN0eWxlTGlrZX0gW3N0eWxlXSBMYXllciBzdHlsZS4gU2VlXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3N0eWxlfSBmb3IgZGVmYXVsdCBzdHlsZSB3aGljaCB3aWxsIGJlIHVzZWQgaWYgdGhpcyBpcyBub3QgZGVmaW5lZC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VwZGF0ZVdoaWxlQW5pbWF0aW5nPWZhbHNlXSBXaGVuIHNldCB0byBgdHJ1ZWAsIGZlYXR1cmUgYmF0Y2hlcyB3aWxsIGJlXG4gKiByZWNyZWF0ZWQgZHVyaW5nIGFuaW1hdGlvbnMuIFRoaXMgbWVhbnMgdGhhdCBubyB2ZWN0b3JzIHdpbGwgYmUgc2hvd24gY2xpcHBlZCwgYnV0IHRoZSBzZXR0aW5nXG4gKiB3aWxsIGhhdmUgYSBwZXJmb3JtYW5jZSBpbXBhY3QgZm9yIGxhcmdlIGFtb3VudHMgb2YgdmVjdG9yIGRhdGEuIFdoZW4gc2V0IHRvIGBmYWxzZWAsIGJhdGNoZXNcbiAqIHdpbGwgYmUgcmVjcmVhdGVkIHdoZW4gbm8gYW5pbWF0aW9uIGlzIGFjdGl2ZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VwZGF0ZVdoaWxlSW50ZXJhY3Rpbmc9ZmFsc2VdIFdoZW4gc2V0IHRvIGB0cnVlYCwgZmVhdHVyZSBiYXRjaGVzIHdpbGwgYmVcbiAqIHJlY3JlYXRlZCBkdXJpbmcgaW50ZXJhY3Rpb25zLiBTZWUgYWxzbyBgdXBkYXRlV2hpbGVBbmltYXRpbmdgLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtwcmVsb2FkPTBdIFByZWxvYWQuIExvYWQgbG93LXJlc29sdXRpb24gdGlsZXMgdXAgdG8gYHByZWxvYWRgIGxldmVscy4gYDBgXG4gKiBtZWFucyBubyBwcmVsb2FkaW5nLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbdXNlSW50ZXJpbVRpbGVzT25FcnJvcj10cnVlXSBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIExheWVyIGZvciB2ZWN0b3IgdGlsZSBkYXRhIHRoYXQgaXMgcmVuZGVyZWQgY2xpZW50LXNpZGUuXG4gKiBOb3RlIHRoYXQgYW55IHByb3BlcnR5IHNldCBpbiB0aGUgb3B0aW9ucyBpcyBzZXQgYXMgYSB7QGxpbmsgbW9kdWxlOm9sL09iamVjdH5CYXNlT2JqZWN0fVxuICogcHJvcGVydHkgb24gdGhlIGxheWVyIG9iamVjdDsgZm9yIGV4YW1wbGUsIHNldHRpbmcgYHRpdGxlOiAnTXkgVGl0bGUnYCBpbiB0aGVcbiAqIG9wdGlvbnMgbWVhbnMgdGhhdCBgdGl0bGVgIGlzIG9ic2VydmFibGUsIGFuZCBoYXMgZ2V0L3NldCBhY2Nlc3NvcnMuXG4gKlxuICogQHBhcmFtIHtPcHRpb25zPX0gb3B0X29wdGlvbnMgT3B0aW9ucy5cbiAqIEBleHRlbmRzIHtCYXNlVmVjdG9yTGF5ZXI8aW1wb3J0KFwiLi4vc291cmNlL1ZlY3RvclRpbGUuanNcIikuZGVmYXVsdD59XG4gKiBAYXBpXG4gKi9cblxudmFyIFZlY3RvclRpbGVMYXllciA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhWZWN0b3JUaWxlTGF5ZXIsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnM9fSBvcHRfb3B0aW9ucyBPcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFZlY3RvclRpbGVMYXllcihvcHRfb3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICB2YXIgb3B0aW9ucyA9IG9wdF9vcHRpb25zID8gb3B0X29wdGlvbnMgOiB7fTtcbiAgICB2YXIgYmFzZU9wdGlvbnMgPVxuICAgIC8qKiBAdHlwZSB7T2JqZWN0fSAqL1xuICAgIGFzc2lnbih7fSwgb3B0aW9ucyk7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnByZWxvYWQ7XG4gICAgZGVsZXRlIGJhc2VPcHRpb25zLnVzZUludGVyaW1UaWxlc09uRXJyb3I7XG4gICAgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9CYXNlVmVjdG9yLmpzXCIpLk9wdGlvbnN9ICovXG4gICAgYmFzZU9wdGlvbnMpIHx8IHRoaXM7XG4gICAgdmFyIHJlbmRlck1vZGUgPSBvcHRpb25zLnJlbmRlck1vZGUgfHwgVmVjdG9yVGlsZVJlbmRlclR5cGUuSFlCUklEO1xuICAgIGFzc2VydChyZW5kZXJNb2RlID09IHVuZGVmaW5lZCB8fCByZW5kZXJNb2RlID09IFZlY3RvclRpbGVSZW5kZXJUeXBlLklNQUdFIHx8IHJlbmRlck1vZGUgPT0gVmVjdG9yVGlsZVJlbmRlclR5cGUuSFlCUklEIHx8IHJlbmRlck1vZGUgPT0gVmVjdG9yVGlsZVJlbmRlclR5cGUuVkVDVE9SLCAyOCk7IC8vIGByZW5kZXJNb2RlYCBtdXN0IGJlIGAnaW1hZ2UnYCwgYCdoeWJyaWQnYCBvciBgJ3ZlY3RvcidgLlxuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9WZWN0b3JUaWxlUmVuZGVyVHlwZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyTW9kZV8gPSByZW5kZXJNb2RlO1xuXG4gICAgX3RoaXMuc2V0UHJlbG9hZChvcHRpb25zLnByZWxvYWQgPyBvcHRpb25zLnByZWxvYWQgOiAwKTtcblxuICAgIF90aGlzLnNldFVzZUludGVyaW1UaWxlc09uRXJyb3Iob3B0aW9ucy51c2VJbnRlcmltVGlsZXNPbkVycm9yICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnVzZUludGVyaW1UaWxlc09uRXJyb3IgOiB0cnVlKTtcblxuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlIGEgcmVuZGVyZXIgZm9yIHRoaXMgbGF5ZXIuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3JlbmRlcmVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IEEgbGF5ZXIgcmVuZGVyZXIuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBWZWN0b3JUaWxlTGF5ZXIucHJvdG90eXBlLmNyZWF0ZVJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBuZXcgQ2FudmFzVmVjdG9yVGlsZUxheWVyUmVuZGVyZXIodGhpcyk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRvcG1vc3QgZmVhdHVyZSB0aGF0IGludGVyc2VjdHMgdGhlIGdpdmVuIHBpeGVsIG9uIHRoZSB2aWV3cG9ydC4gUmV0dXJucyBhIHByb21pc2VcbiAgICogdGhhdCByZXNvbHZlcyB3aXRoIGFuIGFycmF5IG9mIGZlYXR1cmVzLiBUaGUgYXJyYXkgd2lsbCBlaXRoZXIgY29udGFpbiB0aGUgdG9wbW9zdCBmZWF0dXJlXG4gICAqIHdoZW4gYSBoaXQgd2FzIGRldGVjdGVkLCBvciBpdCB3aWxsIGJlIGVtcHR5LlxuICAgKlxuICAgKiBUaGUgaGl0IGRldGVjdGlvbiBhbGdvcml0aG0gdXNlZCBmb3IgdGhpcyBtZXRob2QgaXMgb3B0aW1pemVkIGZvciBwZXJmb3JtYW5jZSwgYnV0IGlzIGxlc3NcbiAgICogYWNjdXJhdGUgdGhhbiB0aGUgb25lIHVzZWQgaW4ge0BsaW5rIGltcG9ydChcIi4uL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0I2dldEZlYXR1cmVzQXRQaXhlbH06IFRleHRcbiAgICogaXMgbm90IGNvbnNpZGVyZWQsIGFuZCBpY29ucyBhcmUgb25seSByZXByZXNlbnRlZCBieSB0aGVpciBib3VuZGluZyBib3ggaW5zdGVhZCBvZiB0aGUgZXhhY3RcbiAgICogaW1hZ2UuXG4gICAqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFBpeGVsLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PGltcG9ydChcIi4uL0ZlYXR1cmVcIikuZGVmYXVsdD4+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCBhbiBhcnJheSBvZiBmZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAocGl4ZWwpIHtcbiAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRGZWF0dXJlcy5jYWxsKHRoaXMsIHBpeGVsKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vVmVjdG9yVGlsZVJlbmRlclR5cGUuanNcIikuZGVmYXVsdH0gVGhlIHJlbmRlciBtb2RlLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuZ2V0UmVuZGVyTW9kZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJNb2RlXztcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgbGV2ZWwgYXMgbnVtYmVyIHRvIHdoaWNoIHdlIHdpbGwgcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaGUgbGV2ZWwgdG8gcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuZ2V0UHJlbG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgICB0aGlzLmdldChUaWxlUHJvcGVydHkuUFJFTE9BRClcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogV2hldGhlciB3ZSB1c2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVXNlIGludGVyaW0gdGlsZXMgb24gZXJyb3IuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlTGF5ZXIucHJvdG90eXBlLmdldFVzZUludGVyaW1UaWxlc09uRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgICAgIHRoaXMuZ2V0KFRpbGVQcm9wZXJ0eS5VU0VfSU5URVJJTV9USUxFU19PTl9FUlJPUilcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBsZXZlbCBhcyBudW1iZXIgdG8gd2hpY2ggd2Ugd2lsbCBwcmVsb2FkIHRpbGVzIHVwIHRvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcHJlbG9hZCBUaGUgbGV2ZWwgdG8gcHJlbG9hZCB0aWxlcyB1cCB0by5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuc2V0UHJlbG9hZCA9IGZ1bmN0aW9uIChwcmVsb2FkKSB7XG4gICAgdGhpcy5zZXQoVGlsZVByb3BlcnR5LlBSRUxPQUQsIHByZWxvYWQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHdoZXRoZXIgd2UgdXNlIGludGVyaW0gdGlsZXMgb24gZXJyb3IuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXNlSW50ZXJpbVRpbGVzT25FcnJvciBVc2UgaW50ZXJpbSB0aWxlcyBvbiBlcnJvci5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGVMYXllci5wcm90b3R5cGUuc2V0VXNlSW50ZXJpbVRpbGVzT25FcnJvciA9IGZ1bmN0aW9uICh1c2VJbnRlcmltVGlsZXNPbkVycm9yKSB7XG4gICAgdGhpcy5zZXQoVGlsZVByb3BlcnR5LlVTRV9JTlRFUklNX1RJTEVTX09OX0VSUk9SLCB1c2VJbnRlcmltVGlsZXNPbkVycm9yKTtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yVGlsZUxheWVyO1xufShCYXNlVmVjdG9yTGF5ZXIpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JUaWxlTGF5ZXI7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9UaWxlXG4gKi9cblxuXG5pbXBvcnQgRXZlbnRUYXJnZXQgZnJvbSAnLi9ldmVudHMvVGFyZ2V0LmpzJztcbmltcG9ydCBFdmVudFR5cGUgZnJvbSAnLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IHsgYWJzdHJhY3QgfSBmcm9tICcuL3V0aWwuanMnO1xuaW1wb3J0IHsgZWFzZUluIH0gZnJvbSAnLi9lYXNpbmcuanMnO1xuLyoqXG4gKiBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC9UaWxlfSBmb3IgdGhlIHRpbGUgYW5kIGFcbiAqIGB7c3RyaW5nfWAgZm9yIHRoZSB1cmwgYXMgYXJndW1lbnRzLiBUaGUgZGVmYXVsdCBpc1xuICogYGBganNcbiAqIHNvdXJjZS5zZXRUaWxlTG9hZEZ1bmN0aW9uKGZ1bmN0aW9uKHRpbGUsIHNyYykge1xuICogICB0aWxlLmdldEltYWdlKCkuc3JjID0gc3JjO1xuICogfSk7XG4gKiBgYGBcbiAqIEZvciBtb3JlIGZpbmUgZ3JhaW5lZCBjb250cm9sLCB0aGUgbG9hZCBmdW5jdGlvbiBjYW4gdXNlIGZldGNoIG9yIFhNTEh0dHBSZXF1ZXN0IGFuZCBpbnZvbHZlXG4gKiBlcnJvciBoYW5kbGluZzpcbiAqXG4gKiBgYGBqc1xuICogaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICdvbC9UaWxlU3RhdGUnO1xuICpcbiAqIHNvdXJjZS5zZXRUaWxlTG9hZEZ1bmN0aW9uKGZ1bmN0aW9uKHRpbGUsIHNyYykge1xuICogICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gKiAgIHhoci5yZXNwb25zZVR5cGUgPSAnYmxvYic7XG4gKiAgIHhoci5hZGRFdmVudExpc3RlbmVyKCdsb2FkZW5kJywgZnVuY3Rpb24gKGV2dCkge1xuICogICAgIHZhciBkYXRhID0gdGhpcy5yZXNwb25zZTtcbiAqICAgICBpZiAoZGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gKiAgICAgICB0aWxlLmdldEltYWdlKCkuc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChkYXRhKTtcbiAqICAgICB9IGVsc2Uge1xuICogICAgICAgdGlsZS5zZXRTdGF0ZShUaWxlU3RhdGUuRVJST1IpO1xuICogICAgIH1cbiAqICAgfSk7XG4gKiAgIHhoci5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGZ1bmN0aW9uICgpIHtcbiAqICAgICB0aWxlLnNldFN0YXRlKFRpbGVTdGF0ZS5FUlJPUik7XG4gKiAgIH0pO1xuICogICB4aHIub3BlbignR0VUJywgc3JjKTtcbiAqICAgeGhyLnNlbmQoKTtcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKFRpbGUsIHN0cmluZyk6IHZvaWR9IExvYWRGdW5jdGlvblxuICogQGFwaVxuICovXG5cbi8qKlxuICoge0BsaW5rIG1vZHVsZTpvbC9zb3VyY2UvVGlsZX5UaWxlfSBzb3VyY2VzIHVzZSBhIGZ1bmN0aW9uIG9mIHRoaXMgdHlwZSB0byBnZXRcbiAqIHRoZSB1cmwgdGhhdCBwcm92aWRlcyBhIHRpbGUgZm9yIGEgZ2l2ZW4gdGlsZSBjb29yZGluYXRlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgYW4ge0BsaW5rIG1vZHVsZTpvbC90aWxlY29vcmR+VGlsZUNvb3JkfSBmb3IgdGhlIHRpbGVcbiAqIGNvb3JkaW5hdGUsIGEgYHtudW1iZXJ9YCByZXByZXNlbnRpbmcgdGhlIHBpeGVsIHJhdGlvIGFuZCBhXG4gKiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0gZm9yIHRoZSBwcm9qZWN0aW9uICBhcyBhcmd1bWVudHNcbiAqIGFuZCByZXR1cm5zIGEgYHtzdHJpbmd9YCByZXByZXNlbnRpbmcgdGhlIHRpbGUgVVJMLCBvciB1bmRlZmluZWQgaWYgbm8gdGlsZVxuICogc2hvdWxkIGJlIHJlcXVlc3RlZCBmb3IgdGhlIHBhc3NlZCB0aWxlIGNvb3JkaW5hdGUuXG4gKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKGltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZCwgbnVtYmVyLFxuICogICAgICAgICAgIGltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQpOiAoc3RyaW5nfHVuZGVmaW5lZCl9IFVybEZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RyYW5zaXRpb249MjUwXSBBIGR1cmF0aW9uIGZvciB0aWxlIG9wYWNpdHlcbiAqIHRyYW5zaXRpb25zIGluIG1pbGxpc2Vjb25kcy4gQSBkdXJhdGlvbiBvZiAwIGRpc2FibGVzIHRoZSBvcGFjaXR5IHRyYW5zaXRpb24uXG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBCYXNlIGNsYXNzIGZvciB0aWxlcy5cbiAqXG4gKiBAYWJzdHJhY3RcbiAqL1xuXG52YXIgVGlsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlLCBfc3VwZXIpO1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlU3RhdGUuanNcIikuZGVmYXVsdH0gc3RhdGUgU3RhdGUuXG4gICAqIEBwYXJhbSB7T3B0aW9ucz19IG9wdF9vcHRpb25zIFRpbGUgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUaWxlKHRpbGVDb29yZCwgc3RhdGUsIG9wdF9vcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcblxuICAgIHZhciBvcHRpb25zID0gb3B0X29wdGlvbnMgPyBvcHRfb3B0aW9ucyA6IHt9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlQ29vcmQgPSB0aWxlQ29vcmQ7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1RpbGVTdGF0ZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAvKipcbiAgICAgKiBBbiBcImludGVyaW1cIiB0aWxlIGZvciB0aGlzIHRpbGUuIFRoZSBpbnRlcmltIHRpbGUgbWF5IGJlIHVzZWQgd2hpbGUgdGhpc1xuICAgICAqIG9uZSBpcyBsb2FkaW5nLCBmb3IgXCJzbW9vdGhcIiB0cmFuc2l0aW9ucyB3aGVuIGNoYW5naW5nIHBhcmFtcy9kaW1lbnNpb25zXG4gICAgICogb24gdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7VGlsZX1cbiAgICAgKi9cblxuICAgIF90aGlzLmludGVyaW1UaWxlID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBUaGUgdGlsZSBpcyBhdmFpbGFibGUgYXQgdGhlIGhpZ2hlc3QgcG9zc2libGUgcmVzb2x1dGlvbi4gU3ViY2xhc3NlcyBjYW5cbiAgICAgKiBzZXQgdGhpcyB0byBgZmFsc2VgIGluaXRpYWxseS4gVGlsZSBsb2FkIGxpc3RlbmVycyB3aWxsIG5vdCBiZVxuICAgICAqIHVucmVnaXN0ZXJlZCBiZWZvcmUgdGhpcyBpcyBzZXQgdG8gYHRydWVgIGFuZCBhIGAjY2hhbmdlZCgpYCBpcyBjYWxsZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaWZpID0gdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBBIGtleSBhc3NpZ25lZCB0byB0aGUgdGlsZS4gVGhpcyBpcyB1c2VkIGJ5IHRoZSB0aWxlIHNvdXJjZSB0byBkZXRlcm1pbmVcbiAgICAgKiBpZiB0aGlzIHRpbGUgY2FuIGVmZmVjdGl2ZWx5IGJlIHVzZWQsIG9yIGlmIGEgbmV3IHRpbGUgc2hvdWxkIGJlIGNyZWF0ZWRcbiAgICAgKiBhbmQgdGhpcyBvbmUgYmUgdXNlZCBhcyBhbiBpbnRlcmltIHRpbGUgZm9yIHRoaXMgbmV3IHRpbGUuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLmtleSA9ICcnO1xuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBmb3IgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbi5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhbnNpdGlvbl8gPSBvcHRpb25zLnRyYW5zaXRpb24gPT09IHVuZGVmaW5lZCA/IDI1MCA6IG9wdGlvbnMudHJhbnNpdGlvbjtcbiAgICAvKipcbiAgICAgKiBMb29rdXAgb2Ygc3RhcnQgdGltZXMgZm9yIHJlbmRlcmluZyB0cmFuc2l0aW9ucy4gIElmIHRoZSBzdGFydCB0aW1lIGlzXG4gICAgICogZXF1YWwgdG8gLTEsIHRoZSB0cmFuc2l0aW9uIGlzIGNvbXBsZXRlLlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBudW1iZXI+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudHJhbnNpdGlvblN0YXJ0c18gPSB7fTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5jaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChFdmVudFR5cGUuQ0hBTkdFKTtcbiAgfTtcbiAgLyoqXG4gICAqIENhbGxlZCBieSB0aGUgdGlsZSBjYWNoZSB3aGVuIHRoZSB0aWxlIGlzIHJlbW92ZWQgZnJvbSB0aGUgY2FjaGUgZHVlIHRvIGV4cGlyeVxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7fTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gS2V5LlxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmdldEtleSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXkgKyAnLycgKyB0aGlzLnRpbGVDb29yZDtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgaW50ZXJpbSB0aWxlIG1vc3Qgc3VpdGFibGUgZm9yIHJlbmRlcmluZyB1c2luZyB0aGUgY2hhaW4gb2YgaW50ZXJpbVxuICAgKiB0aWxlcy4gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgIG1vc3QgcmVjZW50IHRpbGUgdGhhdCBoYXMgYmVlbiBsb2FkZWQsIGlmIG5vXG4gICAqIHN1Y2ggdGlsZSBleGlzdHMsIHRoZSBvcmlnaW5hbCB0aWxlIGlzIHJldHVybmVkLlxuICAgKiBAcmV0dXJuIHshVGlsZX0gQmVzdCB0aWxlIGZvciByZW5kZXJpbmcuXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUuZ2V0SW50ZXJpbVRpbGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmludGVyaW1UaWxlKSB7XG4gICAgICAvL2VtcHR5IGNoYWluXG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB2YXIgdGlsZSA9IHRoaXMuaW50ZXJpbVRpbGU7IC8vIGZpbmQgdGhlIGZpcnN0IGxvYWRlZCB0aWxlIGFuZCByZXR1cm4gaXQuIFNpbmNlIHRoZSBjaGFpbiBpcyBzb3J0ZWQgaW5cbiAgICAvLyBkZWNyZWFzaW5nIG9yZGVyIG9mIGNyZWF0aW9uIHRpbWUsIHRoZXJlIGlzIG5vIG5lZWQgdG8gc2VhcmNoIHRoZSByZW1haW5kZXJcbiAgICAvLyBvZiB0aGUgbGlzdCAoYWxsIHRob3NlIHRpbGVzIGNvcnJlc3BvbmQgdG8gb2xkZXIgcmVxdWVzdHMgYW5kIHdpbGwgYmVcbiAgICAvLyBjbGVhbmVkIHVwIGJ5IHJlZnJlc2hJbnRlcmltQ2hhaW4pXG5cbiAgICBkbyB7XG4gICAgICBpZiAodGlsZS5nZXRTdGF0ZSgpID09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgLy8gU2hvdyB0aWxlIGltbWVkaWF0ZWx5IGluc3RlYWQgb2YgZmFkaW5nIGl0IGluIGFmdGVyIGxvYWRpbmcsIGJlY2F1c2VcbiAgICAgICAgLy8gdGhlIGludGVyaW0gdGlsZSBpcyBpbiBwbGFjZSBhbHJlYWR5XG4gICAgICAgIHRoaXMudHJhbnNpdGlvbl8gPSAwO1xuICAgICAgICByZXR1cm4gdGlsZTtcbiAgICAgIH1cblxuICAgICAgdGlsZSA9IHRpbGUuaW50ZXJpbVRpbGU7XG4gICAgfSB3aGlsZSAodGlsZSk7IC8vIHdlIGNhbiBub3QgZmluZCBhIGJldHRlciB0aWxlXG5cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICAvKipcbiAgICogR29lcyB0aHJvdWdoIHRoZSBjaGFpbiBvZiBpbnRlcmltIHRpbGVzIGFuZCBkaXNjYXJkcyBzZWN0aW9ucyBvZiB0aGUgY2hhaW5cbiAgICogdGhhdCBhcmUgbm8gbG9uZ2VyIHJlbGV2YW50LlxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLnJlZnJlc2hJbnRlcmltQ2hhaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF0aGlzLmludGVyaW1UaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRpbGUgPSB0aGlzLmludGVyaW1UaWxlO1xuICAgIHZhciBwcmV2ID1cbiAgICAvKiogQHR5cGUge1RpbGV9ICovXG4gICAgdGhpcztcblxuICAgIGRvIHtcbiAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLkxPQURFRCkge1xuICAgICAgICAvL3dlIGhhdmUgYSBsb2FkZWQgdGlsZSwgd2UgY2FuIGRpc2NhcmQgdGhlIHJlc3Qgb2YgdGhlIGxpc3RcbiAgICAgICAgLy93ZSB3b3VsZCBjb3VsZCBhYm9ydCBhbnkgTE9BRElORyB0aWxlIHJlcXVlc3RcbiAgICAgICAgLy9vbGRlciB0aGFuIHRoaXMgdGlsZSAoaS5lLiBhbnkgTE9BRElORyB0aWxlIGZvbGxvd2luZyB0aGlzIGVudHJ5IGluIHRoZSBjaGFpbilcbiAgICAgICAgdGlsZS5pbnRlcmltVGlsZSA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLkxPQURJTkcpIHtcbiAgICAgICAgLy9rZWVwIHRoaXMgTE9BRElORyB0aWxlIGFueSBsb2FkZWQgdGlsZXMgbGF0ZXIgaW4gdGhlIGNoYWluIGFyZVxuICAgICAgICAvL29sZGVyIHRoYW4gdGhpcyB0aWxlLCBzbyB3ZSdyZSBzdGlsbCBpbnRlcmVzdGVkIGluIHRoZSByZXF1ZXN0XG4gICAgICAgIHByZXYgPSB0aWxlO1xuICAgICAgfSBlbHNlIGlmICh0aWxlLmdldFN0YXRlKCkgPT0gVGlsZVN0YXRlLklETEUpIHtcbiAgICAgICAgLy90aGUgaGVhZCBvZiB0aGUgbGlzdCBpcyB0aGUgbW9zdCBjdXJyZW50IHRpbGUsIHdlIGRvbid0IG5lZWRcbiAgICAgICAgLy90byBzdGFydCBhbnkgb3RoZXIgcmVxdWVzdHMgZm9yIHRoaXMgY2hhaW5cbiAgICAgICAgcHJldi5pbnRlcmltVGlsZSA9IHRpbGUuaW50ZXJpbVRpbGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmV2ID0gdGlsZTtcbiAgICAgIH1cblxuICAgICAgdGlsZSA9IHByZXYuaW50ZXJpbVRpbGU7XG4gICAgfSB3aGlsZSAodGlsZSk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRpbGUgY29vcmRpbmF0ZSBmb3IgdGhpcyB0aWxlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IFRoZSB0aWxlIGNvb3JkaW5hdGUuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5nZXRUaWxlQ29vcmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGlsZUNvb3JkO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9UaWxlU3RhdGUuanNcIikuZGVmYXVsdH0gU3RhdGUuXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUuZ2V0U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGU7XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBzdGF0ZSBvZiB0aGlzIHRpbGUuIElmIHlvdSB3cml0ZSB5b3VyIG93biB7QGxpbmsgbW9kdWxlOm9sL1RpbGV+TG9hZEZ1bmN0aW9uIHRpbGVMb2FkRnVuY3Rpb259ICxcbiAgICogaXQgaXMgaW1wb3J0YW50IHRvIHNldCB0aGUgc3RhdGUgY29ycmVjdGx5IHRvIHtAbGluayBtb2R1bGU6b2wvVGlsZVN0YXRlfkVSUk9SfVxuICAgKiB3aGVuIHRoZSB0aWxlIGNhbm5vdCBiZSBsb2FkZWQuIE90aGVyd2lzZSB0aGUgdGlsZSBjYW5ub3QgYmUgcmVtb3ZlZCBmcm9tXG4gICAqIHRoZSB0aWxlIHF1ZXVlIGFuZCB3aWxsIGJsb2NrIG90aGVyIHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGlsZVN0YXRlLmpzXCIpLmRlZmF1bHR9IHN0YXRlIFN0YXRlLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUuc2V0U3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICBpZiAodGhpcy5zdGF0ZSAhPT0gVGlsZVN0YXRlLkVSUk9SICYmIHRoaXMuc3RhdGUgPiBzdGF0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIGxvYWQgc2VxdWVuY2UgdmlvbGF0aW9uJyk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9O1xuICAvKipcbiAgICogTG9hZCB0aGUgaW1hZ2Ugb3IgcmV0cnkgaWYgbG9hZGluZyBwcmV2aW91c2x5IGZhaWxlZC5cbiAgICogTG9hZGluZyBpcyB0YWtlbiBjYXJlIG9mIGJ5IHRoZSB0aWxlIHF1ZXVlLCBhbmQgY2FsbGluZyB0aGlzIG1ldGhvZCBpc1xuICAgKiBvbmx5IG5lZWRlZCBmb3IgcHJlbG9hZGluZyBvciBmb3IgcmVsb2FkaW5nIGluIGNhc2Ugb2YgYW4gZXJyb3IuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBhYnN0cmFjdCgpO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBhbHBoYSB2YWx1ZSBmb3IgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgQW4gaWQgZm9yIHRoZSByZW5kZXJlci5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWUgVGhlIHJlbmRlciBmcmFtZSB0aW1lLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMS5cbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5nZXRBbHBoYSA9IGZ1bmN0aW9uIChpZCwgdGltZSkge1xuICAgIGlmICghdGhpcy50cmFuc2l0aW9uXykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgdmFyIHN0YXJ0ID0gdGhpcy50cmFuc2l0aW9uU3RhcnRzX1tpZF07XG5cbiAgICBpZiAoIXN0YXJ0KSB7XG4gICAgICBzdGFydCA9IHRpbWU7XG4gICAgICB0aGlzLnRyYW5zaXRpb25TdGFydHNfW2lkXSA9IHN0YXJ0O1xuICAgIH0gZWxzZSBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICB2YXIgZGVsdGEgPSB0aW1lIC0gc3RhcnQgKyAxMDAwIC8gNjA7IC8vIGF2b2lkIHJlbmRlcmluZyBhdCAwXG5cbiAgICBpZiAoZGVsdGEgPj0gdGhpcy50cmFuc2l0aW9uXykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVhc2VJbihkZWx0YSAvIHRoaXMudHJhbnNpdGlvbl8pO1xuICB9O1xuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIGEgdGlsZSBpcyBpbiBhbiBhbHBoYSB0cmFuc2l0aW9uLiAgQSB0aWxlIGlzIGNvbnNpZGVyZWQgaW5cbiAgICogdHJhbnNpdGlvbiBpZiB0aWxlLmdldEFscGhhKCkgaGFzIG5vdCB5ZXQgYmVlbiBjYWxsZWQgb3IgaGFzIGJlZW4gY2FsbGVkXG4gICAqIGFuZCByZXR1cm5lZCAxLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgQW4gaWQgZm9yIHRoZSByZW5kZXJlci5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHRpbGUgaXMgaW4gdHJhbnNpdGlvbi5cbiAgICovXG5cblxuICBUaWxlLnByb3RvdHlwZS5pblRyYW5zaXRpb24gPSBmdW5jdGlvbiAoaWQpIHtcbiAgICBpZiAoIXRoaXMudHJhbnNpdGlvbl8pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy50cmFuc2l0aW9uU3RhcnRzX1tpZF0gIT09IC0xO1xuICB9O1xuICAvKipcbiAgICogTWFyayBhIHRyYW5zaXRpb24gYXMgY29tcGxldGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBBbiBpZCBmb3IgdGhlIHJlbmRlcmVyLlxuICAgKi9cblxuXG4gIFRpbGUucHJvdG90eXBlLmVuZFRyYW5zaXRpb24gPSBmdW5jdGlvbiAoaWQpIHtcbiAgICBpZiAodGhpcy50cmFuc2l0aW9uXykge1xuICAgICAgdGhpcy50cmFuc2l0aW9uU3RhcnRzX1tpZF0gPSAtMTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFRpbGU7XG59KEV2ZW50VGFyZ2V0KTtcblxuZXhwb3J0IGRlZmF1bHQgVGlsZTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL0ltYWdlVGlsZVxuICovXG5cblxuaW1wb3J0IFRpbGUgZnJvbSAnLi9UaWxlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi9UaWxlU3RhdGUuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi9kb20uanMnO1xuaW1wb3J0IHsgbGlzdGVuSW1hZ2UgfSBmcm9tICcuL0ltYWdlLmpzJztcblxudmFyIEltYWdlVGlsZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhJbWFnZVRpbGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGVTdGF0ZS5qc1wiKS5kZWZhdWx0fSBzdGF0ZSBTdGF0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNyYyBJbWFnZSBzb3VyY2UgVVJJLlxuICAgKiBAcGFyYW0gez9zdHJpbmd9IGNyb3NzT3JpZ2luIENyb3NzIG9yaWdpbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSB0aWxlTG9hZEZ1bmN0aW9uIFRpbGUgbG9hZCBmdW5jdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuT3B0aW9ucz19IG9wdF9vcHRpb25zIFRpbGUgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBJbWFnZVRpbGUodGlsZUNvb3JkLCBzdGF0ZSwgc3JjLCBjcm9zc09yaWdpbiwgdGlsZUxvYWRGdW5jdGlvbiwgb3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlQ29vcmQsIHN0YXRlLCBvcHRfb3B0aW9ucykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/c3RyaW5nfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5jcm9zc09yaWdpbl8gPSBjcm9zc09yaWdpbjtcbiAgICAvKipcbiAgICAgKiBJbWFnZSBVUklcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cblxuICAgIF90aGlzLnNyY18gPSBzcmM7XG4gICAgX3RoaXMua2V5ID0gc3JjO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR8SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5pbWFnZV8gPSBuZXcgSW1hZ2UoKTtcblxuICAgIGlmIChjcm9zc09yaWdpbiAhPT0gbnVsbCkge1xuICAgICAgX3RoaXMuaW1hZ2VfLmNyb3NzT3JpZ2luID0gY3Jvc3NPcmlnaW47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgez9mdW5jdGlvbigpOnZvaWR9XG4gICAgICovXG5cblxuICAgIF90aGlzLnVubGlzdGVuXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVMb2FkRnVuY3Rpb25fID0gdGlsZUxvYWRGdW5jdGlvbjtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgSFRNTCBpbWFnZSBlbGVtZW50IGZvciB0aGlzIHRpbGUgKG1heSBiZSBhIENhbnZhcywgSW1hZ2UsIG9yIFZpZGVvKS5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR8SFRNTEltYWdlRWxlbWVudHxIVE1MVmlkZW9FbGVtZW50fSBJbWFnZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlVGlsZS5wcm90b3R5cGUuZ2V0SW1hZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VfO1xuICB9O1xuICAvKipcbiAgICogVHJhY2tzIGxvYWRpbmcgb3IgcmVhZCBlcnJvcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSW1hZ2VUaWxlLnByb3RvdHlwZS5oYW5kbGVJbWFnZUVycm9yXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLkVSUk9SO1xuICAgIHRoaXMudW5saXN0ZW5JbWFnZV8oKTtcbiAgICB0aGlzLmltYWdlXyA9IGdldEJsYW5rSW1hZ2UoKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFRyYWNrcyBzdWNjZXNzZnVsIGltYWdlIGxvYWQuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgSW1hZ2VUaWxlLnByb3RvdHlwZS5oYW5kbGVJbWFnZUxvYWRfID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBpbWFnZSA9XG4gICAgLyoqIEB0eXBlIHtIVE1MSW1hZ2VFbGVtZW50fSAqL1xuICAgIHRoaXMuaW1hZ2VfO1xuXG4gICAgaWYgKGltYWdlLm5hdHVyYWxXaWR0aCAmJiBpbWFnZS5uYXR1cmFsSGVpZ2h0KSB7XG4gICAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLkxPQURFRDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FTVBUWTtcbiAgICB9XG5cbiAgICB0aGlzLnVubGlzdGVuSW1hZ2VfKCk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIEltYWdlVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZSA9PSBUaWxlU3RhdGUuRVJST1IpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSBUaWxlU3RhdGUuSURMRTtcbiAgICAgIHRoaXMuaW1hZ2VfID0gbmV3IEltYWdlKCk7XG5cbiAgICAgIGlmICh0aGlzLmNyb3NzT3JpZ2luXyAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmltYWdlXy5jcm9zc09yaWdpbiA9IHRoaXMuY3Jvc3NPcmlnaW5fO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXRlID09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLkxPQURJTkc7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIHRoaXMudGlsZUxvYWRGdW5jdGlvbl8odGhpcywgdGhpcy5zcmNfKTtcbiAgICAgIHRoaXMudW5saXN0ZW5fID0gbGlzdGVuSW1hZ2UodGhpcy5pbWFnZV8sIHRoaXMuaGFuZGxlSW1hZ2VMb2FkXy5iaW5kKHRoaXMpLCB0aGlzLmhhbmRsZUltYWdlRXJyb3JfLmJpbmQodGhpcykpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIERpc2NhcmRzIGV2ZW50IGhhbmRsZXJzIHdoaWNoIGxpc3RlbiBmb3IgbG9hZCBjb21wbGV0aW9uIG9yIGVycm9ycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICBJbWFnZVRpbGUucHJvdG90eXBlLnVubGlzdGVuSW1hZ2VfID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnVubGlzdGVuXykge1xuICAgICAgdGhpcy51bmxpc3Rlbl8oKTtcbiAgICAgIHRoaXMudW5saXN0ZW5fID0gbnVsbDtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIEltYWdlVGlsZTtcbn0oVGlsZSk7XG4vKipcbiAqIEdldCBhIDEtcGl4ZWwgYmxhbmsgaW1hZ2UuXG4gKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudH0gQmxhbmsgaW1hZ2UuXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRCbGFua0ltYWdlKCkge1xuICB2YXIgY3R4ID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEpO1xuICBjdHguZmlsbFN0eWxlID0gJ3JnYmEoMCwwLDAsMCknO1xuICBjdHguZmlsbFJlY3QoMCwgMCwgMSwgMSk7XG4gIHJldHVybiBjdHguY2FudmFzO1xufVxuXG5leHBvcnQgZGVmYXVsdCBJbWFnZVRpbGU7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3JlcHJvai9jb21tb25cbiAqL1xuXG4vKipcbiAqIERlZmF1bHQgbWF4aW11bSBhbGxvd2VkIHRocmVzaG9sZCAgKGluIHBpeGVscykgZm9yIHJlcHJvamVjdGlvblxuICogdHJpYW5ndWxhdGlvbi5cbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCB2YXIgRVJST1JfVEhSRVNIT0xEID0gMC41O1xuLyoqXG4gKiBFbmFibGUgYXV0b21hdGljIHJlcHJvamVjdGlvbiBvZiByYXN0ZXIgc291cmNlcy4gRGVmYXVsdCBpcyBgdHJ1ZWAuXG4gKiBUT0RPOiBkZWNpZGUgaWYgd2Ugd2FudCB0byBleHBvc2UgdGhpcyBhcyBhIGJ1aWxkIGZsYWcgb3IgcmVtb3ZlIGl0XG4gKiBAdHlwZSB7Ym9vbGVhbn1cbiAqL1xuXG5leHBvcnQgdmFyIEVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OID0gdHJ1ZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvcmVwcm9qL1RyaWFuZ3VsYXRpb25cbiAqL1xuaW1wb3J0IHsgYm91bmRpbmdFeHRlbnQsIGNyZWF0ZUVtcHR5LCBleHRlbmRDb29yZGluYXRlLCBnZXRBcmVhLCBnZXRCb3R0b21MZWZ0LCBnZXRCb3R0b21SaWdodCwgZ2V0VG9wTGVmdCwgZ2V0VG9wUmlnaHQsIGdldFdpZHRoLCBpbnRlcnNlY3RzIH0gZnJvbSAnLi4vZXh0ZW50LmpzJztcbmltcG9ydCB7IGdldFRyYW5zZm9ybSB9IGZyb20gJy4uL3Byb2ouanMnO1xuaW1wb3J0IHsgbG9nMiwgbW9kdWxvIH0gZnJvbSAnLi4vbWF0aC5qcyc7XG4vKipcbiAqIFNpbmdsZSB0cmlhbmdsZTsgY29uc2lzdHMgb2YgMyBzb3VyY2UgcG9pbnRzIGFuZCAzIHRhcmdldCBwb2ludHMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUcmlhbmdsZVxuICogQHByb3BlcnR5IHtBcnJheTxpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBzb3VyY2VcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPn0gdGFyZ2V0XG4gKi9cblxuLyoqXG4gKiBNYXhpbXVtIG51bWJlciBvZiBzdWJkaXZpc2lvbiBzdGVwcyBkdXJpbmcgcmFzdGVyIHJlcHJvamVjdGlvbiB0cmlhbmd1bGF0aW9uLlxuICogUHJldmVudHMgaGlnaCBtZW1vcnkgdXNhZ2UgYW5kIGxhcmdlIG51bWJlciBvZiBwcm9qNCBjYWxscyAoZm9yIGNlcnRhaW5cbiAqIHRyYW5zZm9ybWF0aW9ucyBhbmQgYXJlYXMpLiBBdCBtb3N0IGAyKigyXnRoaXMpYCB0cmlhbmdsZXMgYXJlIGNyZWF0ZWQgZm9yXG4gKiBlYWNoIHRyaWFuZ3VsYXRlZCBleHRlbnQgKHRpbGUvaW1hZ2UpLlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG52YXIgTUFYX1NVQkRJVklTSU9OID0gMTA7XG4vKipcbiAqIE1heGltdW0gYWxsb3dlZCBzaXplIG9mIHRyaWFuZ2xlIHJlbGF0aXZlIHRvIHdvcmxkIHdpZHRoLiBXaGVuIHRyYW5zZm9ybWluZ1xuICogY29ybmVycyBvZiB3b3JsZCBleHRlbnQgYmV0d2VlbiBjZXJ0YWluIHByb2plY3Rpb25zLCB0aGUgcmVzdWx0aW5nXG4gKiB0cmlhbmd1bGF0aW9uIHNlZW1zIHRvIGhhdmUgemVybyBlcnJvciBhbmQgbm8gc3ViZGl2aXNpb24gaXMgcGVyZm9ybWVkLiBJZlxuICogdGhlIHRyaWFuZ2xlIHdpZHRoIGlzIG1vcmUgdGhhbiB0aGlzIChyZWxhdGl2ZSB0byB3b3JsZCB3aWR0aDsgMC0xKSxcbiAqIHN1YmRpdmlzb24gaXMgZm9yY2VkICh1cCB0byBgTUFYX1NVQkRJVklTSU9OYCkuIERlZmF1bHQgaXMgYDAuMjVgLlxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG52YXIgTUFYX1RSSUFOR0xFX1dJRFRIID0gMC4yNTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2xhc3MgY29udGFpbmluZyB0cmlhbmd1bGF0aW9uIG9mIHRoZSBnaXZlbiB0YXJnZXQgZXh0ZW50LlxuICogVXNlZCBmb3IgZGV0ZXJtaW5pbmcgc291cmNlIGRhdGEgYW5kIHRoZSByZXByb2plY3Rpb24gaXRzZWxmLlxuICovXG5cbnZhciBUcmlhbmd1bGF0aW9uID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHNvdXJjZVByb2ogU291cmNlIHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHRhcmdldFByb2ogVGFyZ2V0IHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gdGFyZ2V0RXh0ZW50IFRhcmdldCBleHRlbnQgdG8gdHJpYW5ndWxhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gbWF4U291cmNlRXh0ZW50IE1heGltYWwgc291cmNlIGV4dGVudCB0aGF0IGNhbiBiZSB1c2VkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZXJyb3JUaHJlc2hvbGQgQWNjZXB0YWJsZSBlcnJvciAoaW4gc291cmNlIHVuaXRzKS5cbiAgICogQHBhcmFtIHs/bnVtYmVyfSBvcHRfZGVzdGluYXRpb25SZXNvbHV0aW9uIFRoZSAob3B0aW9uYWwpIHJlc29sdXRpb24gb2YgdGhlIGRlc3RpbmF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gVHJpYW5ndWxhdGlvbihzb3VyY2VQcm9qLCB0YXJnZXRQcm9qLCB0YXJnZXRFeHRlbnQsIG1heFNvdXJjZUV4dGVudCwgZXJyb3JUaHJlc2hvbGQsIG9wdF9kZXN0aW5hdGlvblJlc29sdXRpb24pIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLnNvdXJjZVByb2pfID0gc291cmNlUHJvajtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMudGFyZ2V0UHJval8gPSB0YXJnZXRQcm9qO1xuICAgIC8qKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59ICovXG5cbiAgICB2YXIgdHJhbnNmb3JtSW52Q2FjaGUgPSB7fTtcbiAgICB2YXIgdHJhbnNmb3JtSW52ID0gZ2V0VHJhbnNmb3JtKHRoaXMudGFyZ2V0UHJval8sIHRoaXMuc291cmNlUHJval8pO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjIEEgY29vcmRpbmF0ZS5cbiAgICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFRyYW5zZm9ybWVkIGNvb3JkaW5hdGUuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMudHJhbnNmb3JtSW52XyA9IGZ1bmN0aW9uIChjKSB7XG4gICAgICB2YXIga2V5ID0gY1swXSArICcvJyArIGNbMV07XG5cbiAgICAgIGlmICghdHJhbnNmb3JtSW52Q2FjaGVba2V5XSkge1xuICAgICAgICB0cmFuc2Zvcm1JbnZDYWNoZVtrZXldID0gdHJhbnNmb3JtSW52KGMpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJhbnNmb3JtSW52Q2FjaGVba2V5XTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIHRoaXMubWF4U291cmNlRXh0ZW50XyA9IG1heFNvdXJjZUV4dGVudDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLmVycm9yVGhyZXNob2xkU3F1YXJlZF8gPSBlcnJvclRocmVzaG9sZCAqIGVycm9yVGhyZXNob2xkO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxUcmlhbmdsZT59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMudHJpYW5nbGVzXyA9IFtdO1xuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyB0aGF0IHRoZSB0cmlhbmd1bGF0aW9uIGNyb3NzZXMgZWRnZSBvZiB0aGUgc291cmNlIHByb2plY3Rpb24uXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMud3JhcHNYSW5Tb3VyY2VfID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMuY2FuV3JhcFhJblNvdXJjZV8gPSB0aGlzLnNvdXJjZVByb2pfLmNhbldyYXBYKCkgJiYgISFtYXhTb3VyY2VFeHRlbnQgJiYgISF0aGlzLnNvdXJjZVByb2pfLmdldEV4dGVudCgpICYmIGdldFdpZHRoKG1heFNvdXJjZUV4dGVudCkgPT0gZ2V0V2lkdGgodGhpcy5zb3VyY2VQcm9qXy5nZXRFeHRlbnQoKSk7XG4gICAgLyoqXG4gICAgICogQHR5cGUgez9udW1iZXJ9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIHRoaXMuc291cmNlV29ybGRXaWR0aF8gPSB0aGlzLnNvdXJjZVByb2pfLmdldEV4dGVudCgpID8gZ2V0V2lkdGgodGhpcy5zb3VyY2VQcm9qXy5nZXRFeHRlbnQoKSkgOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHs/bnVtYmVyfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgICB0aGlzLnRhcmdldFdvcmxkV2lkdGhfID0gdGhpcy50YXJnZXRQcm9qXy5nZXRFeHRlbnQoKSA/IGdldFdpZHRoKHRoaXMudGFyZ2V0UHJval8uZ2V0RXh0ZW50KCkpIDogbnVsbDtcbiAgICB2YXIgZGVzdGluYXRpb25Ub3BMZWZ0ID0gZ2V0VG9wTGVmdCh0YXJnZXRFeHRlbnQpO1xuICAgIHZhciBkZXN0aW5hdGlvblRvcFJpZ2h0ID0gZ2V0VG9wUmlnaHQodGFyZ2V0RXh0ZW50KTtcbiAgICB2YXIgZGVzdGluYXRpb25Cb3R0b21SaWdodCA9IGdldEJvdHRvbVJpZ2h0KHRhcmdldEV4dGVudCk7XG4gICAgdmFyIGRlc3RpbmF0aW9uQm90dG9tTGVmdCA9IGdldEJvdHRvbUxlZnQodGFyZ2V0RXh0ZW50KTtcbiAgICB2YXIgc291cmNlVG9wTGVmdCA9IHRoaXMudHJhbnNmb3JtSW52XyhkZXN0aW5hdGlvblRvcExlZnQpO1xuICAgIHZhciBzb3VyY2VUb3BSaWdodCA9IHRoaXMudHJhbnNmb3JtSW52XyhkZXN0aW5hdGlvblRvcFJpZ2h0KTtcbiAgICB2YXIgc291cmNlQm90dG9tUmlnaHQgPSB0aGlzLnRyYW5zZm9ybUludl8oZGVzdGluYXRpb25Cb3R0b21SaWdodCk7XG4gICAgdmFyIHNvdXJjZUJvdHRvbUxlZnQgPSB0aGlzLnRyYW5zZm9ybUludl8oZGVzdGluYXRpb25Cb3R0b21MZWZ0KTtcbiAgICAvKlxuICAgICAqIFRoZSBtYXhTdWJkaXZpc2lvbiBjb250cm9scyBob3cgbWFueSBzcGxpdHRpbmdzIG9mIHRoZSB0YXJnZXQgYXJlYSBjYW5cbiAgICAgKiBiZSBkb25lLiBUaGUgaWRlYSBoZXJlIGlzIHRvIGRvIGEgbGluZWFyIG1hcHBpbmcgb2YgdGhlIHRhcmdldCBhcmVhc1xuICAgICAqIGJ1dCB0aGUgYWN0dWFsIG92ZXJhbCByZXByb2plY3Rpb24gKGNhbiBiZSkgZXh0cmVtZWx5IG5vbi1saW5lYXIuIFRoZVxuICAgICAqIGRlZmF1bHQgdmFsdWUgb2YgTUFYX1NVQkRJVklTSU9OIHdhcyBjaG9zZW4gYmFzZWQgb24gbWFwcGluZyBhIDI1NngyNTZcbiAgICAgKiB0aWxlIHNpemUuIEhvd2V2ZXIgdGhpcyBmdW5jdGlvbiBpcyBhbHNvIGNhbGxlZCB0byByZW1hcCBjYW52YXMgcmVuZGVyZWRcbiAgICAgKiBsYXllcnMgd2hpY2ggY2FuIGJlIG11Y2ggbGFyZ2VyLiBUaGlzIGNhbGN1bGF0aW9uIGluY3JlYXNlcyB0aGUgbWF4U3ViZGl2aXNpb25cbiAgICAgKiB2YWx1ZSBieSB0aGUgcmlnaHQgZmFjdG9yIHNvIHRoYXQgZWFjaCAyNTZ4MjU2IHBpeGVsIGFyZWEgaGFzXG4gICAgICogTUFYX1NVQkRJVklTSU9OIGRpdmlzaW9ucy5cbiAgICAgKi9cblxuICAgIHZhciBtYXhTdWJkaXZpc2lvbiA9IE1BWF9TVUJESVZJU0lPTiArIChvcHRfZGVzdGluYXRpb25SZXNvbHV0aW9uID8gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKGxvZzIoZ2V0QXJlYSh0YXJnZXRFeHRlbnQpIC8gKG9wdF9kZXN0aW5hdGlvblJlc29sdXRpb24gKiBvcHRfZGVzdGluYXRpb25SZXNvbHV0aW9uICogMjU2ICogMjU2KSkpKSA6IDApO1xuICAgIHRoaXMuYWRkUXVhZF8oZGVzdGluYXRpb25Ub3BMZWZ0LCBkZXN0aW5hdGlvblRvcFJpZ2h0LCBkZXN0aW5hdGlvbkJvdHRvbVJpZ2h0LCBkZXN0aW5hdGlvbkJvdHRvbUxlZnQsIHNvdXJjZVRvcExlZnQsIHNvdXJjZVRvcFJpZ2h0LCBzb3VyY2VCb3R0b21SaWdodCwgc291cmNlQm90dG9tTGVmdCwgbWF4U3ViZGl2aXNpb24pO1xuXG4gICAgaWYgKHRoaXMud3JhcHNYSW5Tb3VyY2VfKSB7XG4gICAgICB2YXIgbGVmdEJvdW5kXzEgPSBJbmZpbml0eTtcbiAgICAgIHRoaXMudHJpYW5nbGVzXy5mb3JFYWNoKGZ1bmN0aW9uICh0cmlhbmdsZSwgaSwgYXJyKSB7XG4gICAgICAgIGxlZnRCb3VuZF8xID0gTWF0aC5taW4obGVmdEJvdW5kXzEsIHRyaWFuZ2xlLnNvdXJjZVswXVswXSwgdHJpYW5nbGUuc291cmNlWzFdWzBdLCB0cmlhbmdsZS5zb3VyY2VbMl1bMF0pO1xuICAgICAgfSk7IC8vIFNoaWZ0IHRyaWFuZ2xlcyB0byBiZSBhcyBjbG9zZSB0byBgbGVmdEJvdW5kYCBhcyBwb3NzaWJsZVxuICAgICAgLy8gKGlmIHRoZSBkaXN0YW5jZSBpcyBtb3JlIHRoYW4gYHdvcmxkV2lkdGggLyAyYCBpdCBjYW4gYmUgY2xvc2VyLlxuXG4gICAgICB0aGlzLnRyaWFuZ2xlc18uZm9yRWFjaChmdW5jdGlvbiAodHJpYW5nbGUpIHtcbiAgICAgICAgaWYgKE1hdGgubWF4KHRyaWFuZ2xlLnNvdXJjZVswXVswXSwgdHJpYW5nbGUuc291cmNlWzFdWzBdLCB0cmlhbmdsZS5zb3VyY2VbMl1bMF0pIC0gbGVmdEJvdW5kXzEgPiB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfIC8gMikge1xuICAgICAgICAgIHZhciBuZXdUcmlhbmdsZSA9IFtbdHJpYW5nbGUuc291cmNlWzBdWzBdLCB0cmlhbmdsZS5zb3VyY2VbMF1bMV1dLCBbdHJpYW5nbGUuc291cmNlWzFdWzBdLCB0cmlhbmdsZS5zb3VyY2VbMV1bMV1dLCBbdHJpYW5nbGUuc291cmNlWzJdWzBdLCB0cmlhbmdsZS5zb3VyY2VbMl1bMV1dXTtcblxuICAgICAgICAgIGlmIChuZXdUcmlhbmdsZVswXVswXSAtIGxlZnRCb3VuZF8xID4gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyAvIDIpIHtcbiAgICAgICAgICAgIG5ld1RyaWFuZ2xlWzBdWzBdIC09IHRoaXMuc291cmNlV29ybGRXaWR0aF87XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG5ld1RyaWFuZ2xlWzFdWzBdIC0gbGVmdEJvdW5kXzEgPiB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfIC8gMikge1xuICAgICAgICAgICAgbmV3VHJpYW5nbGVbMV1bMF0gLT0gdGhpcy5zb3VyY2VXb3JsZFdpZHRoXztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobmV3VHJpYW5nbGVbMl1bMF0gLSBsZWZ0Qm91bmRfMSA+IHRoaXMuc291cmNlV29ybGRXaWR0aF8gLyAyKSB7XG4gICAgICAgICAgICBuZXdUcmlhbmdsZVsyXVswXSAtPSB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfO1xuICAgICAgICAgIH0gLy8gUmFyZWx5IChpZiB0aGUgZXh0ZW50IGNvbnRhaW5zIGJvdGggdGhlIGRhdGVsaW5lIGFuZCBwcmltZSBtZXJpZGlhbilcbiAgICAgICAgICAvLyB0aGUgc2hpZnQgY2FuIGluIHR1cm4gYnJlYWsgc29tZSB0cmlhbmdsZXMuXG4gICAgICAgICAgLy8gRGV0ZWN0IHRoaXMgaGVyZSBhbmQgZG9uJ3Qgc2hpZnQgaW4gc3VjaCBjYXNlcy5cblxuXG4gICAgICAgICAgdmFyIG1pblggPSBNYXRoLm1pbihuZXdUcmlhbmdsZVswXVswXSwgbmV3VHJpYW5nbGVbMV1bMF0sIG5ld1RyaWFuZ2xlWzJdWzBdKTtcbiAgICAgICAgICB2YXIgbWF4WCA9IE1hdGgubWF4KG5ld1RyaWFuZ2xlWzBdWzBdLCBuZXdUcmlhbmdsZVsxXVswXSwgbmV3VHJpYW5nbGVbMl1bMF0pO1xuXG4gICAgICAgICAgaWYgKG1heFggLSBtaW5YIDwgdGhpcy5zb3VyY2VXb3JsZFdpZHRoXyAvIDIpIHtcbiAgICAgICAgICAgIHRyaWFuZ2xlLnNvdXJjZSA9IG5ld1RyaWFuZ2xlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB0cmFuc2Zvcm1JbnZDYWNoZSA9IHt9O1xuICB9XG4gIC8qKlxuICAgKiBBZGRzIHRyaWFuZ2xlIHRvIHRoZSB0cmlhbmd1bGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYSBUaGUgdGFyZ2V0IGEgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGIgVGhlIHRhcmdldCBiIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjIFRoZSB0YXJnZXQgYyBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYVNyYyBUaGUgc291cmNlIGEgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGJTcmMgVGhlIHNvdXJjZSBiIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjU3JjIFRoZSBzb3VyY2UgYyBjb29yZGluYXRlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRyaWFuZ3VsYXRpb24ucHJvdG90eXBlLmFkZFRyaWFuZ2xlXyA9IGZ1bmN0aW9uIChhLCBiLCBjLCBhU3JjLCBiU3JjLCBjU3JjKSB7XG4gICAgdGhpcy50cmlhbmdsZXNfLnB1c2goe1xuICAgICAgc291cmNlOiBbYVNyYywgYlNyYywgY1NyY10sXG4gICAgICB0YXJnZXQ6IFthLCBiLCBjXVxuICAgIH0pO1xuICB9O1xuICAvKipcbiAgICogQWRkcyBxdWFkIChwb2ludHMgaW4gY2xvY2std2lzZSBvcmRlcikgdG8gdGhlIHRyaWFuZ3VsYXRpb25cbiAgICogKGFuZCByZXByb2plY3RzIHRoZSB2ZXJ0aWNlcykgaWYgdmFsaWQuXG4gICAqIFBlcmZvcm1zIHF1YWQgc3ViZGl2aXNpb24gaWYgbmVlZGVkIHRvIGluY3JlYXNlIHByZWNpc2lvbi5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGEgVGhlIHRhcmdldCBhIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBiIFRoZSB0YXJnZXQgYiBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYyBUaGUgdGFyZ2V0IGMgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGQgVGhlIHRhcmdldCBkIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBhU3JjIFRoZSBzb3VyY2UgYSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gYlNyYyBUaGUgc291cmNlIGIgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNTcmMgVGhlIHNvdXJjZSBjIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBkU3JjIFRoZSBzb3VyY2UgZCBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbWF4U3ViZGl2aXNpb24gTWF4aW1hbCBhbGxvd2VkIHN1YmRpdmlzaW9uIG9mIHRoZSBxdWFkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRyaWFuZ3VsYXRpb24ucHJvdG90eXBlLmFkZFF1YWRfID0gZnVuY3Rpb24gKGEsIGIsIGMsIGQsIGFTcmMsIGJTcmMsIGNTcmMsIGRTcmMsIG1heFN1YmRpdmlzaW9uKSB7XG4gICAgdmFyIHNvdXJjZVF1YWRFeHRlbnQgPSBib3VuZGluZ0V4dGVudChbYVNyYywgYlNyYywgY1NyYywgZFNyY10pO1xuICAgIHZhciBzb3VyY2VDb3ZlcmFnZVggPSB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfID8gZ2V0V2lkdGgoc291cmNlUXVhZEV4dGVudCkgLyB0aGlzLnNvdXJjZVdvcmxkV2lkdGhfIDogbnVsbDtcbiAgICB2YXIgc291cmNlV29ybGRXaWR0aCA9XG4gICAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gICAgdGhpcy5zb3VyY2VXb3JsZFdpZHRoXzsgLy8gd2hlbiB0aGUgcXVhZCBpcyB3cmFwcGVkIGluIHRoZSBzb3VyY2UgcHJvamVjdGlvblxuICAgIC8vIGl0IGNvdmVycyBtb3N0IG9mIHRoZSBwcm9qZWN0aW9uIGV4dGVudCwgYnV0IG5vdCBmdWxseVxuXG4gICAgdmFyIHdyYXBzWCA9IHRoaXMuc291cmNlUHJval8uY2FuV3JhcFgoKSAmJiBzb3VyY2VDb3ZlcmFnZVggPiAwLjUgJiYgc291cmNlQ292ZXJhZ2VYIDwgMTtcbiAgICB2YXIgbmVlZHNTdWJkaXZpc2lvbiA9IGZhbHNlO1xuXG4gICAgaWYgKG1heFN1YmRpdmlzaW9uID4gMCkge1xuICAgICAgaWYgKHRoaXMudGFyZ2V0UHJval8uaXNHbG9iYWwoKSAmJiB0aGlzLnRhcmdldFdvcmxkV2lkdGhfKSB7XG4gICAgICAgIHZhciB0YXJnZXRRdWFkRXh0ZW50ID0gYm91bmRpbmdFeHRlbnQoW2EsIGIsIGMsIGRdKTtcbiAgICAgICAgdmFyIHRhcmdldENvdmVyYWdlWCA9IGdldFdpZHRoKHRhcmdldFF1YWRFeHRlbnQpIC8gdGhpcy50YXJnZXRXb3JsZFdpZHRoXztcbiAgICAgICAgbmVlZHNTdWJkaXZpc2lvbiA9IHRhcmdldENvdmVyYWdlWCA+IE1BWF9UUklBTkdMRV9XSURUSCB8fCBuZWVkc1N1YmRpdmlzaW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXdyYXBzWCAmJiB0aGlzLnNvdXJjZVByb2pfLmlzR2xvYmFsKCkgJiYgc291cmNlQ292ZXJhZ2VYKSB7XG4gICAgICAgIG5lZWRzU3ViZGl2aXNpb24gPSBzb3VyY2VDb3ZlcmFnZVggPiBNQVhfVFJJQU5HTEVfV0lEVEggfHwgbmVlZHNTdWJkaXZpc2lvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIW5lZWRzU3ViZGl2aXNpb24gJiYgdGhpcy5tYXhTb3VyY2VFeHRlbnRfKSB7XG4gICAgICBpZiAoaXNGaW5pdGUoc291cmNlUXVhZEV4dGVudFswXSkgJiYgaXNGaW5pdGUoc291cmNlUXVhZEV4dGVudFsxXSkgJiYgaXNGaW5pdGUoc291cmNlUXVhZEV4dGVudFsyXSkgJiYgaXNGaW5pdGUoc291cmNlUXVhZEV4dGVudFszXSkpIHtcbiAgICAgICAgaWYgKCFpbnRlcnNlY3RzKHNvdXJjZVF1YWRFeHRlbnQsIHRoaXMubWF4U291cmNlRXh0ZW50XykpIHtcbiAgICAgICAgICAvLyB3aG9sZSBxdWFkIG91dHNpZGUgc291cmNlIHByb2plY3Rpb24gZXh0ZW50IC0+IGlnbm9yZVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBpc05vdEZpbml0ZSA9IDA7XG5cbiAgICBpZiAoIW5lZWRzU3ViZGl2aXNpb24pIHtcbiAgICAgIGlmICghaXNGaW5pdGUoYVNyY1swXSkgfHwgIWlzRmluaXRlKGFTcmNbMV0pIHx8ICFpc0Zpbml0ZShiU3JjWzBdKSB8fCAhaXNGaW5pdGUoYlNyY1sxXSkgfHwgIWlzRmluaXRlKGNTcmNbMF0pIHx8ICFpc0Zpbml0ZShjU3JjWzFdKSB8fCAhaXNGaW5pdGUoZFNyY1swXSkgfHwgIWlzRmluaXRlKGRTcmNbMV0pKSB7XG4gICAgICAgIGlmIChtYXhTdWJkaXZpc2lvbiA+IDApIHtcbiAgICAgICAgICBuZWVkc1N1YmRpdmlzaW9uID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBJdCBtaWdodCBiZSB0aGUgY2FzZSB0aGF0IG9ubHkgMSBvZiB0aGUgcG9pbnRzIGlzIGluZmluaXRlLiBJbiB0aGlzIGNhc2VcbiAgICAgICAgICAvLyB3ZSBjYW4gZHJhdyBhIHNpbmdsZSB0cmlhbmdsZSB3aXRoIHRoZSBvdGhlciB0aHJlZSBwb2ludHNcbiAgICAgICAgICBpc05vdEZpbml0ZSA9ICghaXNGaW5pdGUoYVNyY1swXSkgfHwgIWlzRmluaXRlKGFTcmNbMV0pID8gOCA6IDApICsgKCFpc0Zpbml0ZShiU3JjWzBdKSB8fCAhaXNGaW5pdGUoYlNyY1sxXSkgPyA0IDogMCkgKyAoIWlzRmluaXRlKGNTcmNbMF0pIHx8ICFpc0Zpbml0ZShjU3JjWzFdKSA/IDIgOiAwKSArICghaXNGaW5pdGUoZFNyY1swXSkgfHwgIWlzRmluaXRlKGRTcmNbMV0pID8gMSA6IDApO1xuXG4gICAgICAgICAgaWYgKGlzTm90RmluaXRlICE9IDEgJiYgaXNOb3RGaW5pdGUgIT0gMiAmJiBpc05vdEZpbml0ZSAhPSA0ICYmIGlzTm90RmluaXRlICE9IDgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWF4U3ViZGl2aXNpb24gPiAwKSB7XG4gICAgICBpZiAoIW5lZWRzU3ViZGl2aXNpb24pIHtcbiAgICAgICAgdmFyIGNlbnRlciA9IFsoYVswXSArIGNbMF0pIC8gMiwgKGFbMV0gKyBjWzFdKSAvIDJdO1xuICAgICAgICB2YXIgY2VudGVyU3JjID0gdGhpcy50cmFuc2Zvcm1JbnZfKGNlbnRlcik7XG4gICAgICAgIHZhciBkeCA9IHZvaWQgMDtcblxuICAgICAgICBpZiAod3JhcHNYKSB7XG4gICAgICAgICAgdmFyIGNlbnRlclNyY0VzdGltWCA9IChtb2R1bG8oYVNyY1swXSwgc291cmNlV29ybGRXaWR0aCkgKyBtb2R1bG8oY1NyY1swXSwgc291cmNlV29ybGRXaWR0aCkpIC8gMjtcbiAgICAgICAgICBkeCA9IGNlbnRlclNyY0VzdGltWCAtIG1vZHVsbyhjZW50ZXJTcmNbMF0sIHNvdXJjZVdvcmxkV2lkdGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGR4ID0gKGFTcmNbMF0gKyBjU3JjWzBdKSAvIDIgLSBjZW50ZXJTcmNbMF07XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZHkgPSAoYVNyY1sxXSArIGNTcmNbMV0pIC8gMiAtIGNlbnRlclNyY1sxXTtcbiAgICAgICAgdmFyIGNlbnRlclNyY0Vycm9yU3F1YXJlZCA9IGR4ICogZHggKyBkeSAqIGR5O1xuICAgICAgICBuZWVkc1N1YmRpdmlzaW9uID0gY2VudGVyU3JjRXJyb3JTcXVhcmVkID4gdGhpcy5lcnJvclRocmVzaG9sZFNxdWFyZWRfO1xuICAgICAgfVxuXG4gICAgICBpZiAobmVlZHNTdWJkaXZpc2lvbikge1xuICAgICAgICBpZiAoTWF0aC5hYnMoYVswXSAtIGNbMF0pIDw9IE1hdGguYWJzKGFbMV0gLSBjWzFdKSkge1xuICAgICAgICAgIC8vIHNwbGl0IGhvcml6b250YWxseSAodG9wICYgYm90dG9tKVxuICAgICAgICAgIHZhciBiYyA9IFsoYlswXSArIGNbMF0pIC8gMiwgKGJbMV0gKyBjWzFdKSAvIDJdO1xuICAgICAgICAgIHZhciBiY1NyYyA9IHRoaXMudHJhbnNmb3JtSW52XyhiYyk7XG4gICAgICAgICAgdmFyIGRhID0gWyhkWzBdICsgYVswXSkgLyAyLCAoZFsxXSArIGFbMV0pIC8gMl07XG4gICAgICAgICAgdmFyIGRhU3JjID0gdGhpcy50cmFuc2Zvcm1JbnZfKGRhKTtcbiAgICAgICAgICB0aGlzLmFkZFF1YWRfKGEsIGIsIGJjLCBkYSwgYVNyYywgYlNyYywgYmNTcmMsIGRhU3JjLCBtYXhTdWJkaXZpc2lvbiAtIDEpO1xuICAgICAgICAgIHRoaXMuYWRkUXVhZF8oZGEsIGJjLCBjLCBkLCBkYVNyYywgYmNTcmMsIGNTcmMsIGRTcmMsIG1heFN1YmRpdmlzaW9uIC0gMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gc3BsaXQgdmVydGljYWxseSAobGVmdCAmIHJpZ2h0KVxuICAgICAgICAgIHZhciBhYiA9IFsoYVswXSArIGJbMF0pIC8gMiwgKGFbMV0gKyBiWzFdKSAvIDJdO1xuICAgICAgICAgIHZhciBhYlNyYyA9IHRoaXMudHJhbnNmb3JtSW52XyhhYik7XG4gICAgICAgICAgdmFyIGNkID0gWyhjWzBdICsgZFswXSkgLyAyLCAoY1sxXSArIGRbMV0pIC8gMl07XG4gICAgICAgICAgdmFyIGNkU3JjID0gdGhpcy50cmFuc2Zvcm1JbnZfKGNkKTtcbiAgICAgICAgICB0aGlzLmFkZFF1YWRfKGEsIGFiLCBjZCwgZCwgYVNyYywgYWJTcmMsIGNkU3JjLCBkU3JjLCBtYXhTdWJkaXZpc2lvbiAtIDEpO1xuICAgICAgICAgIHRoaXMuYWRkUXVhZF8oYWIsIGIsIGMsIGNkLCBhYlNyYywgYlNyYywgY1NyYywgY2RTcmMsIG1heFN1YmRpdmlzaW9uIC0gMSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHdyYXBzWCkge1xuICAgICAgaWYgKCF0aGlzLmNhbldyYXBYSW5Tb3VyY2VfKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy53cmFwc1hJblNvdXJjZV8gPSB0cnVlO1xuICAgIH0gLy8gRXhhY3RseSB6ZXJvIG9yIG9uZSBvZiAqU3JjIGlzIG5vdCBmaW5pdGVcbiAgICAvLyBUaGUgdHJpYW5nbGVzIG11c3QgaGF2ZSB0aGUgZGlhZ29uYWwgbGluZSBhcyB0aGUgZmlyc3Qgc2lkZVxuICAgIC8vIFRoaXMgaXMgdG8gYWxsb3cgZWFzeSBjb2RlIGluIHJlcHJvai5zIHRvIG1ha2UgaXQgc3RyYWlnaHQgZm9yIGJyb2tlblxuICAgIC8vIGJyb3dzZXJzIHRoYXQgY2FuJ3QgaGFuZGxlIGRpYWdvbmFsIGNsaXBwaW5nXG5cblxuICAgIGlmICgoaXNOb3RGaW5pdGUgJiAweGIpID09IDApIHtcbiAgICAgIHRoaXMuYWRkVHJpYW5nbGVfKGEsIGMsIGQsIGFTcmMsIGNTcmMsIGRTcmMpO1xuICAgIH1cblxuICAgIGlmICgoaXNOb3RGaW5pdGUgJiAweGUpID09IDApIHtcbiAgICAgIHRoaXMuYWRkVHJpYW5nbGVfKGEsIGMsIGIsIGFTcmMsIGNTcmMsIGJTcmMpO1xuICAgIH1cblxuICAgIGlmIChpc05vdEZpbml0ZSkge1xuICAgICAgLy8gVHJ5IHRoZSBvdGhlciB0d28gdHJpYW5nbGVzXG4gICAgICBpZiAoKGlzTm90RmluaXRlICYgMHhkKSA9PSAwKSB7XG4gICAgICAgIHRoaXMuYWRkVHJpYW5nbGVfKGIsIGQsIGEsIGJTcmMsIGRTcmMsIGFTcmMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoKGlzTm90RmluaXRlICYgMHg3KSA9PSAwKSB7XG4gICAgICAgIHRoaXMuYWRkVHJpYW5nbGVfKGIsIGQsIGMsIGJTcmMsIGRTcmMsIGNTcmMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgZXh0ZW50IG9mIHRoZSAnc291cmNlJyBjb29yZGluYXRlcyBmcm9tIGFsbCB0aGUgdHJpYW5nbGVzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBDYWxjdWxhdGVkIGV4dGVudC5cbiAgICovXG5cblxuICBUcmlhbmd1bGF0aW9uLnByb3RvdHlwZS5jYWxjdWxhdGVTb3VyY2VFeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGV4dGVudCA9IGNyZWF0ZUVtcHR5KCk7XG4gICAgdGhpcy50cmlhbmdsZXNfLmZvckVhY2goZnVuY3Rpb24gKHRyaWFuZ2xlLCBpLCBhcnIpIHtcbiAgICAgIHZhciBzcmMgPSB0cmlhbmdsZS5zb3VyY2U7XG4gICAgICBleHRlbmRDb29yZGluYXRlKGV4dGVudCwgc3JjWzBdKTtcbiAgICAgIGV4dGVuZENvb3JkaW5hdGUoZXh0ZW50LCBzcmNbMV0pO1xuICAgICAgZXh0ZW5kQ29vcmRpbmF0ZShleHRlbnQsIHNyY1syXSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PFRyaWFuZ2xlPn0gQXJyYXkgb2YgdGhlIGNhbGN1bGF0ZWQgdHJpYW5nbGVzLlxuICAgKi9cblxuXG4gIFRyaWFuZ3VsYXRpb24ucHJvdG90eXBlLmdldFRyaWFuZ2xlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50cmlhbmdsZXNfO1xuICB9O1xuXG4gIHJldHVybiBUcmlhbmd1bGF0aW9uO1xufSgpO1xuXG5leHBvcnQgZGVmYXVsdCBUcmlhbmd1bGF0aW9uOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvY29tbW9uXG4gKi9cblxuLyoqXG4gKiBEZWZhdWx0IFdNUyB2ZXJzaW9uLlxuICogQHR5cGUge3N0cmluZ31cbiAqL1xuZXhwb3J0IHZhciBERUZBVUxUX1dNU19WRVJTSU9OID0gJzEuMy4wJztcbi8qKlxuICogQ29udGV4dCBvcHRpb25zIHRvIGRpc2FibGUgaW1hZ2Ugc21vb3RoaW5nLlxuICogQHR5cGUge09iamVjdH1cbiAqL1xuXG5leHBvcnQgdmFyIElNQUdFX1NNT09USElOR19ESVNBQkxFRCA9IHtcbiAgaW1hZ2VTbW9vdGhpbmdFbmFibGVkOiBmYWxzZSxcbiAgbXNJbWFnZVNtb290aGluZ0VuYWJsZWQ6IGZhbHNlXG59OyIsIi8qKlxuICogQG1vZHVsZSBvbC9yZXByb2pcbiAqL1xuaW1wb3J0IHsgSU1BR0VfU01PT1RISU5HX0RJU0FCTEVEIH0gZnJvbSAnLi9zb3VyY2UvY29tbW9uLmpzJztcbmltcG9ydCB7IGFzc2lnbiB9IGZyb20gJy4vb2JqLmpzJztcbmltcG9ydCB7IGNvbnRhaW5zQ29vcmRpbmF0ZSwgY3JlYXRlRW1wdHksIGV4dGVuZCwgZm9yRWFjaENvcm5lciwgZ2V0Q2VudGVyLCBnZXRIZWlnaHQsIGdldFRvcExlZnQsIGdldFdpZHRoIH0gZnJvbSAnLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi9kb20uanMnO1xuaW1wb3J0IHsgZ2V0UG9pbnRSZXNvbHV0aW9uLCB0cmFuc2Zvcm0gfSBmcm9tICcuL3Byb2ouanMnO1xuaW1wb3J0IHsgc29sdmVMaW5lYXJTeXN0ZW0gfSBmcm9tICcuL21hdGguanMnO1xudmFyIGJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nXztcbi8qKlxuICogVGhpcyBkcmF3cyBhIHNtYWxsIHRyaWFuZ2xlIGludG8gYSBjYW52YXMgYnkgc2V0dGluZyB0aGUgdHJpYW5nbGUgYXMgdGhlIGNsaXAgcmVnaW9uXG4gKiBhbmQgdGhlbiBkcmF3aW5nIGEgKHRvbyBsYXJnZSkgcmVjdGFuZ2xlXG4gKlxuICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGN0eCBUaGUgY29udGV4dCBpbiB3aGljaCB0byBkcmF3IHRoZSB0cmlhbmdsZVxuICogQHBhcmFtIHtudW1iZXJ9IHUxIFRoZSB4LWNvb3JkaW5hdGUgb2YgdGhlIHNlY29uZCBwb2ludC4gVGhlIGZpcnN0IHBvaW50IGlzIDAsMC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2MSBUaGUgeS1jb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdTIgVGhlIHgtY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgcG9pbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdjIgVGhlIHktY29vcmRpbmF0ZSBvZiB0aGUgdGhpcmQgcG9pbnQuXG4gKi9cblxuZnVuY3Rpb24gZHJhd1Rlc3RUcmlhbmdsZShjdHgsIHUxLCB2MSwgdTIsIHYyKSB7XG4gIGN0eC5iZWdpblBhdGgoKTtcbiAgY3R4Lm1vdmVUbygwLCAwKTtcbiAgY3R4LmxpbmVUbyh1MSwgdjEpO1xuICBjdHgubGluZVRvKHUyLCB2Mik7XG4gIGN0eC5jbG9zZVBhdGgoKTtcbiAgY3R4LnNhdmUoKTtcbiAgY3R4LmNsaXAoKTtcbiAgY3R4LmZpbGxSZWN0KDAsIDAsIE1hdGgubWF4KHUxLCB1MikgKyAxLCBNYXRoLm1heCh2MSwgdjIpKTtcbiAgY3R4LnJlc3RvcmUoKTtcbn1cbi8qKlxuICogR2l2ZW4gdGhlIGRhdGEgZnJvbSBnZXRJbWFnZURhdGEsIHNlZSBpZiB0aGUgcmlnaHQgdmFsdWVzIGFwcGVhciBhdCB0aGUgcHJvdmlkZWQgb2Zmc2V0LlxuICogUmV0dXJucyB0cnVlIGlmIGVpdGhlciB0aGUgY29sb3Igb3IgdHJhbnNwYXJlbmN5IGlzIG9mZlxuICpcbiAqIEBwYXJhbSB7VWludDhDbGFtcGVkQXJyYXl9IGRhdGEgVGhlIGRhdGEgcmV0dXJuZWQgZnJvbSBnZXRJbWFnZURhdGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgVGhlIHBpeGVsIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiBkYXRhLlxuICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgZGlhZ29uYWwgcmVuZGVyaW5nIGlzIGJyb2tlblxuICovXG5cblxuZnVuY3Rpb24gdmVyaWZ5QnJva2VuRGlhZ29uYWxSZW5kZXJpbmcoZGF0YSwgb2Zmc2V0KSB7XG4gIC8vIHRoZSB2YWx1ZXMgb3VnaHQgdG8gYmUgY2xvc2UgdG8gdGhlIHJnYmEoMjEwLCAwLCAwLCAwLjc1KVxuICByZXR1cm4gTWF0aC5hYnMoZGF0YVtvZmZzZXQgKiA0XSAtIDIxMCkgPiAyIHx8IE1hdGguYWJzKGRhdGFbb2Zmc2V0ICogNCArIDNdIC0gMC43NSAqIDI1NSkgPiAyO1xufVxuLyoqXG4gKiBEZXRlcm1pbmVzIGlmIHRoZSBjdXJyZW50IGJyb3dzZXIgY29uZmlndXJhdGlvbiBjYW4gcmVuZGVyIHRyaWFuZ3VsYXIgY2xpcCByZWdpb25zIGNvcnJlY3RseS5cbiAqIFRoaXMgdmFsdWUgaXMgY2FjaGVkIHNvIHRoZSBmdW5jdGlvbiBpcyBvbmx5IGV4cGVuc2l2ZSB0aGUgZmlyc3QgdGltZSBjYWxsZWQuXG4gKiBGaXJlZm94IG9uIFdpbmRvd3MgKGFzIG9mIG5vdykgZG9lcyBub3QgaWYgSFdBIGlzIGVuYWJsZWQuIFNlZSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xNjA2OTc2XG4gKiBJRSBhbHNvIGRvZXNuJ3QuIENocm9tZSB3b3JrcywgYW5kIGV2ZXJ5dGhpbmcgc2VlbXMgdG8gd29yayBvbiBPU1ggYW5kIEFuZHJvaWQuIFRoaXMgZnVuY3Rpb24gY2FjaGVzIHRoZVxuICogcmVzdWx0LiBJIHN1cHBvc2UgdGhhdCBpdCBpcyBjb25jZWl2YWJseSBwb3NzaWJsZSB0aGF0IGEgYnJvd3NlciBtaWdodCBmbGlwIG1vZGVzIHdoaWxlIHRoZSBhcHAgaXNcbiAqIHJ1bm5pbmcsIGJ1dCBsZXRzIGhvcGUgbm90LlxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIERpYWdvbmFsIFJlbmRlcmluZyBpcyBicm9rZW4uXG4gKi9cblxuXG5mdW5jdGlvbiBpc0Jyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKCkge1xuICBpZiAoYnJva2VuRGlhZ29uYWxSZW5kZXJpbmdfID09PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgY3R4ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBjdHguZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2xpZ2h0ZXInO1xuICAgIGN0eC5maWxsU3R5bGUgPSAncmdiYSgyMTAsIDAsIDAsIDAuNzUpJztcbiAgICBkcmF3VGVzdFRyaWFuZ2xlKGN0eCwgNCwgNSwgNCwgMCk7XG4gICAgZHJhd1Rlc3RUcmlhbmdsZShjdHgsIDQsIDUsIDAsIDUpO1xuICAgIHZhciBkYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCAzLCAzKS5kYXRhO1xuICAgIGJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nXyA9IHZlcmlmeUJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKGRhdGEsIDApIHx8IHZlcmlmeUJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKGRhdGEsIDQpIHx8IHZlcmlmeUJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nKGRhdGEsIDgpO1xuICB9XG5cbiAgcmV0dXJuIGJyb2tlbkRpYWdvbmFsUmVuZGVyaW5nXztcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyBpZGVhbCByZXNvbHV0aW9uIHRvIHVzZSBmcm9tIHRoZSBzb3VyY2UgaW4gb3JkZXIgdG8gYWNoaWV2ZVxuICogcGl4ZWwgbWFwcGluZyBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byAxOjEgZHVyaW5nIHJlcHJvamVjdGlvbi5cbiAqIFRoZSByZXNvbHV0aW9uIGlzIGNhbGN1bGF0ZWQgcmVnYXJkbGVzcyBvZiB3aGF0IHJlc29sdXRpb25zXG4gKiBhcmUgYWN0dWFsbHkgYXZhaWxhYmxlIGluIHRoZSBkYXRhc2V0IChUaWxlR3JpZCwgSW1hZ2UsIC4uLikuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VQcm9qIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSB0YXJnZXRQcm9qIFRhcmdldCBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gdGFyZ2V0Q2VudGVyIFRhcmdldCBjZW50ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gdGFyZ2V0UmVzb2x1dGlvbiBUYXJnZXQgcmVzb2x1dGlvbi5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGJlc3QgcmVzb2x1dGlvbiB0byB1c2UuIENhbiBiZSArLUluZmluaXR5LCBOYU4gb3IgMC5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVTb3VyY2VSZXNvbHV0aW9uKHNvdXJjZVByb2osIHRhcmdldFByb2osIHRhcmdldENlbnRlciwgdGFyZ2V0UmVzb2x1dGlvbikge1xuICB2YXIgc291cmNlQ2VudGVyID0gdHJhbnNmb3JtKHRhcmdldENlbnRlciwgdGFyZ2V0UHJvaiwgc291cmNlUHJvaik7IC8vIGNhbGN1bGF0ZSB0aGUgaWRlYWwgcmVzb2x1dGlvbiBvZiB0aGUgc291cmNlIGRhdGFcblxuICB2YXIgc291cmNlUmVzb2x1dGlvbiA9IGdldFBvaW50UmVzb2x1dGlvbih0YXJnZXRQcm9qLCB0YXJnZXRSZXNvbHV0aW9uLCB0YXJnZXRDZW50ZXIpO1xuICB2YXIgdGFyZ2V0TWV0ZXJzUGVyVW5pdCA9IHRhcmdldFByb2ouZ2V0TWV0ZXJzUGVyVW5pdCgpO1xuXG4gIGlmICh0YXJnZXRNZXRlcnNQZXJVbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBzb3VyY2VSZXNvbHV0aW9uICo9IHRhcmdldE1ldGVyc1BlclVuaXQ7XG4gIH1cblxuICB2YXIgc291cmNlTWV0ZXJzUGVyVW5pdCA9IHNvdXJjZVByb2ouZ2V0TWV0ZXJzUGVyVW5pdCgpO1xuXG4gIGlmIChzb3VyY2VNZXRlcnNQZXJVbml0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBzb3VyY2VSZXNvbHV0aW9uIC89IHNvdXJjZU1ldGVyc1BlclVuaXQ7XG4gIH0gLy8gQmFzZWQgb24gdGhlIHByb2plY3Rpb24gcHJvcGVydGllcywgdGhlIHBvaW50IHJlc29sdXRpb24gYXQgdGhlIHNwZWNpZmllZFxuICAvLyBjb29yZGluYXRlcyBtYXkgYmUgc2xpZ2h0bHkgZGlmZmVyZW50LiBXZSBuZWVkIHRvIHJldmVyc2UtY29tcGVuc2F0ZSB0aGlzXG4gIC8vIGluIG9yZGVyIHRvIGFjaGlldmUgb3B0aW1hbCByZXN1bHRzLlxuXG5cbiAgdmFyIHNvdXJjZUV4dGVudCA9IHNvdXJjZVByb2ouZ2V0RXh0ZW50KCk7XG5cbiAgaWYgKCFzb3VyY2VFeHRlbnQgfHwgY29udGFpbnNDb29yZGluYXRlKHNvdXJjZUV4dGVudCwgc291cmNlQ2VudGVyKSkge1xuICAgIHZhciBjb21wZW5zYXRpb25GYWN0b3IgPSBnZXRQb2ludFJlc29sdXRpb24oc291cmNlUHJvaiwgc291cmNlUmVzb2x1dGlvbiwgc291cmNlQ2VudGVyKSAvIHNvdXJjZVJlc29sdXRpb247XG5cbiAgICBpZiAoaXNGaW5pdGUoY29tcGVuc2F0aW9uRmFjdG9yKSAmJiBjb21wZW5zYXRpb25GYWN0b3IgPiAwKSB7XG4gICAgICBzb3VyY2VSZXNvbHV0aW9uIC89IGNvbXBlbnNhdGlvbkZhY3RvcjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc291cmNlUmVzb2x1dGlvbjtcbn1cbi8qKlxuICogQ2FsY3VsYXRlcyBpZGVhbCByZXNvbHV0aW9uIHRvIHVzZSBmcm9tIHRoZSBzb3VyY2UgaW4gb3JkZXIgdG8gYWNoaWV2ZVxuICogcGl4ZWwgbWFwcGluZyBhcyBjbG9zZSBhcyBwb3NzaWJsZSB0byAxOjEgZHVyaW5nIHJlcHJvamVjdGlvbi5cbiAqIFRoZSByZXNvbHV0aW9uIGlzIGNhbGN1bGF0ZWQgcmVnYXJkbGVzcyBvZiB3aGF0IHJlc29sdXRpb25zXG4gKiBhcmUgYWN0dWFsbHkgYXZhaWxhYmxlIGluIHRoZSBkYXRhc2V0IChUaWxlR3JpZCwgSW1hZ2UsIC4uLikuXG4gKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VQcm9qIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSB0YXJnZXRQcm9qIFRhcmdldCBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IHRhcmdldEV4dGVudCBUYXJnZXQgZXh0ZW50XG4gKiBAcGFyYW0ge251bWJlcn0gdGFyZ2V0UmVzb2x1dGlvbiBUYXJnZXQgcmVzb2x1dGlvbi5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGJlc3QgcmVzb2x1dGlvbiB0byB1c2UuIENhbiBiZSArLUluZmluaXR5LCBOYU4gb3IgMC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlU291cmNlRXh0ZW50UmVzb2x1dGlvbihzb3VyY2VQcm9qLCB0YXJnZXRQcm9qLCB0YXJnZXRFeHRlbnQsIHRhcmdldFJlc29sdXRpb24pIHtcbiAgdmFyIHRhcmdldENlbnRlciA9IGdldENlbnRlcih0YXJnZXRFeHRlbnQpO1xuICB2YXIgc291cmNlUmVzb2x1dGlvbiA9IGNhbGN1bGF0ZVNvdXJjZVJlc29sdXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgdGFyZ2V0Q2VudGVyLCB0YXJnZXRSZXNvbHV0aW9uKTtcblxuICBpZiAoIWlzRmluaXRlKHNvdXJjZVJlc29sdXRpb24pIHx8IHNvdXJjZVJlc29sdXRpb24gPD0gMCkge1xuICAgIGZvckVhY2hDb3JuZXIodGFyZ2V0RXh0ZW50LCBmdW5jdGlvbiAoY29ybmVyKSB7XG4gICAgICBzb3VyY2VSZXNvbHV0aW9uID0gY2FsY3VsYXRlU291cmNlUmVzb2x1dGlvbihzb3VyY2VQcm9qLCB0YXJnZXRQcm9qLCBjb3JuZXIsIHRhcmdldFJlc29sdXRpb24pO1xuICAgICAgcmV0dXJuIGlzRmluaXRlKHNvdXJjZVJlc29sdXRpb24pICYmIHNvdXJjZVJlc29sdXRpb24gPiAwO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNvdXJjZVJlc29sdXRpb247XG59XG4vKipcbiAqIFJlbmRlcnMgdGhlIHNvdXJjZSBkYXRhIGludG8gbmV3IGNhbnZhcyBiYXNlZCBvbiB0aGUgdHJpYW5ndWxhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggV2lkdGggb2YgdGhlIGNhbnZhcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgSGVpZ2h0IG9mIHRoZSBjYW52YXMuXG4gKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzb3VyY2VSZXNvbHV0aW9uIFNvdXJjZSByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IHNvdXJjZUV4dGVudCBFeHRlbnQgb2YgdGhlIGRhdGEgc291cmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRhcmdldFJlc29sdXRpb24gVGFyZ2V0IHJlc29sdXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gdGFyZ2V0RXh0ZW50IFRhcmdldCBleHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcmVwcm9qL1RyaWFuZ3VsYXRpb24uanNcIikuZGVmYXVsdH0gdHJpYW5ndWxhdGlvblxuICogQ2FsY3VsYXRlZCB0cmlhbmd1bGF0aW9uLlxuICogQHBhcmFtIHtBcnJheTx7ZXh0ZW50OiBpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnQsXG4gKiAgICAgICAgICAgICAgICAgaW1hZ2U6IChIVE1MQ2FudmFzRWxlbWVudHxIVE1MSW1hZ2VFbGVtZW50fEhUTUxWaWRlb0VsZW1lbnQpfT59IHNvdXJjZXNcbiAqIEFycmF5IG9mIHNvdXJjZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gZ3V0dGVyIEd1dHRlciBvZiB0aGUgc291cmNlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9yZW5kZXJFZGdlcyBSZW5kZXIgcmVwcm9qZWN0aW9uIGVkZ2VzLlxuICogQHBhcmFtIHtvYmplY3Q9fSBvcHRfY29udGV4dE9wdGlvbnMgUHJvcGVydGllcyB0byBzZXQgb24gdGhlIGNhbnZhcyBjb250ZXh0LlxuICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IENhbnZhcyB3aXRoIHJlcHJvamVjdGVkIGRhdGEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlcih3aWR0aCwgaGVpZ2h0LCBwaXhlbFJhdGlvLCBzb3VyY2VSZXNvbHV0aW9uLCBzb3VyY2VFeHRlbnQsIHRhcmdldFJlc29sdXRpb24sIHRhcmdldEV4dGVudCwgdHJpYW5ndWxhdGlvbiwgc291cmNlcywgZ3V0dGVyLCBvcHRfcmVuZGVyRWRnZXMsIG9wdF9jb250ZXh0T3B0aW9ucykge1xuICB2YXIgY29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRChNYXRoLnJvdW5kKHBpeGVsUmF0aW8gKiB3aWR0aCksIE1hdGgucm91bmQocGl4ZWxSYXRpbyAqIGhlaWdodCkpO1xuICBhc3NpZ24oY29udGV4dCwgb3B0X2NvbnRleHRPcHRpb25zKTtcblxuICBpZiAoc291cmNlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gY29udGV4dC5jYW52YXM7XG4gIH1cblxuICBjb250ZXh0LnNjYWxlKHBpeGVsUmF0aW8sIHBpeGVsUmF0aW8pO1xuXG4gIGZ1bmN0aW9uIHBpeGVsUm91bmQodmFsdWUpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh2YWx1ZSAqIHBpeGVsUmF0aW8pIC8gcGl4ZWxSYXRpbztcbiAgfVxuXG4gIGNvbnRleHQuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2xpZ2h0ZXInO1xuICB2YXIgc291cmNlRGF0YUV4dGVudCA9IGNyZWF0ZUVtcHR5KCk7XG4gIHNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbiAoc3JjLCBpLCBhcnIpIHtcbiAgICBleHRlbmQoc291cmNlRGF0YUV4dGVudCwgc3JjLmV4dGVudCk7XG4gIH0pO1xuICB2YXIgY2FudmFzV2lkdGhJblVuaXRzID0gZ2V0V2lkdGgoc291cmNlRGF0YUV4dGVudCk7XG4gIHZhciBjYW52YXNIZWlnaHRJblVuaXRzID0gZ2V0SGVpZ2h0KHNvdXJjZURhdGFFeHRlbnQpO1xuICB2YXIgc3RpdGNoQ29udGV4dCA9IGNyZWF0ZUNhbnZhc0NvbnRleHQyRChNYXRoLnJvdW5kKHBpeGVsUmF0aW8gKiBjYW52YXNXaWR0aEluVW5pdHMgLyBzb3VyY2VSZXNvbHV0aW9uKSwgTWF0aC5yb3VuZChwaXhlbFJhdGlvICogY2FudmFzSGVpZ2h0SW5Vbml0cyAvIHNvdXJjZVJlc29sdXRpb24pKTtcbiAgYXNzaWduKHN0aXRjaENvbnRleHQsIG9wdF9jb250ZXh0T3B0aW9ucyk7XG4gIHZhciBzdGl0Y2hTY2FsZSA9IHBpeGVsUmF0aW8gLyBzb3VyY2VSZXNvbHV0aW9uO1xuICBzb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNyYywgaSwgYXJyKSB7XG4gICAgdmFyIHhQb3MgPSBzcmMuZXh0ZW50WzBdIC0gc291cmNlRGF0YUV4dGVudFswXTtcbiAgICB2YXIgeVBvcyA9IC0oc3JjLmV4dGVudFszXSAtIHNvdXJjZURhdGFFeHRlbnRbM10pO1xuICAgIHZhciBzcmNXaWR0aCA9IGdldFdpZHRoKHNyYy5leHRlbnQpO1xuICAgIHZhciBzcmNIZWlnaHQgPSBnZXRIZWlnaHQoc3JjLmV4dGVudCk7IC8vIFRoaXMgdGVzdCBzaG91bGQgbmV2ZXIgZmFpbCAtLSBidXQgaXQgZG9lcy4gTmVlZCB0byBmaW5kIGEgZml4IHRoZSB1cHN0cmVhbSBjb25kaXRpb25cblxuICAgIGlmIChzcmMuaW1hZ2Uud2lkdGggPiAwICYmIHNyYy5pbWFnZS5oZWlnaHQgPiAwKSB7XG4gICAgICBzdGl0Y2hDb250ZXh0LmRyYXdJbWFnZShzcmMuaW1hZ2UsIGd1dHRlciwgZ3V0dGVyLCBzcmMuaW1hZ2Uud2lkdGggLSAyICogZ3V0dGVyLCBzcmMuaW1hZ2UuaGVpZ2h0IC0gMiAqIGd1dHRlciwgeFBvcyAqIHN0aXRjaFNjYWxlLCB5UG9zICogc3RpdGNoU2NhbGUsIHNyY1dpZHRoICogc3RpdGNoU2NhbGUsIHNyY0hlaWdodCAqIHN0aXRjaFNjYWxlKTtcbiAgICB9XG4gIH0pO1xuICB2YXIgdGFyZ2V0VG9wTGVmdCA9IGdldFRvcExlZnQodGFyZ2V0RXh0ZW50KTtcbiAgdHJpYW5ndWxhdGlvbi5nZXRUcmlhbmdsZXMoKS5mb3JFYWNoKGZ1bmN0aW9uICh0cmlhbmdsZSwgaSwgYXJyKSB7XG4gICAgLyogQ2FsY3VsYXRlIGFmZmluZSB0cmFuc2Zvcm0gKHNyYyAtPiBkc3QpXG4gICAgICogUmVzdWx0aW5nIG1hdHJpeCBjYW4gYmUgdXNlZCB0byB0cmFuc2Zvcm0gY29vcmRpbmF0ZVxuICAgICAqIGZyb20gYHNvdXJjZVByb2plY3Rpb25gIHRvIGRlc3RpbmF0aW9uIHBpeGVscy5cbiAgICAgKlxuICAgICAqIFRvIG9wdGltaXplIG51bWJlciBvZiBjb250ZXh0IGNhbGxzIGFuZCBpbmNyZWFzZSBudW1lcmljYWwgc3RhYmlsaXR5LFxuICAgICAqIHdlIGFsc28gZG8gdGhlIGZvbGxvd2luZyBvcGVyYXRpb25zOlxuICAgICAqIHRyYW5zKC10b3BMZWZ0RXh0ZW50Q29ybmVyKSwgc2NhbGUoMSAvIHRhcmdldFJlc29sdXRpb24pLCBzY2FsZSgxLCAtMSlcbiAgICAgKiBoZXJlIGJlZm9yZSBzb2x2aW5nIHRoZSBsaW5lYXIgc3lzdGVtIHNvIFt1aSwgdmldIGFyZSBwaXhlbCBjb29yZGluYXRlcy5cbiAgICAgKlxuICAgICAqIFNyYyBwb2ludHM6IHhpLCB5aVxuICAgICAqIERzdCBwb2ludHM6IHVpLCB2aVxuICAgICAqIEFmZmluZSBjb2VmZmljaWVudHM6IGFpalxuICAgICAqXG4gICAgICogfCB4MCB5MCAxICAwICAwIDAgfCAgIHxhMDB8ICAgfHUwfFxuICAgICAqIHwgeDEgeTEgMSAgMCAgMCAwIHwgICB8YTAxfCAgIHx1MXxcbiAgICAgKiB8IHgyIHkyIDEgIDAgIDAgMCB8IHggfGEwMnwgPSB8dTJ8XG4gICAgICogfCAgMCAgMCAwIHgwIHkwIDEgfCAgIHxhMTB8ICAgfHYwfFxuICAgICAqIHwgIDAgIDAgMCB4MSB5MSAxIHwgICB8YTExfCAgIHx2MXxcbiAgICAgKiB8ICAwICAwIDAgeDIgeTIgMSB8ICAgfGExMnwgICB8djJ8XG4gICAgICovXG4gICAgdmFyIHNvdXJjZSA9IHRyaWFuZ2xlLnNvdXJjZTtcbiAgICB2YXIgdGFyZ2V0ID0gdHJpYW5nbGUudGFyZ2V0O1xuICAgIHZhciB4MCA9IHNvdXJjZVswXVswXSxcbiAgICAgICAgeTAgPSBzb3VyY2VbMF1bMV07XG4gICAgdmFyIHgxID0gc291cmNlWzFdWzBdLFxuICAgICAgICB5MSA9IHNvdXJjZVsxXVsxXTtcbiAgICB2YXIgeDIgPSBzb3VyY2VbMl1bMF0sXG4gICAgICAgIHkyID0gc291cmNlWzJdWzFdOyAvLyBNYWtlIHN1cmUgdGhhdCBldmVyeXRoaW5nIGlzIG9uIHBpeGVsIGJvdW5kYXJpZXNcblxuICAgIHZhciB1MCA9IHBpeGVsUm91bmQoKHRhcmdldFswXVswXSAtIHRhcmdldFRvcExlZnRbMF0pIC8gdGFyZ2V0UmVzb2x1dGlvbik7XG4gICAgdmFyIHYwID0gcGl4ZWxSb3VuZCgtKHRhcmdldFswXVsxXSAtIHRhcmdldFRvcExlZnRbMV0pIC8gdGFyZ2V0UmVzb2x1dGlvbik7XG4gICAgdmFyIHUxID0gcGl4ZWxSb3VuZCgodGFyZ2V0WzFdWzBdIC0gdGFyZ2V0VG9wTGVmdFswXSkgLyB0YXJnZXRSZXNvbHV0aW9uKTtcbiAgICB2YXIgdjEgPSBwaXhlbFJvdW5kKC0odGFyZ2V0WzFdWzFdIC0gdGFyZ2V0VG9wTGVmdFsxXSkgLyB0YXJnZXRSZXNvbHV0aW9uKTtcbiAgICB2YXIgdTIgPSBwaXhlbFJvdW5kKCh0YXJnZXRbMl1bMF0gLSB0YXJnZXRUb3BMZWZ0WzBdKSAvIHRhcmdldFJlc29sdXRpb24pO1xuICAgIHZhciB2MiA9IHBpeGVsUm91bmQoLSh0YXJnZXRbMl1bMV0gLSB0YXJnZXRUb3BMZWZ0WzFdKSAvIHRhcmdldFJlc29sdXRpb24pOyAvLyBTaGlmdCBhbGwgdGhlIHNvdXJjZSBwb2ludHMgdG8gaW1wcm92ZSBudW1lcmljYWwgc3RhYmlsaXR5XG4gICAgLy8gb2YgYWxsIHRoZSBzdWJzZXF1ZW50IGNhbGN1bGF0aW9ucy4gVGhlIFt4MCwgeTBdIGlzIHVzZWQgaGVyZS5cbiAgICAvLyBUaGlzIGlzIGFsc28gdXNlZCB0byBzaW1wbGlmeSB0aGUgbGluZWFyIHN5c3RlbS5cblxuICAgIHZhciBzb3VyY2VOdW1lcmljYWxTaGlmdFggPSB4MDtcbiAgICB2YXIgc291cmNlTnVtZXJpY2FsU2hpZnRZID0geTA7XG4gICAgeDAgPSAwO1xuICAgIHkwID0gMDtcbiAgICB4MSAtPSBzb3VyY2VOdW1lcmljYWxTaGlmdFg7XG4gICAgeTEgLT0gc291cmNlTnVtZXJpY2FsU2hpZnRZO1xuICAgIHgyIC09IHNvdXJjZU51bWVyaWNhbFNoaWZ0WDtcbiAgICB5MiAtPSBzb3VyY2VOdW1lcmljYWxTaGlmdFk7XG4gICAgdmFyIGF1Z21lbnRlZE1hdHJpeCA9IFtbeDEsIHkxLCAwLCAwLCB1MSAtIHUwXSwgW3gyLCB5MiwgMCwgMCwgdTIgLSB1MF0sIFswLCAwLCB4MSwgeTEsIHYxIC0gdjBdLCBbMCwgMCwgeDIsIHkyLCB2MiAtIHYwXV07XG4gICAgdmFyIGFmZmluZUNvZWZzID0gc29sdmVMaW5lYXJTeXN0ZW0oYXVnbWVudGVkTWF0cml4KTtcblxuICAgIGlmICghYWZmaW5lQ29lZnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb250ZXh0LnNhdmUoKTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuXG4gICAgaWYgKGlzQnJva2VuRGlhZ29uYWxSZW5kZXJpbmcoKSB8fCBvcHRfY29udGV4dE9wdGlvbnMgPT09IElNQUdFX1NNT09USElOR19ESVNBQkxFRCkge1xuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgYWxsIGxpbmVzIGFyZSBob3Jpem9udGFsIG9yIHZlcnRpY2FsXG4gICAgICBjb250ZXh0Lm1vdmVUbyh1MSwgdjEpOyAvLyBUaGlzIGlzIHRoZSBkaWFnb25hbCBsaW5lLiBEbyBpdCBpbiA0IHN0ZXBzXG5cbiAgICAgIHZhciBzdGVwcyA9IDQ7XG4gICAgICB2YXIgdWQgPSB1MCAtIHUxO1xuICAgICAgdmFyIHZkID0gdjAgLSB2MTtcblxuICAgICAgZm9yICh2YXIgc3RlcCA9IDA7IHN0ZXAgPCBzdGVwczsgc3RlcCsrKSB7XG4gICAgICAgIC8vIEdvIGhvcml6b250YWxseVxuICAgICAgICBjb250ZXh0LmxpbmVUbyh1MSArIHBpeGVsUm91bmQoKHN0ZXAgKyAxKSAqIHVkIC8gc3RlcHMpLCB2MSArIHBpeGVsUm91bmQoc3RlcCAqIHZkIC8gKHN0ZXBzIC0gMSkpKTsgLy8gR28gdmVydGljYWxseVxuXG4gICAgICAgIGlmIChzdGVwICE9IHN0ZXBzIC0gMSkge1xuICAgICAgICAgIGNvbnRleHQubGluZVRvKHUxICsgcGl4ZWxSb3VuZCgoc3RlcCArIDEpICogdWQgLyBzdGVwcyksIHYxICsgcGl4ZWxSb3VuZCgoc3RlcCArIDEpICogdmQgLyAoc3RlcHMgLSAxKSkpO1xuICAgICAgICB9XG4gICAgICB9IC8vIFdlIGFyZSBhbG1vc3QgYXQgdTByLCB2MHJcblxuXG4gICAgICBjb250ZXh0LmxpbmVUbyh1MiwgdjIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZXh0Lm1vdmVUbyh1MSwgdjEpO1xuICAgICAgY29udGV4dC5saW5lVG8odTAsIHYwKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHUyLCB2Mik7XG4gICAgfVxuXG4gICAgY29udGV4dC5jbGlwKCk7XG4gICAgY29udGV4dC50cmFuc2Zvcm0oYWZmaW5lQ29lZnNbMF0sIGFmZmluZUNvZWZzWzJdLCBhZmZpbmVDb2Vmc1sxXSwgYWZmaW5lQ29lZnNbM10sIHUwLCB2MCk7XG4gICAgY29udGV4dC50cmFuc2xhdGUoc291cmNlRGF0YUV4dGVudFswXSAtIHNvdXJjZU51bWVyaWNhbFNoaWZ0WCwgc291cmNlRGF0YUV4dGVudFszXSAtIHNvdXJjZU51bWVyaWNhbFNoaWZ0WSk7XG4gICAgY29udGV4dC5zY2FsZShzb3VyY2VSZXNvbHV0aW9uIC8gcGl4ZWxSYXRpbywgLXNvdXJjZVJlc29sdXRpb24gLyBwaXhlbFJhdGlvKTtcbiAgICBjb250ZXh0LmRyYXdJbWFnZShzdGl0Y2hDb250ZXh0LmNhbnZhcywgMCwgMCk7XG4gICAgY29udGV4dC5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGlmIChvcHRfcmVuZGVyRWRnZXMpIHtcbiAgICBjb250ZXh0LnNhdmUoKTtcbiAgICBjb250ZXh0Lmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdzb3VyY2Utb3Zlcic7XG4gICAgY29udGV4dC5zdHJva2VTdHlsZSA9ICdibGFjayc7XG4gICAgY29udGV4dC5saW5lV2lkdGggPSAxO1xuICAgIHRyaWFuZ3VsYXRpb24uZ2V0VHJpYW5nbGVzKCkuZm9yRWFjaChmdW5jdGlvbiAodHJpYW5nbGUsIGksIGFycikge1xuICAgICAgdmFyIHRhcmdldCA9IHRyaWFuZ2xlLnRhcmdldDtcbiAgICAgIHZhciB1MCA9ICh0YXJnZXRbMF1bMF0gLSB0YXJnZXRUb3BMZWZ0WzBdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICB2YXIgdjAgPSAtKHRhcmdldFswXVsxXSAtIHRhcmdldFRvcExlZnRbMV0pIC8gdGFyZ2V0UmVzb2x1dGlvbjtcbiAgICAgIHZhciB1MSA9ICh0YXJnZXRbMV1bMF0gLSB0YXJnZXRUb3BMZWZ0WzBdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICB2YXIgdjEgPSAtKHRhcmdldFsxXVsxXSAtIHRhcmdldFRvcExlZnRbMV0pIC8gdGFyZ2V0UmVzb2x1dGlvbjtcbiAgICAgIHZhciB1MiA9ICh0YXJnZXRbMl1bMF0gLSB0YXJnZXRUb3BMZWZ0WzBdKSAvIHRhcmdldFJlc29sdXRpb247XG4gICAgICB2YXIgdjIgPSAtKHRhcmdldFsyXVsxXSAtIHRhcmdldFRvcExlZnRbMV0pIC8gdGFyZ2V0UmVzb2x1dGlvbjtcbiAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICBjb250ZXh0Lm1vdmVUbyh1MSwgdjEpO1xuICAgICAgY29udGV4dC5saW5lVG8odTAsIHYwKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHUyLCB2Mik7XG4gICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICB9KTtcbiAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgfVxuXG4gIHJldHVybiBjb250ZXh0LmNhbnZhcztcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3JlcHJvai9UaWxlXG4gKi9cblxuXG5pbXBvcnQgeyBFUlJPUl9USFJFU0hPTEQgfSBmcm9tICcuL2NvbW1vbi5qcyc7XG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi4vVGlsZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgVHJpYW5ndWxhdGlvbiBmcm9tICcuL1RyaWFuZ3VsYXRpb24uanMnO1xuaW1wb3J0IHsgY2FsY3VsYXRlU291cmNlRXh0ZW50UmVzb2x1dGlvbiwgcmVuZGVyIGFzIHJlbmRlclJlcHJvamVjdGVkIH0gZnJvbSAnLi4vcmVwcm9qLmpzJztcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi4vbWF0aC5qcyc7XG5pbXBvcnQgeyBnZXRBcmVhLCBnZXRJbnRlcnNlY3Rpb24gfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgbGlzdGVuLCB1bmxpc3RlbkJ5S2V5IH0gZnJvbSAnLi4vZXZlbnRzLmpzJztcbi8qKlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcikgOiBpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9IEZ1bmN0aW9uVHlwZVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQ2xhc3MgZW5jYXBzdWxhdGluZyBzaW5nbGUgcmVwcm9qZWN0ZWQgdGlsZS5cbiAqIFNlZSB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9UaWxlSW1hZ2V+VGlsZUltYWdlfS5cbiAqXG4gKi9cblxudmFyIFJlcHJvalRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoUmVwcm9qVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHNvdXJjZVByb2ogU291cmNlIHByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gc291cmNlVGlsZUdyaWQgU291cmNlIHRpbGUgZ3JpZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gdGFyZ2V0UHJvaiBUYXJnZXQgcHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0YXJnZXRUaWxlR3JpZCBUYXJnZXQgdGlsZSBncmlkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBDb29yZGluYXRlIG9mIHRoZSB0aWxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHdyYXBwZWRUaWxlQ29vcmQgQ29vcmRpbmF0ZSBvZiB0aGUgdGlsZSB3cmFwcGVkIGluIFguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gZ3V0dGVyIEd1dHRlciBvZiB0aGUgc291cmNlIHRpbGVzLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9uVHlwZX0gZ2V0VGlsZUZ1bmN0aW9uXG4gICAqICAgICBGdW5jdGlvbiByZXR1cm5pbmcgc291cmNlIHRpbGVzICh6LCB4LCB5LCBwaXhlbFJhdGlvKS5cbiAgICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZXJyb3JUaHJlc2hvbGQgQWNjZXB0YWJsZSByZXByb2plY3Rpb24gZXJyb3IgKGluIHB4KS5cbiAgICogQHBhcmFtIHtib29sZWFuPX0gb3B0X3JlbmRlckVkZ2VzIFJlbmRlciByZXByb2plY3Rpb24gZWRnZXMuXG4gICAqIEBwYXJhbSB7b2JqZWN0PX0gb3B0X2NvbnRleHRPcHRpb25zIFByb3BlcnRpZXMgdG8gc2V0IG9uIHRoZSBjYW52YXMgY29udGV4dC5cbiAgICovXG5cblxuICBmdW5jdGlvbiBSZXByb2pUaWxlKHNvdXJjZVByb2osIHNvdXJjZVRpbGVHcmlkLCB0YXJnZXRQcm9qLCB0YXJnZXRUaWxlR3JpZCwgdGlsZUNvb3JkLCB3cmFwcGVkVGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBndXR0ZXIsIGdldFRpbGVGdW5jdGlvbiwgb3B0X2Vycm9yVGhyZXNob2xkLCBvcHRfcmVuZGVyRWRnZXMsIG9wdF9jb250ZXh0T3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHRpbGVDb29yZCwgVGlsZVN0YXRlLklETEUpIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMucmVuZGVyRWRnZXNfID0gb3B0X3JlbmRlckVkZ2VzICE9PSB1bmRlZmluZWQgPyBvcHRfcmVuZGVyRWRnZXMgOiBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtvYmplY3R9XG4gICAgICovXG5cbiAgICBfdGhpcy5jb250ZXh0T3B0aW9uc18gPSBvcHRfY29udGV4dE9wdGlvbnM7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMucGl4ZWxSYXRpb18gPSBwaXhlbFJhdGlvO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmd1dHRlcl8gPSBndXR0ZXI7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7SFRNTENhbnZhc0VsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5jYW52YXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc291cmNlVGlsZUdyaWRfID0gc291cmNlVGlsZUdyaWQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRhcmdldFRpbGVHcmlkXyA9IHRhcmdldFRpbGVHcmlkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9XG4gICAgICovXG5cbiAgICBfdGhpcy53cmFwcGVkVGlsZUNvb3JkXyA9IHdyYXBwZWRUaWxlQ29vcmQgPyB3cmFwcGVkVGlsZUNvb3JkIDogdGlsZUNvb3JkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFBcnJheTxpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc291cmNlVGlsZXNfID0gW107XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0FycmF5PGltcG9ydChcIi4uL2V2ZW50cy5qc1wiKS5FdmVudHNLZXk+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuc291cmNlc0xpc3RlbmVyS2V5c18gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZVpfID0gMDtcbiAgICB2YXIgdGFyZ2V0RXh0ZW50ID0gdGFyZ2V0VGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KF90aGlzLndyYXBwZWRUaWxlQ29vcmRfKTtcblxuICAgIHZhciBtYXhUYXJnZXRFeHRlbnQgPSBfdGhpcy50YXJnZXRUaWxlR3JpZF8uZ2V0RXh0ZW50KCk7XG5cbiAgICB2YXIgbWF4U291cmNlRXh0ZW50ID0gX3RoaXMuc291cmNlVGlsZUdyaWRfLmdldEV4dGVudCgpO1xuXG4gICAgdmFyIGxpbWl0ZWRUYXJnZXRFeHRlbnQgPSBtYXhUYXJnZXRFeHRlbnQgPyBnZXRJbnRlcnNlY3Rpb24odGFyZ2V0RXh0ZW50LCBtYXhUYXJnZXRFeHRlbnQpIDogdGFyZ2V0RXh0ZW50O1xuXG4gICAgaWYgKGdldEFyZWEobGltaXRlZFRhcmdldEV4dGVudCkgPT09IDApIHtcbiAgICAgIC8vIFRpbGUgaXMgY29tcGxldGVseSBvdXRzaWRlIHJhbmdlIC0+IEVNUFRZXG4gICAgICAvLyBUT0RPOiBpcyBpdCBhY3R1YWxseSBjb3JyZWN0IHRoYXQgdGhlIHNvdXJjZSBldmVuIGNyZWF0ZXMgdGhlIHRpbGUgP1xuICAgICAgX3RoaXMuc3RhdGUgPSBUaWxlU3RhdGUuRU1QVFk7XG4gICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuXG4gICAgdmFyIHNvdXJjZVByb2pFeHRlbnQgPSBzb3VyY2VQcm9qLmdldEV4dGVudCgpO1xuXG4gICAgaWYgKHNvdXJjZVByb2pFeHRlbnQpIHtcbiAgICAgIGlmICghbWF4U291cmNlRXh0ZW50KSB7XG4gICAgICAgIG1heFNvdXJjZUV4dGVudCA9IHNvdXJjZVByb2pFeHRlbnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXhTb3VyY2VFeHRlbnQgPSBnZXRJbnRlcnNlY3Rpb24obWF4U291cmNlRXh0ZW50LCBzb3VyY2VQcm9qRXh0ZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgdGFyZ2V0UmVzb2x1dGlvbiA9IHRhcmdldFRpbGVHcmlkLmdldFJlc29sdXRpb24oX3RoaXMud3JhcHBlZFRpbGVDb29yZF9bMF0pO1xuICAgIHZhciBzb3VyY2VSZXNvbHV0aW9uID0gY2FsY3VsYXRlU291cmNlRXh0ZW50UmVzb2x1dGlvbihzb3VyY2VQcm9qLCB0YXJnZXRQcm9qLCBsaW1pdGVkVGFyZ2V0RXh0ZW50LCB0YXJnZXRSZXNvbHV0aW9uKTtcblxuICAgIGlmICghaXNGaW5pdGUoc291cmNlUmVzb2x1dGlvbikgfHwgc291cmNlUmVzb2x1dGlvbiA8PSAwKSB7XG4gICAgICAvLyBpbnZhbGlkIHNvdXJjZVJlc29sdXRpb24gLT4gRU1QVFlcbiAgICAgIC8vIHByb2JhYmx5IGVkZ2VzIG9mIHRoZSBwcm9qZWN0aW9ucyB3aGVuIG5vIGV4dGVudCBpcyBkZWZpbmVkXG4gICAgICBfdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FTVBUWTtcbiAgICAgIHJldHVybiBfdGhpcztcbiAgICB9XG5cbiAgICB2YXIgZXJyb3JUaHJlc2hvbGRJblBpeGVscyA9IG9wdF9lcnJvclRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8gb3B0X2Vycm9yVGhyZXNob2xkIDogRVJST1JfVEhSRVNIT0xEO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFpbXBvcnQoXCIuL1RyaWFuZ3VsYXRpb24uanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLnRyaWFuZ3VsYXRpb25fID0gbmV3IFRyaWFuZ3VsYXRpb24oc291cmNlUHJvaiwgdGFyZ2V0UHJvaiwgbGltaXRlZFRhcmdldEV4dGVudCwgbWF4U291cmNlRXh0ZW50LCBzb3VyY2VSZXNvbHV0aW9uICogZXJyb3JUaHJlc2hvbGRJblBpeGVscywgdGFyZ2V0UmVzb2x1dGlvbik7XG5cbiAgICBpZiAoX3RoaXMudHJpYW5ndWxhdGlvbl8uZ2V0VHJpYW5nbGVzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBubyB2YWxpZCB0cmlhbmdsZXMgLT4gRU1QVFlcbiAgICAgIF90aGlzLnN0YXRlID0gVGlsZVN0YXRlLkVNUFRZO1xuICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cblxuICAgIF90aGlzLnNvdXJjZVpfID0gc291cmNlVGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24oc291cmNlUmVzb2x1dGlvbik7XG5cbiAgICB2YXIgc291cmNlRXh0ZW50ID0gX3RoaXMudHJpYW5ndWxhdGlvbl8uY2FsY3VsYXRlU291cmNlRXh0ZW50KCk7XG5cbiAgICBpZiAobWF4U291cmNlRXh0ZW50KSB7XG4gICAgICBpZiAoc291cmNlUHJvai5jYW5XcmFwWCgpKSB7XG4gICAgICAgIHNvdXJjZUV4dGVudFsxXSA9IGNsYW1wKHNvdXJjZUV4dGVudFsxXSwgbWF4U291cmNlRXh0ZW50WzFdLCBtYXhTb3VyY2VFeHRlbnRbM10pO1xuICAgICAgICBzb3VyY2VFeHRlbnRbM10gPSBjbGFtcChzb3VyY2VFeHRlbnRbM10sIG1heFNvdXJjZUV4dGVudFsxXSwgbWF4U291cmNlRXh0ZW50WzNdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNvdXJjZUV4dGVudCA9IGdldEludGVyc2VjdGlvbihzb3VyY2VFeHRlbnQsIG1heFNvdXJjZUV4dGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFnZXRBcmVhKHNvdXJjZUV4dGVudCkpIHtcbiAgICAgIF90aGlzLnN0YXRlID0gVGlsZVN0YXRlLkVNUFRZO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc291cmNlUmFuZ2UgPSBzb3VyY2VUaWxlR3JpZC5nZXRUaWxlUmFuZ2VGb3JFeHRlbnRBbmRaKHNvdXJjZUV4dGVudCwgX3RoaXMuc291cmNlWl8pO1xuXG4gICAgICBmb3IgKHZhciBzcmNYID0gc291cmNlUmFuZ2UubWluWDsgc3JjWCA8PSBzb3VyY2VSYW5nZS5tYXhYOyBzcmNYKyspIHtcbiAgICAgICAgZm9yICh2YXIgc3JjWSA9IHNvdXJjZVJhbmdlLm1pblk7IHNyY1kgPD0gc291cmNlUmFuZ2UubWF4WTsgc3JjWSsrKSB7XG4gICAgICAgICAgdmFyIHRpbGUgPSBnZXRUaWxlRnVuY3Rpb24oX3RoaXMuc291cmNlWl8sIHNyY1gsIHNyY1ksIHBpeGVsUmF0aW8pO1xuXG4gICAgICAgICAgaWYgKHRpbGUpIHtcbiAgICAgICAgICAgIF90aGlzLnNvdXJjZVRpbGVzXy5wdXNoKHRpbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoX3RoaXMuc291cmNlVGlsZXNfLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBfdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5FTVBUWTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgSFRNTCBDYW52YXMgZWxlbWVudCBmb3IgdGhpcyB0aWxlLlxuICAgKiBAcmV0dXJuIHtIVE1MQ2FudmFzRWxlbWVudH0gQ2FudmFzLlxuICAgKi9cblxuXG4gIFJlcHJvalRpbGUucHJvdG90eXBlLmdldEltYWdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhc187XG4gIH07XG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFJlcHJvalRpbGUucHJvdG90eXBlLnJlcHJvamVjdF8gPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNvdXJjZXMgPSBbXTtcbiAgICB0aGlzLnNvdXJjZVRpbGVzXy5mb3JFYWNoKGZ1bmN0aW9uICh0aWxlLCBpLCBhcnIpIHtcbiAgICAgIGlmICh0aWxlICYmIHRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICAgIHNvdXJjZXMucHVzaCh7XG4gICAgICAgICAgZXh0ZW50OiB0aGlzLnNvdXJjZVRpbGVHcmlkXy5nZXRUaWxlQ29vcmRFeHRlbnQodGlsZS50aWxlQ29vcmQpLFxuICAgICAgICAgIGltYWdlOiB0aWxlLmdldEltYWdlKClcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLnNvdXJjZVRpbGVzXy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKHNvdXJjZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLkVSUk9SO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgeiA9IHRoaXMud3JhcHBlZFRpbGVDb29yZF9bMF07XG4gICAgICB2YXIgc2l6ZSA9IHRoaXMudGFyZ2V0VGlsZUdyaWRfLmdldFRpbGVTaXplKHopO1xuICAgICAgdmFyIHdpZHRoID0gdHlwZW9mIHNpemUgPT09ICdudW1iZXInID8gc2l6ZSA6IHNpemVbMF07XG4gICAgICB2YXIgaGVpZ2h0ID0gdHlwZW9mIHNpemUgPT09ICdudW1iZXInID8gc2l6ZSA6IHNpemVbMV07XG4gICAgICB2YXIgdGFyZ2V0UmVzb2x1dGlvbiA9IHRoaXMudGFyZ2V0VGlsZUdyaWRfLmdldFJlc29sdXRpb24oeik7XG4gICAgICB2YXIgc291cmNlUmVzb2x1dGlvbiA9IHRoaXMuc291cmNlVGlsZUdyaWRfLmdldFJlc29sdXRpb24odGhpcy5zb3VyY2VaXyk7XG4gICAgICB2YXIgdGFyZ2V0RXh0ZW50ID0gdGhpcy50YXJnZXRUaWxlR3JpZF8uZ2V0VGlsZUNvb3JkRXh0ZW50KHRoaXMud3JhcHBlZFRpbGVDb29yZF8pO1xuICAgICAgdGhpcy5jYW52YXNfID0gcmVuZGVyUmVwcm9qZWN0ZWQod2lkdGgsIGhlaWdodCwgdGhpcy5waXhlbFJhdGlvXywgc291cmNlUmVzb2x1dGlvbiwgdGhpcy5zb3VyY2VUaWxlR3JpZF8uZ2V0RXh0ZW50KCksIHRhcmdldFJlc29sdXRpb24sIHRhcmdldEV4dGVudCwgdGhpcy50cmlhbmd1bGF0aW9uXywgc291cmNlcywgdGhpcy5ndXR0ZXJfLCB0aGlzLnJlbmRlckVkZ2VzXywgdGhpcy5jb250ZXh0T3B0aW9uc18pO1xuICAgICAgdGhpcy5zdGF0ZSA9IFRpbGVTdGF0ZS5MT0FERUQ7XG4gICAgfVxuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH07XG4gIC8qKlxuICAgKiBMb2FkIG5vdCB5ZXQgbG9hZGVkIFVSSS5cbiAgICovXG5cblxuICBSZXByb2pUaWxlLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnN0YXRlID09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICB0aGlzLnN0YXRlID0gVGlsZVN0YXRlLkxPQURJTkc7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIHZhciBsZWZ0VG9Mb2FkXzEgPSAwO1xuICAgICAgdGhpcy5zb3VyY2VzTGlzdGVuZXJLZXlzXyA9IFtdO1xuICAgICAgdGhpcy5zb3VyY2VUaWxlc18uZm9yRWFjaChmdW5jdGlvbiAodGlsZSwgaSwgYXJyKSB7XG4gICAgICAgIHZhciBzdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcblxuICAgICAgICBpZiAoc3RhdGUgPT0gVGlsZVN0YXRlLklETEUgfHwgc3RhdGUgPT0gVGlsZVN0YXRlLkxPQURJTkcpIHtcbiAgICAgICAgICBsZWZ0VG9Mb2FkXzErKztcbiAgICAgICAgICB2YXIgc291cmNlTGlzdGVuS2V5XzEgPSBsaXN0ZW4odGlsZSwgRXZlbnRUeXBlLkNIQU5HRSwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcblxuICAgICAgICAgICAgaWYgKHN0YXRlID09IFRpbGVTdGF0ZS5MT0FERUQgfHwgc3RhdGUgPT0gVGlsZVN0YXRlLkVSUk9SIHx8IHN0YXRlID09IFRpbGVTdGF0ZS5FTVBUWSkge1xuICAgICAgICAgICAgICB1bmxpc3RlbkJ5S2V5KHNvdXJjZUxpc3RlbktleV8xKTtcbiAgICAgICAgICAgICAgbGVmdFRvTG9hZF8xLS07XG5cbiAgICAgICAgICAgICAgaWYgKGxlZnRUb0xvYWRfMSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMudW5saXN0ZW5Tb3VyY2VzXygpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVwcm9qZWN0XygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgdGhpcyk7XG4gICAgICAgICAgdGhpcy5zb3VyY2VzTGlzdGVuZXJLZXlzXy5wdXNoKHNvdXJjZUxpc3RlbktleV8xKTtcbiAgICAgICAgfVxuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgIHRoaXMuc291cmNlVGlsZXNfLmZvckVhY2goZnVuY3Rpb24gKHRpbGUsIGksIGFycikge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aWxlLmdldFN0YXRlKCk7XG5cbiAgICAgICAgaWYgKHN0YXRlID09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICAgICAgdGlsZS5sb2FkKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAobGVmdFRvTG9hZF8xID09PSAwKSB7XG4gICAgICAgIHNldFRpbWVvdXQodGhpcy5yZXByb2plY3RfLmJpbmQodGhpcyksIDApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgUmVwcm9qVGlsZS5wcm90b3R5cGUudW5saXN0ZW5Tb3VyY2VzXyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNvdXJjZXNMaXN0ZW5lcktleXNfLmZvckVhY2godW5saXN0ZW5CeUtleSk7XG4gICAgdGhpcy5zb3VyY2VzTGlzdGVuZXJLZXlzXyA9IG51bGw7XG4gIH07XG5cbiAgcmV0dXJuIFJlcHJvalRpbGU7XG59KFRpbGUpO1xuXG5leHBvcnQgZGVmYXVsdCBSZXByb2pUaWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zdHJ1Y3RzL0xSVUNhY2hlXG4gKi9cbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4uL2Fzc2VydHMuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBFbnRyeVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGtleV9cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBuZXdlclxuICogQHByb3BlcnR5IHtPYmplY3R9IG9sZGVyXG4gKiBAcHJvcGVydHkgeyp9IHZhbHVlX1xuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogSW1wbGVtZW50cyBhIExlYXN0LVJlY2VudGx5LVVzZWQgY2FjaGUgd2hlcmUgdGhlIGtleXMgZG8gbm90IGNvbmZsaWN0IHdpdGhcbiAqIE9iamVjdCdzIHByb3BlcnRpZXMgKGUuZy4gJ2hhc093blByb3BlcnR5JyBpcyBub3QgYWxsb3dlZCBhcyBhIGtleSkuIEV4cGlyaW5nXG4gKiBpdGVtcyBmcm9tIHRoZSBjYWNoZSBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIHVzZXIuXG4gKlxuICogQGZpcmVzIGltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0XG4gKiBAdGVtcGxhdGUgVFxuICovXG5cbnZhciBMUlVDYWNoZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcj19IG9wdF9oaWdoV2F0ZXJNYXJrIEhpZ2ggd2F0ZXIgbWFyay5cbiAgICovXG4gIGZ1bmN0aW9uIExSVUNhY2hlKG9wdF9oaWdoV2F0ZXJNYXJrKSB7XG4gICAgLyoqXG4gICAgICogRGVzaXJlZCBtYXggY2FjaGUgc2l6ZSBhZnRlciBleHBpcmVDYWNoZSgpLiBJZiBzZXQgdG8gMCwgbm8gY2FjaGUgZW50cmllc1xuICAgICAqIHdpbGwgYmUgcHJ1bmVkIGF0IGFsbC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMuaGlnaFdhdGVyTWFyayA9IG9wdF9oaWdoV2F0ZXJNYXJrICE9PSB1bmRlZmluZWQgPyBvcHRfaGlnaFdhdGVyTWFyayA6IDIwNDg7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy5jb3VudF8gPSAwO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBFbnRyeT59XG4gICAgICovXG5cbiAgICB0aGlzLmVudHJpZXNfID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7P0VudHJ5fVxuICAgICAqL1xuXG4gICAgdGhpcy5vbGRlc3RfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHs/RW50cnl9XG4gICAgICovXG5cbiAgICB0aGlzLm5ld2VzdF8gPSBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBDYW4gZXhwaXJlIGNhY2hlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5jYW5FeHBpcmVDYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5oaWdoV2F0ZXJNYXJrID4gMCAmJiB0aGlzLmdldENvdW50KCkgPiB0aGlzLmhpZ2hXYXRlck1hcms7XG4gIH07XG4gIC8qKlxuICAgKiBGSVhNRSBlbXB0eSBkZXNjcmlwdGlvbiBmb3IganNkb2NcbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5jb3VudF8gPSAwO1xuICAgIHRoaXMuZW50cmllc18gPSB7fTtcbiAgICB0aGlzLm9sZGVzdF8gPSBudWxsO1xuICAgIHRoaXMubmV3ZXN0XyA9IG51bGw7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ29udGFpbnMga2V5LlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5jb250YWluc0tleSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5lbnRyaWVzXy5oYXNPd25Qcm9wZXJ0eShrZXkpO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtmdW5jdGlvbihULCBzdHJpbmcsIExSVUNhY2hlPFQ+KTogP30gZiBUaGUgZnVuY3Rpb25cbiAgICogICAgIHRvIGNhbGwgZm9yIGV2ZXJ5IGVudHJ5IGZyb20gdGhlIG9sZGVzdCB0byB0aGUgbmV3ZXIuIFRoaXMgZnVuY3Rpb24gdGFrZXNcbiAgICogICAgIDMgYXJndW1lbnRzICh0aGUgZW50cnkgdmFsdWUsIHRoZSBlbnRyeSBrZXkgYW5kIHRoZSBMUlVDYWNoZSBvYmplY3QpLlxuICAgKiAgICAgVGhlIHJldHVybiB2YWx1ZSBpcyBpZ25vcmVkLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGYpIHtcbiAgICB2YXIgZW50cnkgPSB0aGlzLm9sZGVzdF87XG5cbiAgICB3aGlsZSAoZW50cnkpIHtcbiAgICAgIGYoZW50cnkudmFsdWVfLCBlbnRyeS5rZXlfLCB0aGlzKTtcbiAgICAgIGVudHJ5ID0gZW50cnkubmV3ZXI7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBLZXkuXG4gICAqIEBwYXJhbSB7Kj19IG9wdF9vcHRpb25zIE9wdGlvbnMgKHJlc2VydmVyZCBmb3Igc3ViY2xhc3NlcykuXG4gICAqIEByZXR1cm4ge1R9IFZhbHVlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5LCBvcHRfb3B0aW9ucykge1xuICAgIHZhciBlbnRyeSA9IHRoaXMuZW50cmllc19ba2V5XTtcbiAgICBhc3NlcnQoZW50cnkgIT09IHVuZGVmaW5lZCwgMTUpOyAvLyBUcmllZCB0byBnZXQgYSB2YWx1ZSBmb3IgYSBrZXkgdGhhdCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgY2FjaGVcblxuICAgIGlmIChlbnRyeSA9PT0gdGhpcy5uZXdlc3RfKSB7XG4gICAgICByZXR1cm4gZW50cnkudmFsdWVfO1xuICAgIH0gZWxzZSBpZiAoZW50cnkgPT09IHRoaXMub2xkZXN0Xykge1xuICAgICAgdGhpcy5vbGRlc3RfID1cbiAgICAgIC8qKiBAdHlwZSB7RW50cnl9ICovXG4gICAgICB0aGlzLm9sZGVzdF8ubmV3ZXI7XG4gICAgICB0aGlzLm9sZGVzdF8ub2xkZXIgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRyeS5uZXdlci5vbGRlciA9IGVudHJ5Lm9sZGVyO1xuICAgICAgZW50cnkub2xkZXIubmV3ZXIgPSBlbnRyeS5uZXdlcjtcbiAgICB9XG5cbiAgICBlbnRyeS5uZXdlciA9IG51bGw7XG4gICAgZW50cnkub2xkZXIgPSB0aGlzLm5ld2VzdF87XG4gICAgdGhpcy5uZXdlc3RfLm5ld2VyID0gZW50cnk7XG4gICAgdGhpcy5uZXdlc3RfID0gZW50cnk7XG4gICAgcmV0dXJuIGVudHJ5LnZhbHVlXztcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBlbnRyeSBmcm9tIHRoZSBjYWNoZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgZW50cnkga2V5LlxuICAgKiBAcmV0dXJuIHtUfSBUaGUgcmVtb3ZlZCBlbnRyeS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBlbnRyeSA9IHRoaXMuZW50cmllc19ba2V5XTtcbiAgICBhc3NlcnQoZW50cnkgIT09IHVuZGVmaW5lZCwgMTUpOyAvLyBUcmllZCB0byBnZXQgYSB2YWx1ZSBmb3IgYSBrZXkgdGhhdCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgY2FjaGVcblxuICAgIGlmIChlbnRyeSA9PT0gdGhpcy5uZXdlc3RfKSB7XG4gICAgICB0aGlzLm5ld2VzdF8gPVxuICAgICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICAgIGVudHJ5Lm9sZGVyO1xuXG4gICAgICBpZiAodGhpcy5uZXdlc3RfKSB7XG4gICAgICAgIHRoaXMubmV3ZXN0Xy5uZXdlciA9IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChlbnRyeSA9PT0gdGhpcy5vbGRlc3RfKSB7XG4gICAgICB0aGlzLm9sZGVzdF8gPVxuICAgICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICAgIGVudHJ5Lm5ld2VyO1xuXG4gICAgICBpZiAodGhpcy5vbGRlc3RfKSB7XG4gICAgICAgIHRoaXMub2xkZXN0Xy5vbGRlciA9IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudHJ5Lm5ld2VyLm9sZGVyID0gZW50cnkub2xkZXI7XG4gICAgICBlbnRyeS5vbGRlci5uZXdlciA9IGVudHJ5Lm5ld2VyO1xuICAgIH1cblxuICAgIGRlbGV0ZSB0aGlzLmVudHJpZXNfW2tleV07XG4gICAgLS10aGlzLmNvdW50XztcbiAgICByZXR1cm4gZW50cnkudmFsdWVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBDb3VudC5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0Q291bnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY291bnRfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gS2V5cy5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0S2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga2V5cyA9IG5ldyBBcnJheSh0aGlzLmNvdW50Xyk7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciBlbnRyeTtcblxuICAgIGZvciAoZW50cnkgPSB0aGlzLm5ld2VzdF87IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm9sZGVyKSB7XG4gICAgICBrZXlzW2krK10gPSBlbnRyeS5rZXlfO1xuICAgIH1cblxuICAgIHJldHVybiBrZXlzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8VD59IFZhbHVlcy5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuZ2V0VmFsdWVzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZXMgPSBuZXcgQXJyYXkodGhpcy5jb3VudF8pO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgZW50cnk7XG5cbiAgICBmb3IgKGVudHJ5ID0gdGhpcy5uZXdlc3RfOyBlbnRyeTsgZW50cnkgPSBlbnRyeS5vbGRlcikge1xuICAgICAgdmFsdWVzW2krK10gPSBlbnRyeS52YWx1ZV87XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge1R9IExhc3QgdmFsdWUuXG4gICAqL1xuXG5cbiAgTFJVQ2FjaGUucHJvdG90eXBlLnBlZWtMYXN0ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm9sZGVzdF8udmFsdWVfO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfSBMYXN0IGtleS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucGVla0xhc3RLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMub2xkZXN0Xy5rZXlfO1xuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBrZXkgb2YgdGhlIG5ld2VzdCBpdGVtIGluIHRoZSBjYWNoZS4gIFRocm93cyBpZiB0aGUgY2FjaGUgaXMgZW1wdHkuXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIG5ld2VzdCBrZXkuXG4gICAqL1xuXG5cbiAgTFJVQ2FjaGUucHJvdG90eXBlLnBlZWtGaXJzdEtleSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5uZXdlc3RfLmtleV87XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtUfSB2YWx1ZSBWYWx1ZS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBlbnRyeSA9IHRoaXMub2xkZXN0XztcbiAgICBkZWxldGUgdGhpcy5lbnRyaWVzX1tlbnRyeS5rZXlfXTtcblxuICAgIGlmIChlbnRyeS5uZXdlcikge1xuICAgICAgZW50cnkubmV3ZXIub2xkZXIgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMub2xkZXN0XyA9XG4gICAgLyoqIEB0eXBlIHtFbnRyeX0gKi9cbiAgICBlbnRyeS5uZXdlcjtcblxuICAgIGlmICghdGhpcy5vbGRlc3RfKSB7XG4gICAgICB0aGlzLm5ld2VzdF8gPSBudWxsO1xuICAgIH1cblxuICAgIC0tdGhpcy5jb3VudF87XG4gICAgcmV0dXJuIGVudHJ5LnZhbHVlXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgS2V5LlxuICAgKiBAcGFyYW0ge1R9IHZhbHVlIFZhbHVlLlxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5yZXBsYWNlID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB0aGlzLmdldChrZXkpOyAvLyB1cGRhdGUgYG5ld2VzdF9gXG5cbiAgICB0aGlzLmVudHJpZXNfW2tleV0udmFsdWVfID0gdmFsdWU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IEtleS5cbiAgICogQHBhcmFtIHtUfSB2YWx1ZSBWYWx1ZS5cbiAgICovXG5cblxuICBMUlVDYWNoZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICBhc3NlcnQoIShrZXkgaW4gdGhpcy5lbnRyaWVzXyksIDE2KTsgLy8gVHJpZWQgdG8gc2V0IGEgdmFsdWUgZm9yIGEga2V5IHRoYXQgaXMgdXNlZCBhbHJlYWR5XG5cbiAgICB2YXIgZW50cnkgPSB7XG4gICAgICBrZXlfOiBrZXksXG4gICAgICBuZXdlcjogbnVsbCxcbiAgICAgIG9sZGVyOiB0aGlzLm5ld2VzdF8sXG4gICAgICB2YWx1ZV86IHZhbHVlXG4gICAgfTtcblxuICAgIGlmICghdGhpcy5uZXdlc3RfKSB7XG4gICAgICB0aGlzLm9sZGVzdF8gPSBlbnRyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5uZXdlc3RfLm5ld2VyID0gZW50cnk7XG4gICAgfVxuXG4gICAgdGhpcy5uZXdlc3RfID0gZW50cnk7XG4gICAgdGhpcy5lbnRyaWVzX1trZXldID0gZW50cnk7XG4gICAgKyt0aGlzLmNvdW50XztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCBhIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgZm9yIHRoZSBjYWNoZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQ2FjaGUgc2l6ZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIExSVUNhY2hlLnByb3RvdHlwZS5zZXRTaXplID0gZnVuY3Rpb24gKHNpemUpIHtcbiAgICB0aGlzLmhpZ2hXYXRlck1hcmsgPSBzaXplO1xuICB9O1xuXG4gIHJldHVybiBMUlVDYWNoZTtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgTFJVQ2FjaGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9UaWxlQ2FjaGVcbiAqL1xuXG5cbmltcG9ydCBMUlVDYWNoZSBmcm9tICcuL3N0cnVjdHMvTFJVQ2FjaGUuanMnO1xuaW1wb3J0IHsgZnJvbUtleSwgZ2V0S2V5IH0gZnJvbSAnLi90aWxlY29vcmQuanMnO1xuXG52YXIgVGlsZUNhY2hlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFRpbGVDYWNoZSwgX3N1cGVyKTtcblxuICBmdW5jdGlvbiBUaWxlQ2FjaGUoKSB7XG4gICAgcmV0dXJuIF9zdXBlciAhPT0gbnVsbCAmJiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKSB8fCB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0geyFPYmplY3Q8c3RyaW5nLCBib29sZWFuPn0gdXNlZFRpbGVzIFVzZWQgdGlsZXMuXG4gICAqL1xuXG5cbiAgVGlsZUNhY2hlLnByb3RvdHlwZS5leHBpcmVDYWNoZSA9IGZ1bmN0aW9uICh1c2VkVGlsZXMpIHtcbiAgICB3aGlsZSAodGhpcy5jYW5FeHBpcmVDYWNoZSgpKSB7XG4gICAgICB2YXIgdGlsZSA9IHRoaXMucGVla0xhc3QoKTtcblxuICAgICAgaWYgKHRpbGUuZ2V0S2V5KCkgaW4gdXNlZFRpbGVzKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5wb3AoKS5yZWxlYXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUHJ1bmUgYWxsIHRpbGVzIGZyb20gdGhlIGNhY2hlIHRoYXQgZG9uJ3QgaGF2ZSB0aGUgc2FtZSB6IGFzIHRoZSBuZXdlc3QgdGlsZS5cbiAgICovXG5cblxuICBUaWxlQ2FjaGUucHJvdG90eXBlLnBydW5lRXhjZXB0TmV3ZXN0WiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5nZXRDb3VudCgpID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGtleSA9IHRoaXMucGVla0ZpcnN0S2V5KCk7XG4gICAgdmFyIHRpbGVDb29yZCA9IGZyb21LZXkoa2V5KTtcbiAgICB2YXIgeiA9IHRpbGVDb29yZFswXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKHRpbGUpIHtcbiAgICAgIGlmICh0aWxlLnRpbGVDb29yZFswXSAhPT0geikge1xuICAgICAgICB0aGlzLnJlbW92ZShnZXRLZXkodGlsZS50aWxlQ29vcmQpKTtcbiAgICAgICAgdGlsZS5yZWxlYXNlKCk7XG4gICAgICB9XG4gICAgfS5iaW5kKHRoaXMpKTtcbiAgfTtcblxuICByZXR1cm4gVGlsZUNhY2hlO1xufShMUlVDYWNoZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFRpbGVDYWNoZTsiLCIvKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1RpbGVFdmVudFR5cGVcbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgdGlsZSBzdGFydHMgbG9hZGluZy5cbiAgICogQGV2ZW50IG1vZHVsZTpvbC9zb3VyY2UvVGlsZS5UaWxlU291cmNlRXZlbnQjdGlsZWxvYWRzdGFydFxuICAgKiBAYXBpXG4gICAqL1xuICBUSUxFTE9BRFNUQVJUOiAndGlsZWxvYWRzdGFydCcsXG5cbiAgLyoqXG4gICAqIFRyaWdnZXJlZCB3aGVuIGEgdGlsZSBmaW5pc2hlcyBsb2FkaW5nLCBlaXRoZXIgd2hlbiBpdHMgZGF0YSBpcyBsb2FkZWQsXG4gICAqIG9yIHdoZW4gbG9hZGluZyB3YXMgYWJvcnRlZCBiZWNhdXNlIHRoZSB0aWxlIGlzIG5vIGxvbmdlciBuZWVkZWQuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1RpbGUuVGlsZVNvdXJjZUV2ZW50I3RpbGVsb2FkZW5kXG4gICAqIEBhcGlcbiAgICovXG4gIFRJTEVMT0FERU5EOiAndGlsZWxvYWRlbmQnLFxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyZWQgaWYgdGlsZSBsb2FkaW5nIHJlc3VsdHMgaW4gYW4gZXJyb3IuXG4gICAqIEBldmVudCBtb2R1bGU6b2wvc291cmNlL1RpbGUuVGlsZVNvdXJjZUV2ZW50I3RpbGVsb2FkZXJyb3JcbiAgICogQGFwaVxuICAgKi9cbiAgVElMRUxPQURFUlJPUjogJ3RpbGVsb2FkZXJyb3InXG59OyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1RpbGVcbiAqL1xuXG5cbmltcG9ydCBFdmVudCBmcm9tICcuLi9ldmVudHMvRXZlbnQuanMnO1xuaW1wb3J0IFNvdXJjZSBmcm9tICcuL1NvdXJjZS5qcyc7XG5pbXBvcnQgVGlsZUNhY2hlIGZyb20gJy4uL1RpbGVDYWNoZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgeyBhYnN0cmFjdCB9IGZyb20gJy4uL3V0aWwuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBlcXVpdmFsZW50IH0gZnJvbSAnLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBnZXRLZXlaWFksIHdpdGhpbkV4dGVudEFuZFogfSBmcm9tICcuLi90aWxlY29vcmQuanMnO1xuaW1wb3J0IHsgZ2V0Rm9yUHJvamVjdGlvbiBhcyBnZXRUaWxlR3JpZEZvclByb2plY3Rpb24sIHdyYXBYIH0gZnJvbSAnLi4vdGlsZWdyaWQuanMnO1xuaW1wb3J0IHsgc2NhbGUgYXMgc2NhbGVTaXplLCB0b1NpemUgfSBmcm9tICcuLi9zaXplLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1NvdXJjZS5qc1wiKS5BdHRyaWJ1dGlvbkxpa2V9IFthdHRyaWJ1dGlvbnNdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZT10cnVlXSBBdHRyaWJ1dGlvbnMgYXJlIGNvbGxhcHNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjYWNoZVNpemVdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtvcGFxdWU9ZmFsc2VdIFdoZXRoZXIgdGhlIGxheWVyIGlzIG9wYXF1ZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGlsZVBpeGVsUmF0aW9dXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFtzdGF0ZV1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gW3RpbGVHcmlkXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbd3JhcFg9dHJ1ZV1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBba2V5XVxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt6RGlyZWN0aW9uPTBdXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzOyBub3JtYWxseSBvbmx5IHVzZWQgZm9yIGNyZWF0aW5nIHN1YmNsYXNzZXMgYW5kIG5vdFxuICogaW5zdGFudGlhdGVkIGluIGFwcHMuXG4gKiBCYXNlIGNsYXNzIGZvciBzb3VyY2VzIHByb3ZpZGluZyBpbWFnZXMgZGl2aWRlZCBpbnRvIGEgdGlsZSBncmlkLlxuICogQGFic3RyYWN0XG4gKiBAYXBpXG4gKi9cblxudmFyIFRpbGVTb3VyY2UgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZVNvdXJjZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBTb3VyY2VUaWxlIHNvdXJjZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFRpbGVTb3VyY2Uob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGF0dHJpYnV0aW9uczogb3B0aW9ucy5hdHRyaWJ1dGlvbnMsXG4gICAgICBhdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZTogb3B0aW9ucy5hdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSxcbiAgICAgIHByb2plY3Rpb246IG9wdGlvbnMucHJvamVjdGlvbixcbiAgICAgIHN0YXRlOiBvcHRpb25zLnN0YXRlLFxuICAgICAgd3JhcFg6IG9wdGlvbnMud3JhcFhcbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cblxuICAgIF90aGlzLm9wYXF1ZV8gPSBvcHRpb25zLm9wYXF1ZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vcGFxdWUgOiBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlUGl4ZWxSYXRpb18gPSBvcHRpb25zLnRpbGVQaXhlbFJhdGlvICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpbGVQaXhlbFJhdGlvIDogMTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlR3JpZCA9IG9wdGlvbnMudGlsZUdyaWQgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMudGlsZUdyaWQgOiBudWxsO1xuICAgIHZhciB0aWxlU2l6ZSA9IFsyNTYsIDI1Nl07XG4gICAgdmFyIHRpbGVHcmlkID0gb3B0aW9ucy50aWxlR3JpZDtcblxuICAgIGlmICh0aWxlR3JpZCkge1xuICAgICAgdG9TaXplKHRpbGVHcmlkLmdldFRpbGVTaXplKHRpbGVHcmlkLmdldE1pblpvb20oKSksIHRpbGVTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9UaWxlQ2FjaGUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMudGlsZUNhY2hlID0gbmV3IFRpbGVDYWNoZShvcHRpb25zLmNhY2hlU2l6ZSB8fCAwKTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRtcFNpemUgPSBbMCwgMF07XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgX3RoaXMua2V5XyA9IG9wdGlvbnMua2V5IHx8ICcnO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5PcHRpb25zfVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZU9wdGlvbnMgPSB7XG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb25cbiAgICB9O1xuICAgIC8qKlxuICAgICAqIHpEaXJlY3Rpb24gaGludCwgcmVhZCBieSB0aGUgcmVuZGVyZXIuIEluZGljYXRlcyB3aGljaCByZXNvbHV0aW9uIHNob3VsZCBiZSB1c2VkXG4gICAgICogYnkgYSByZW5kZXJlciBpZiB0aGUgdmlld3MgcmVzb2x1dGlvbiBkb2VzIG5vdCBtYXRjaCBhbnkgcmVzb2x1dGlvbiBvZiB0aGUgdGlsZSBzb3VyY2UuXG4gICAgICogSWYgMCwgdGhlIG5lYXJlc3QgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuIElmIDEsIHRoZSBuZWFyZXN0IGxvd2VyIHJlc29sdXRpb25cbiAgICAgKiB3aWxsIGJlIHVzZWQuIElmIC0xLCB0aGUgbmVhcmVzdCBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnpEaXJlY3Rpb24gPSBvcHRpb25zLnpEaXJlY3Rpb24gPyBvcHRpb25zLnpEaXJlY3Rpb24gOiAwO1xuICAgIHJldHVybiBfdGhpcztcbiAgfVxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gQ2FuIGV4cGlyZSBjYWNoZS5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5jYW5FeHBpcmVDYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlQ2FjaGUuY2FuRXhwaXJlQ2FjaGUoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHshT2JqZWN0PHN0cmluZywgYm9vbGVhbj59IHVzZWRUaWxlcyBVc2VkIHRpbGVzLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmV4cGlyZUNhY2hlID0gZnVuY3Rpb24gKHByb2plY3Rpb24sIHVzZWRUaWxlcykge1xuICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLmdldFRpbGVDYWNoZUZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgICBpZiAodGlsZUNhY2hlKSB7XG4gICAgICB0aWxlQ2FjaGUuZXhwaXJlQ2FjaGUodXNlZFRpbGVzKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFpvb20gbGV2ZWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZVJhbmdlLmpzXCIpLmRlZmF1bHR9IHRpbGVSYW5nZSBUaWxlIHJhbmdlLlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdCk6KGJvb2xlYW58dm9pZCl9IGNhbGxiYWNrIENhbGxlZCB3aXRoIGVhY2hcbiAgICogICAgIGxvYWRlZCB0aWxlLiAgSWYgdGhlIGNhbGxiYWNrIHJldHVybnMgYGZhbHNlYCwgdGhlIHRpbGUgd2lsbCBub3QgYmVcbiAgICogICAgIGNvbnNpZGVyZWQgbG9hZGVkLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdGlsZSByYW5nZSBpcyBmdWxseSBjb3ZlcmVkIHdpdGggbG9hZGVkIHRpbGVzLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmZvckVhY2hMb2FkZWRUaWxlID0gZnVuY3Rpb24gKHByb2plY3Rpb24sIHosIHRpbGVSYW5nZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgdGlsZUNhY2hlID0gdGhpcy5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgaWYgKCF0aWxlQ2FjaGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgY292ZXJlZCA9IHRydWU7XG4gICAgdmFyIHRpbGUsIHRpbGVDb29yZEtleSwgbG9hZGVkO1xuXG4gICAgZm9yICh2YXIgeCA9IHRpbGVSYW5nZS5taW5YOyB4IDw9IHRpbGVSYW5nZS5tYXhYOyArK3gpIHtcbiAgICAgIGZvciAodmFyIHkgPSB0aWxlUmFuZ2UubWluWTsgeSA8PSB0aWxlUmFuZ2UubWF4WTsgKyt5KSB7XG4gICAgICAgIHRpbGVDb29yZEtleSA9IGdldEtleVpYWSh6LCB4LCB5KTtcbiAgICAgICAgbG9hZGVkID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKHRpbGVDYWNoZS5jb250YWluc0tleSh0aWxlQ29vcmRLZXkpKSB7XG4gICAgICAgICAgdGlsZSA9XG4gICAgICAgICAgLyoqIEB0eXBlIHshaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSAqL1xuICAgICAgICAgIHRpbGVDYWNoZS5nZXQodGlsZUNvb3JkS2V5KTtcbiAgICAgICAgICBsb2FkZWQgPSB0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5MT0FERUQ7XG5cbiAgICAgICAgICBpZiAobG9hZGVkKSB7XG4gICAgICAgICAgICBsb2FkZWQgPSBjYWxsYmFjayh0aWxlKSAhPT0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFsb2FkZWQpIHtcbiAgICAgICAgICBjb3ZlcmVkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY292ZXJlZDtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfSBHdXR0ZXIuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0R3V0dGVyRm9yUHJvamVjdGlvbiA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIDA7XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGtleSB0byBiZSB1c2VkIGZvciBhbGwgdGlsZXMgaW4gdGhlIHNvdXJjZS5cbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUga2V5IGZvciBhbGwgdGlsZXMuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRLZXkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMua2V5XztcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdmFsdWUgdG8gYmUgdXNlZCBhcyB0aGUga2V5IGZvciBhbGwgdGlsZXMgaW4gdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IGZvciB0aWxlcy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLnNldEtleSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAodGhpcy5rZXlfICE9PSBrZXkpIHtcbiAgICAgIHRoaXMua2V5XyA9IGtleTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gT3BhcXVlLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldE9wYXF1ZSA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMub3BhcXVlXztcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFJlc29sdXRpb25zLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldFJlc29sdXRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnRpbGVHcmlkLmdldFJlc29sdXRpb25zKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtudW1iZXJ9IHogVGlsZSBjb29yZGluYXRlIHouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB4IFRpbGUgY29vcmRpbmF0ZSB4LlxuICAgKiBAcGFyYW0ge251bWJlcn0geSBUaWxlIGNvb3JkaW5hdGUgeS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsUmF0aW8gUGl4ZWwgcmF0aW8uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL1RpbGUuanNcIikuZGVmYXVsdH0gVGlsZS5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlID0gZnVuY3Rpb24gKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gYWJzdHJhY3QoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgdGlsZSBncmlkIG9mIHRoZSB0aWxlIHNvdXJjZS5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gVGlsZSBncmlkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0VGlsZUdyaWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGlsZUdyaWQ7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4geyFpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBUaWxlIGdyaWQuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICBpZiAoIXRoaXMudGlsZUdyaWQpIHtcbiAgICAgIHJldHVybiBnZXRUaWxlR3JpZEZvclByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnRpbGVHcmlkO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vVGlsZUNhY2hlLmpzXCIpLmRlZmF1bHR9IFRpbGUgY2FjaGUuXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICBhc3NlcnQoZXF1aXZhbGVudCh0aGlzLmdldFByb2plY3Rpb24oKSwgcHJvamVjdGlvbiksIDY4IC8vIEEgVmVjdG9yVGlsZSBzb3VyY2UgY2FuIG9ubHkgYmUgcmVuZGVyZWQgaWYgaXQgaGFzIGEgcHJvamVjdGlvbiBjb21wYXRpYmxlIHdpdGggdGhlIHZpZXcgcHJvamVjdGlvbi5cbiAgICApO1xuICAgIHJldHVybiB0aGlzLnRpbGVDYWNoZTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgdGlsZSBwaXhlbCByYXRpbyBmb3IgdGhpcyBzb3VyY2UuIFN1YmNsYXNzZXMgbWF5IG92ZXJyaWRlIHRoaXNcbiAgICogbWV0aG9kLCB3aGljaCBpcyBtZWFudCB0byByZXR1cm4gYSBzdXBwb3J0ZWQgcGl4ZWwgcmF0aW8gdGhhdCBtYXRjaGVzIHRoZVxuICAgKiBwcm92aWRlZCBgcGl4ZWxSYXRpb2AgYXMgY2xvc2UgYXMgcG9zc2libGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IFRpbGUgcGl4ZWwgcmF0aW8uXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0VGlsZVBpeGVsUmF0aW8gPSBmdW5jdGlvbiAocGl4ZWxSYXRpbykge1xuICAgIHJldHVybiB0aGlzLnRpbGVQaXhlbFJhdGlvXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gVGlsZSBzaXplLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLmdldFRpbGVQaXhlbFNpemUgPSBmdW5jdGlvbiAoeiwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlUGl4ZWxSYXRpbyA9IHRoaXMuZ2V0VGlsZVBpeGVsUmF0aW8ocGl4ZWxSYXRpbyk7XG4gICAgdmFyIHRpbGVTaXplID0gdG9TaXplKHRpbGVHcmlkLmdldFRpbGVTaXplKHopLCB0aGlzLnRtcFNpemUpO1xuXG4gICAgaWYgKHRpbGVQaXhlbFJhdGlvID09IDEpIHtcbiAgICAgIHJldHVybiB0aWxlU2l6ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNjYWxlU2l6ZSh0aWxlU2l6ZSwgdGlsZVBpeGVsUmF0aW8sIHRoaXMudG1wU2l6ZSk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogUmV0dXJucyBhIHRpbGUgY29vcmRpbmF0ZSB3cmFwcGVkIGFyb3VuZCB0aGUgeC1heGlzLiBXaGVuIHRoZSB0aWxlIGNvb3JkaW5hdGVcbiAgICogaXMgb3V0c2lkZSB0aGUgcmVzb2x1dGlvbiBhbmQgZXh0ZW50IHJhbmdlIG9mIHRoZSB0aWxlIGdyaWQsIGBudWxsYCB3aWxsIGJlXG4gICAqIHJldHVybmVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ9fSBvcHRfcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSBUaWxlIGNvb3JkaW5hdGUgdG8gYmUgcGFzc2VkIHRvIHRoZSB0aWxlVXJsRnVuY3Rpb24gb3JcbiAgICogICAgIG51bGwgaWYgbm8gdGlsZSBVUkwgc2hvdWxkIGJlIGNyZWF0ZWQgZm9yIHRoZSBwYXNzZWQgYHRpbGVDb29yZGAuXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuZ2V0VGlsZUNvb3JkRm9yVGlsZVVybEZ1bmN0aW9uID0gZnVuY3Rpb24gKHRpbGVDb29yZCwgb3B0X3Byb2plY3Rpb24pIHtcbiAgICB2YXIgcHJvamVjdGlvbiA9IG9wdF9wcm9qZWN0aW9uICE9PSB1bmRlZmluZWQgPyBvcHRfcHJvamVjdGlvbiA6IHRoaXMuZ2V0UHJvamVjdGlvbigpO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHRoaXMuZ2V0V3JhcFgoKSAmJiBwcm9qZWN0aW9uLmlzR2xvYmFsKCkpIHtcbiAgICAgIHRpbGVDb29yZCA9IHdyYXBYKHRpbGVHcmlkLCB0aWxlQ29vcmQsIHByb2plY3Rpb24pO1xuICAgIH1cblxuICAgIHJldHVybiB3aXRoaW5FeHRlbnRBbmRaKHRpbGVDb29yZCwgdGlsZUdyaWQpID8gdGlsZUNvb3JkIDogbnVsbDtcbiAgfTtcbiAgLyoqXG4gICAqIFJlbW92ZSBhbGwgY2FjaGVkIHRpbGVzIGZyb20gdGhlIHNvdXJjZS4gVGhlIG5leHQgcmVuZGVyIGN5Y2xlIHdpbGwgZmV0Y2ggbmV3IHRpbGVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVGlsZVNvdXJjZS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy50aWxlQ2FjaGUuY2xlYXIoKTtcbiAgfTtcblxuICBUaWxlU291cmNlLnByb3RvdHlwZS5yZWZyZXNoID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuY2xlYXIoKTtcblxuICAgIF9zdXBlci5wcm90b3R5cGUucmVmcmVzaC5jYWxsKHRoaXMpO1xuICB9O1xuICAvKipcbiAgICogSW5jcmVhc2VzIHRoZSBjYWNoZSBzaXplIGlmIG5lZWRlZFxuICAgKiBAcGFyYW0ge251bWJlcn0gdGlsZUNvdW50IE1pbmltdW0gbnVtYmVyIG9mIHRpbGVzIG5lZWRlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKi9cblxuXG4gIFRpbGVTb3VyY2UucHJvdG90eXBlLnVwZGF0ZUNhY2hlU2l6ZSA9IGZ1bmN0aW9uICh0aWxlQ291bnQsIHByb2plY3Rpb24pIHtcbiAgICB2YXIgdGlsZUNhY2hlID0gdGhpcy5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHRpbGVDb3VudCA+IHRpbGVDYWNoZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgICB0aWxlQ2FjaGUuaGlnaFdhdGVyTWFyayA9IHRpbGVDb3VudDtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBNYXJrcyBhIHRpbGUgY29vcmQgYXMgYmVpbmcgdXNlZCwgd2l0aG91dCB0cmlnZ2VyaW5nIGEgbG9hZC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFRpbGUgY29vcmRpbmF0ZSB6LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICovXG5cblxuICBUaWxlU291cmNlLnByb3RvdHlwZS51c2VUaWxlID0gZnVuY3Rpb24gKHosIHgsIHksIHByb2plY3Rpb24pIHt9O1xuXG4gIHJldHVybiBUaWxlU291cmNlO1xufShTb3VyY2UpO1xuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBFdmVudHMgZW1pdHRlZCBieSB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9UaWxlflRpbGVTb3VyY2V9IGluc3RhbmNlcyBhcmUgaW5zdGFuY2VzIG9mIHRoaXNcbiAqIHR5cGUuXG4gKi9cblxuXG52YXIgVGlsZVNvdXJjZUV2ZW50ID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFRpbGVTb3VyY2VFdmVudCwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIFR5cGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSB0aWxlIFRoZSB0aWxlLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFRpbGVTb3VyY2VFdmVudCh0eXBlLCB0aWxlKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgdHlwZSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBUaGUgdGlsZSByZWxhdGVkIHRvIHRoZSBldmVudC5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fVxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuXG4gICAgX3RoaXMudGlsZSA9IHRpbGU7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG5cbiAgcmV0dXJuIFRpbGVTb3VyY2VFdmVudDtcbn0oRXZlbnQpO1xuXG5leHBvcnQgeyBUaWxlU291cmNlRXZlbnQgfTtcbmV4cG9ydCBkZWZhdWx0IFRpbGVTb3VyY2U7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3RpbGV1cmxmdW5jdGlvblxuICovXG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tICcuL2Fzc2VydHMuanMnO1xuaW1wb3J0IHsgbW9kdWxvIH0gZnJvbSAnLi9tYXRoLmpzJztcbmltcG9ydCB7IGhhc2ggYXMgdGlsZUNvb3JkSGFzaCB9IGZyb20gJy4vdGlsZWNvb3JkLmpzJztcbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHRlbXBsYXRlIFRlbXBsYXRlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IHRpbGVHcmlkIFRpbGUgZ3JpZC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gVGlsZSBVUkwgZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgdGlsZUdyaWQpIHtcbiAgdmFyIHpSZWdFeCA9IC9cXHt6XFx9L2c7XG4gIHZhciB4UmVnRXggPSAvXFx7eFxcfS9nO1xuICB2YXIgeVJlZ0V4ID0gL1xce3lcXH0vZztcbiAgdmFyIGRhc2hZUmVnRXggPSAvXFx7LXlcXH0vZztcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgQ29vcmRpbmF0ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaWxlIFVSTC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAodGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gICAgICBpZiAoIXRpbGVDb29yZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoelJlZ0V4LCB0aWxlQ29vcmRbMF0udG9TdHJpbmcoKSkucmVwbGFjZSh4UmVnRXgsIHRpbGVDb29yZFsxXS50b1N0cmluZygpKS5yZXBsYWNlKHlSZWdFeCwgdGlsZUNvb3JkWzJdLnRvU3RyaW5nKCkpLnJlcGxhY2UoZGFzaFlSZWdFeCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciB6ID0gdGlsZUNvb3JkWzBdO1xuICAgICAgICAgIHZhciByYW5nZSA9IHRpbGVHcmlkLmdldEZ1bGxUaWxlUmFuZ2Uoeik7XG4gICAgICAgICAgYXNzZXJ0KHJhbmdlLCA1NSk7IC8vIFRoZSB7LXl9IHBsYWNlaG9sZGVyIHJlcXVpcmVzIGEgdGlsZSBncmlkIHdpdGggZXh0ZW50XG5cbiAgICAgICAgICB2YXIgeSA9IHJhbmdlLmdldEhlaWdodCgpIC0gdGlsZUNvb3JkWzJdIC0gMTtcbiAgICAgICAgICByZXR1cm4geS50b1N0cmluZygpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gdGVtcGxhdGVzIFRlbXBsYXRlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0aWxlR3JpZCBUaWxlIGdyaWQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuVXJsRnVuY3Rpb259IFRpbGUgVVJMIGZ1bmN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGcm9tVGVtcGxhdGVzKHRlbXBsYXRlcywgdGlsZUdyaWQpIHtcbiAgdmFyIGxlbiA9IHRlbXBsYXRlcy5sZW5ndGg7XG4gIHZhciB0aWxlVXJsRnVuY3Rpb25zID0gbmV3IEFycmF5KGxlbik7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIHRpbGVVcmxGdW5jdGlvbnNbaV0gPSBjcmVhdGVGcm9tVGVtcGxhdGUodGVtcGxhdGVzW2ldLCB0aWxlR3JpZCk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlRnJvbVRpbGVVcmxGdW5jdGlvbnModGlsZVVybEZ1bmN0aW9ucyk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9uPn0gdGlsZVVybEZ1bmN0aW9ucyBUaWxlIFVSTCBGdW5jdGlvbnMuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1RpbGUuanNcIikuVXJsRnVuY3Rpb259IFRpbGUgVVJMIGZ1bmN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGcm9tVGlsZVVybEZ1bmN0aW9ucyh0aWxlVXJsRnVuY3Rpb25zKSB7XG4gIGlmICh0aWxlVXJsRnVuY3Rpb25zLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiB0aWxlVXJsRnVuY3Rpb25zWzBdO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgQ29vcmRpbmF0ZS5cbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaWxlIFVSTC5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiAodGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gICAgICBpZiAoIXRpbGVDb29yZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGggPSB0aWxlQ29vcmRIYXNoKHRpbGVDb29yZCk7XG4gICAgICAgIHZhciBpbmRleCA9IG1vZHVsbyhoLCB0aWxlVXJsRnVuY3Rpb25zLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiB0aWxlVXJsRnVuY3Rpb25zW2luZGV4XSh0aWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuICAgICAgfVxuICAgIH1cbiAgKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICogQHJldHVybiB7c3RyaW5nfHVuZGVmaW5lZH0gVGlsZSBVUkwuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIG51bGxUaWxlVXJsRnVuY3Rpb24odGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVVJMLlxuICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn0gQXJyYXkgb2YgdXJscy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXhwYW5kVXJsKHVybCkge1xuICB2YXIgdXJscyA9IFtdO1xuICB2YXIgbWF0Y2ggPSAvXFx7KFthLXpdKS0oW2Etel0pXFx9Ly5leGVjKHVybCk7XG5cbiAgaWYgKG1hdGNoKSB7XG4gICAgLy8gY2hhciByYW5nZVxuICAgIHZhciBzdGFydENoYXJDb2RlID0gbWF0Y2hbMV0uY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgc3RvcENoYXJDb2RlID0gbWF0Y2hbMl0uY2hhckNvZGVBdCgwKTtcbiAgICB2YXIgY2hhckNvZGUgPSB2b2lkIDA7XG5cbiAgICBmb3IgKGNoYXJDb2RlID0gc3RhcnRDaGFyQ29kZTsgY2hhckNvZGUgPD0gc3RvcENoYXJDb2RlOyArK2NoYXJDb2RlKSB7XG4gICAgICB1cmxzLnB1c2godXJsLnJlcGxhY2UobWF0Y2hbMF0sIFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhckNvZGUpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybHM7XG4gIH1cblxuICBtYXRjaCA9IC9cXHsoXFxkKyktKFxcZCspXFx9Ly5leGVjKHVybCk7XG5cbiAgaWYgKG1hdGNoKSB7XG4gICAgLy8gbnVtYmVyIHJhbmdlXG4gICAgdmFyIHN0b3BfMSA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBmb3IgKHZhciBpID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTsgaSA8PSBzdG9wXzE7IGkrKykge1xuICAgICAgdXJscy5wdXNoKHVybC5yZXBsYWNlKG1hdGNoWzBdLCBpLnRvU3RyaW5nKCkpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXJscztcbiAgfVxuXG4gIHVybHMucHVzaCh1cmwpO1xuICByZXR1cm4gdXJscztcbn0iLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL3NvdXJjZS9VcmxUaWxlXG4gKi9cblxuXG5pbXBvcnQgVGlsZUV2ZW50VHlwZSBmcm9tICcuL1RpbGVFdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGVTb3VyY2UsIHsgVGlsZVNvdXJjZUV2ZW50IH0gZnJvbSAnLi9UaWxlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi4vVGlsZVN0YXRlLmpzJztcbmltcG9ydCB7IGNyZWF0ZUZyb21UZW1wbGF0ZXMsIGV4cGFuZFVybCB9IGZyb20gJy4uL3RpbGV1cmxmdW5jdGlvbi5qcyc7XG5pbXBvcnQgeyBnZXRLZXlaWFkgfSBmcm9tICcuLi90aWxlY29vcmQuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9Tb3VyY2UuanNcIikuQXR0cmlidXRpb25MaWtlfSBbYXR0cmlidXRpb25zXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbYXR0cmlidXRpb25zQ29sbGFwc2libGU9dHJ1ZV0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbY2FjaGVTaXplXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbb3BhcXVlPWZhbHNlXSBXaGV0aGVyIHRoZSBsYXllciBpcyBvcGFxdWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFtzdGF0ZV1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gW3RpbGVHcmlkXVxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn0gdGlsZUxvYWRGdW5jdGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IFt0aWxlUGl4ZWxSYXRpb11cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gW3RpbGVVcmxGdW5jdGlvbl1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdXJsXVxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbdXJsc11cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYPXRydWVdXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RyYW5zaXRpb25dXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2tleV1cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekRpcmVjdGlvbj0wXVxuICovXG5cbi8qKlxuICogQGNsYXNzZGVzY1xuICogQmFzZSBjbGFzcyBmb3Igc291cmNlcyBwcm92aWRpbmcgdGlsZXMgZGl2aWRlZCBpbnRvIGEgdGlsZSBncmlkIG92ZXIgaHR0cC5cbiAqXG4gKiBAZmlyZXMgaW1wb3J0KFwiLi9UaWxlLmpzXCIpLlRpbGVTb3VyY2VFdmVudFxuICovXG5cbnZhciBVcmxUaWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFVybFRpbGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgSW1hZ2UgdGlsZSBvcHRpb25zLlxuICAgKi9cblxuXG4gIGZ1bmN0aW9uIFVybFRpbGUob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGF0dHJpYnV0aW9uczogb3B0aW9ucy5hdHRyaWJ1dGlvbnMsXG4gICAgICBjYWNoZVNpemU6IG9wdGlvbnMuY2FjaGVTaXplLFxuICAgICAgb3BhcXVlOiBvcHRpb25zLm9wYXF1ZSxcbiAgICAgIHByb2plY3Rpb246IG9wdGlvbnMucHJvamVjdGlvbixcbiAgICAgIHN0YXRlOiBvcHRpb25zLnN0YXRlLFxuICAgICAgdGlsZUdyaWQ6IG9wdGlvbnMudGlsZUdyaWQsXG4gICAgICB0aWxlUGl4ZWxSYXRpbzogb3B0aW9ucy50aWxlUGl4ZWxSYXRpbyxcbiAgICAgIHdyYXBYOiBvcHRpb25zLndyYXBYLFxuICAgICAgdHJhbnNpdGlvbjogb3B0aW9ucy50cmFuc2l0aW9uLFxuICAgICAga2V5OiBvcHRpb25zLmtleSxcbiAgICAgIGF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlOiBvcHRpb25zLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlLFxuICAgICAgekRpcmVjdGlvbjogb3B0aW9ucy56RGlyZWN0aW9uXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5nZW5lcmF0ZVRpbGVVcmxGdW5jdGlvbl8gPSBfdGhpcy50aWxlVXJsRnVuY3Rpb24gPT09IFVybFRpbGUucHJvdG90eXBlLnRpbGVVcmxGdW5jdGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZUxvYWRGdW5jdGlvbiA9IG9wdGlvbnMudGlsZUxvYWRGdW5jdGlvbjtcblxuICAgIGlmIChvcHRpb25zLnRpbGVVcmxGdW5jdGlvbikge1xuICAgICAgX3RoaXMudGlsZVVybEZ1bmN0aW9uID0gb3B0aW9ucy50aWxlVXJsRnVuY3Rpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7IUFycmF5PHN0cmluZz58bnVsbH1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMudXJscyA9IG51bGw7XG5cbiAgICBpZiAob3B0aW9ucy51cmxzKSB7XG4gICAgICBfdGhpcy5zZXRVcmxzKG9wdGlvbnMudXJscyk7XG4gICAgfSBlbHNlIGlmIChvcHRpb25zLnVybCkge1xuICAgICAgX3RoaXMuc2V0VXJsKG9wdGlvbnMudXJsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGJvb2xlYW4+fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy50aWxlTG9hZGluZ0tleXNfID0ge307XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRpbGUgbG9hZCBmdW5jdGlvbiBvZiB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn0gVGlsZUxvYWRGdW5jdGlvblxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuZ2V0VGlsZUxvYWRGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlTG9hZEZ1bmN0aW9uO1xuICB9O1xuICAvKipcbiAgICogUmV0dXJuIHRoZSB0aWxlIFVSTCBmdW5jdGlvbiBvZiB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9ufSBUaWxlVXJsRnVuY3Rpb25cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLmdldFRpbGVVcmxGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLnRpbGVVcmxGdW5jdGlvbiA9PT0gdGhpcy50aWxlVXJsRnVuY3Rpb24gPyB0aGlzLnRpbGVVcmxGdW5jdGlvbi5iaW5kKHRoaXMpIDogdGhpcy50aWxlVXJsRnVuY3Rpb247XG4gIH07XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIFVSTHMgdXNlZCBmb3IgdGhpcyBzb3VyY2UuXG4gICAqIFdoZW4gYSB0aWxlVXJsRnVuY3Rpb24gaXMgdXNlZCBpbnN0ZWFkIG9mIHVybCBvciB1cmxzLFxuICAgKiBudWxsIHdpbGwgYmUgcmV0dXJuZWQuXG4gICAqIEByZXR1cm4geyFBcnJheTxzdHJpbmc+fG51bGx9IFVSTHMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBVcmxUaWxlLnByb3RvdHlwZS5nZXRVcmxzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLnVybHM7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGUgdGlsZSBjaGFuZ2UgZXZlbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V2ZW50cy9FdmVudC5qc1wiKS5kZWZhdWx0fSBldmVudCBFdmVudC5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLmhhbmRsZVRpbGVDaGFuZ2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgdGlsZSA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgZXZlbnQudGFyZ2V0O1xuICAgIHZhciB1aWQgPSBnZXRVaWQodGlsZSk7XG4gICAgdmFyIHRpbGVTdGF0ZSA9IHRpbGUuZ2V0U3RhdGUoKTtcbiAgICB2YXIgdHlwZTtcblxuICAgIGlmICh0aWxlU3RhdGUgPT0gVGlsZVN0YXRlLkxPQURJTkcpIHtcbiAgICAgIHRoaXMudGlsZUxvYWRpbmdLZXlzX1t1aWRdID0gdHJ1ZTtcbiAgICAgIHR5cGUgPSBUaWxlRXZlbnRUeXBlLlRJTEVMT0FEU1RBUlQ7XG4gICAgfSBlbHNlIGlmICh1aWQgaW4gdGhpcy50aWxlTG9hZGluZ0tleXNfKSB7XG4gICAgICBkZWxldGUgdGhpcy50aWxlTG9hZGluZ0tleXNfW3VpZF07XG4gICAgICB0eXBlID0gdGlsZVN0YXRlID09IFRpbGVTdGF0ZS5FUlJPUiA/IFRpbGVFdmVudFR5cGUuVElMRUxPQURFUlJPUiA6IHRpbGVTdGF0ZSA9PSBUaWxlU3RhdGUuTE9BREVEID8gVGlsZUV2ZW50VHlwZS5USUxFTE9BREVORCA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodHlwZSAhPSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgVGlsZVNvdXJjZUV2ZW50KHR5cGUsIHRpbGUpKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIHRpbGUgbG9hZCBmdW5jdGlvbiBvZiB0aGUgc291cmNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSB0aWxlTG9hZEZ1bmN0aW9uIFRpbGUgbG9hZCBmdW5jdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLnNldFRpbGVMb2FkRnVuY3Rpb24gPSBmdW5jdGlvbiAodGlsZUxvYWRGdW5jdGlvbikge1xuICAgIHRoaXMudGlsZUNhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy50aWxlTG9hZEZ1bmN0aW9uID0gdGlsZUxvYWRGdW5jdGlvbjtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgdGlsZSBVUkwgZnVuY3Rpb24gb2YgdGhlIHNvdXJjZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9UaWxlLmpzXCIpLlVybEZ1bmN0aW9ufSB0aWxlVXJsRnVuY3Rpb24gVGlsZSBVUkwgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0ga2V5IE9wdGlvbmFsIG5ldyB0aWxlIGtleSBmb3IgdGhlIHNvdXJjZS5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLnNldFRpbGVVcmxGdW5jdGlvbiA9IGZ1bmN0aW9uICh0aWxlVXJsRnVuY3Rpb24sIGtleSkge1xuICAgIHRoaXMudGlsZVVybEZ1bmN0aW9uID0gdGlsZVVybEZ1bmN0aW9uO1xuICAgIHRoaXMudGlsZUNhY2hlLnBydW5lRXhjZXB0TmV3ZXN0WigpO1xuXG4gICAgaWYgKHR5cGVvZiBrZXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLnNldEtleShrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIFVSTCB0byB1c2UgZm9yIHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFVSTC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLnNldFVybCA9IGZ1bmN0aW9uICh1cmwpIHtcbiAgICB2YXIgdXJscyA9IGV4cGFuZFVybCh1cmwpO1xuICAgIHRoaXMudXJscyA9IHVybHM7XG4gICAgdGhpcy5zZXRVcmxzKHVybHMpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBVUkxzIHRvIHVzZSBmb3IgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gdXJscyBVUkxzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUuc2V0VXJscyA9IGZ1bmN0aW9uICh1cmxzKSB7XG4gICAgdGhpcy51cmxzID0gdXJscztcbiAgICB2YXIga2V5ID0gdXJscy5qb2luKCdcXG4nKTtcblxuICAgIGlmICh0aGlzLmdlbmVyYXRlVGlsZVVybEZ1bmN0aW9uXykge1xuICAgICAgdGhpcy5zZXRUaWxlVXJsRnVuY3Rpb24oY3JlYXRlRnJvbVRlbXBsYXRlcyh1cmxzLCB0aGlzLnRpbGVHcmlkKSwga2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRLZXkoa2V5KTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3RpbGVjb29yZC5qc1wiKS5UaWxlQ29vcmR9IHRpbGVDb29yZCBUaWxlIGNvb3JkaW5hdGUuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IFRpbGUgVVJMLlxuICAgKi9cblxuXG4gIFVybFRpbGUucHJvdG90eXBlLnRpbGVVcmxGdW5jdGlvbiA9IGZ1bmN0aW9uICh0aWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9O1xuICAvKipcbiAgICogTWFya3MgYSB0aWxlIGNvb3JkIGFzIGJlaW5nIHVzZWQsIHdpdGhvdXQgdHJpZ2dlcmluZyBhIGxvYWQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFRpbGUgY29vcmRpbmF0ZSB6LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqL1xuXG5cbiAgVXJsVGlsZS5wcm90b3R5cGUudXNlVGlsZSA9IGZ1bmN0aW9uICh6LCB4LCB5KSB7XG4gICAgdmFyIHRpbGVDb29yZEtleSA9IGdldEtleVpYWSh6LCB4LCB5KTtcblxuICAgIGlmICh0aGlzLnRpbGVDYWNoZS5jb250YWluc0tleSh0aWxlQ29vcmRLZXkpKSB7XG4gICAgICB0aGlzLnRpbGVDYWNoZS5nZXQodGlsZUNvb3JkS2V5KTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIFVybFRpbGU7XG59KFRpbGVTb3VyY2UpO1xuXG5leHBvcnQgZGVmYXVsdCBVcmxUaWxlOyIsInZhciBfX2V4dGVuZHMgPSB0aGlzICYmIHRoaXMuX19leHRlbmRzIHx8IGZ1bmN0aW9uICgpIHtcbiAgdmFyIF9leHRlbmRTdGF0aWNzID0gZnVuY3Rpb24gZXh0ZW5kU3RhdGljcyhkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHwge1xuICAgICAgX19wcm90b19fOiBbXVxuICAgIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZC5fX3Byb3RvX18gPSBiO1xuICAgIH0gfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGZvciAodmFyIHAgaW4gYikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuICB9O1xuXG4gIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzKGQsIGIpO1xuXG4gICAgZnVuY3Rpb24gX18oKSB7XG4gICAgICB0aGlzLmNvbnN0cnVjdG9yID0gZDtcbiAgICB9XG5cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG4gIH07XG59KCk7XG4vKipcbiAqIEBtb2R1bGUgb2wvc291cmNlL1RpbGVJbWFnZVxuICovXG5cblxuaW1wb3J0IEV2ZW50VHlwZSBmcm9tICcuLi9ldmVudHMvRXZlbnRUeXBlLmpzJztcbmltcG9ydCBJbWFnZVRpbGUgZnJvbSAnLi4vSW1hZ2VUaWxlLmpzJztcbmltcG9ydCBSZXByb2pUaWxlIGZyb20gJy4uL3JlcHJvai9UaWxlLmpzJztcbmltcG9ydCBUaWxlQ2FjaGUgZnJvbSAnLi4vVGlsZUNhY2hlLmpzJztcbmltcG9ydCBUaWxlU3RhdGUgZnJvbSAnLi4vVGlsZVN0YXRlLmpzJztcbmltcG9ydCBVcmxUaWxlIGZyb20gJy4vVXJsVGlsZS5qcyc7XG5pbXBvcnQgeyBFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTiB9IGZyb20gJy4uL3JlcHJvai9jb21tb24uanMnO1xuaW1wb3J0IHsgSU1BR0VfU01PT1RISU5HX0RJU0FCTEVEIH0gZnJvbSAnLi9jb21tb24uanMnO1xuaW1wb3J0IHsgZXF1aXZhbGVudCwgZ2V0IGFzIGdldFByb2plY3Rpb24gfSBmcm9tICcuLi9wcm9qLmpzJztcbmltcG9ydCB7IGdldEtleSwgZ2V0S2V5WlhZIH0gZnJvbSAnLi4vdGlsZWNvb3JkLmpzJztcbmltcG9ydCB7IGdldEZvclByb2plY3Rpb24gYXMgZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uIH0gZnJvbSAnLi4vdGlsZWdyaWQuanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9Tb3VyY2UuanNcIikuQXR0cmlidXRpb25MaWtlfSBbYXR0cmlidXRpb25zXSBBdHRyaWJ1dGlvbnMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZT10cnVlXSBBdHRyaWJ1dGlvbnMgYXJlIGNvbGxhcHNpYmxlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtjYWNoZVNpemVdIEluaXRpYWwgdGlsZSBjYWNoZSBzaXplLiBXaWxsIGF1dG8tZ3JvdyB0byBob2xkIGF0IGxlYXN0IHRoZSBudW1iZXIgb2YgdGlsZXMgaW4gdGhlIHZpZXdwb3J0LlxuICogQHByb3BlcnR5IHtudWxsfHN0cmluZ30gW2Nyb3NzT3JpZ2luXSBUaGUgYGNyb3NzT3JpZ2luYCBhdHRyaWJ1dGUgZm9yIGxvYWRlZCBpbWFnZXMuICBOb3RlIHRoYXRcbiAqIHlvdSBtdXN0IHByb3ZpZGUgYSBgY3Jvc3NPcmlnaW5gIHZhbHVlIGlmIHlvdSB3YW50IHRvIGFjY2VzcyBwaXhlbCBkYXRhIHdpdGggdGhlIENhbnZhcyByZW5kZXJlci5cbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0NPUlNfZW5hYmxlZF9pbWFnZSBmb3IgbW9yZSBkZXRhaWwuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtpbWFnZVNtb290aGluZz10cnVlXSBFbmFibGUgaW1hZ2Ugc21vb3RoaW5nLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbb3BhcXVlPWZhbHNlXSBXaGV0aGVyIHRoZSBsYXllciBpcyBvcGFxdWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IFtwcm9qZWN0aW9uXSBQcm9qZWN0aW9uLiBEZWZhdWx0IGlzIHRoZSB2aWV3IHByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3JlcHJvamVjdGlvbkVycm9yVGhyZXNob2xkPTAuNV0gTWF4aW11bSBhbGxvd2VkIHJlcHJvamVjdGlvbiBlcnJvciAoaW4gcGl4ZWxzKS5cbiAqIEhpZ2hlciB2YWx1ZXMgY2FuIGluY3JlYXNlIHJlcHJvamVjdGlvbiBwZXJmb3JtYW5jZSwgYnV0IGRlY3JlYXNlIHByZWNpc2lvbi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9TdGF0ZS5qc1wiKS5kZWZhdWx0fSBbc3RhdGVdIFNvdXJjZSBzdGF0ZS5cbiAqIEBwcm9wZXJ0eSB7dHlwZW9mIGltcG9ydChcIi4uL0ltYWdlVGlsZS5qc1wiKS5kZWZhdWx0fSBbdGlsZUNsYXNzXSBDbGFzcyB1c2VkIHRvIGluc3RhbnRpYXRlIGltYWdlIHRpbGVzLlxuICogRGVmYXVsdCBpcyB7QGxpbmsgbW9kdWxlOm9sL0ltYWdlVGlsZX5JbWFnZVRpbGV9LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBbdGlsZUdyaWRdIFRpbGUgZ3JpZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259IFt0aWxlTG9hZEZ1bmN0aW9uXSBPcHRpb25hbCBmdW5jdGlvbiB0byBsb2FkIGEgdGlsZSBnaXZlbiBhIFVSTC4gVGhlIGRlZmF1bHQgaXNcbiAqIGBgYGpzXG4gKiBmdW5jdGlvbihpbWFnZVRpbGUsIHNyYykge1xuICogICBpbWFnZVRpbGUuZ2V0SW1hZ2UoKS5zcmMgPSBzcmM7XG4gKiB9O1xuICogYGBgXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbGVQaXhlbFJhdGlvPTFdIFRoZSBwaXhlbCByYXRpbyB1c2VkIGJ5IHRoZSB0aWxlIHNlcnZpY2UuIEZvciBleGFtcGxlLCBpZiB0aGUgdGlsZVxuICogc2VydmljZSBhZHZlcnRpemVzIDI1NnB4IGJ5IDI1NnB4IHRpbGVzIGJ1dCBhY3R1YWxseSBzZW5kcyA1MTJweFxuICogYnkgNTEycHggaW1hZ2VzIChmb3IgcmV0aW5hL2hpZHBpIGRldmljZXMpIHRoZW4gYHRpbGVQaXhlbFJhdGlvYFxuICogc2hvdWxkIGJlIHNldCB0byBgMmAuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1RpbGUuanNcIikuVXJsRnVuY3Rpb259IFt0aWxlVXJsRnVuY3Rpb25dIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGdldCB0aWxlIFVSTCBnaXZlbiBhIHRpbGUgY29vcmRpbmF0ZSBhbmQgdGhlIHByb2plY3Rpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3VybF0gVVJMIHRlbXBsYXRlLiBNdXN0IGluY2x1ZGUgYHt4fWAsIGB7eX1gIG9yIGB7LXl9YCwgYW5kIGB7en1gIHBsYWNlaG9sZGVycy5cbiAqIEEgYHs/LT99YCB0ZW1wbGF0ZSBwYXR0ZXJuLCBmb3IgZXhhbXBsZSBgc3ViZG9tYWlue2EtZn0uZG9tYWluLmNvbWAsIG1heSBiZVxuICogdXNlZCBpbnN0ZWFkIG9mIGRlZmluaW5nIGVhY2ggb25lIHNlcGFyYXRlbHkgaW4gdGhlIGB1cmxzYCBvcHRpb24uXG4gKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IFt1cmxzXSBBbiBhcnJheSBvZiBVUkwgdGVtcGxhdGVzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbd3JhcFhdIFdoZXRoZXIgdG8gd3JhcCB0aGUgd29ybGQgaG9yaXpvbnRhbGx5LiBUaGUgZGVmYXVsdCwgaXMgdG9cbiAqIHJlcXVlc3Qgb3V0LW9mLWJvdW5kcyB0aWxlcyBmcm9tIHRoZSBzZXJ2ZXIuIFdoZW4gc2V0IHRvIGBmYWxzZWAsIG9ubHkgb25lXG4gKiB3b3JsZCB3aWxsIGJlIHJlbmRlcmVkLiBXaGVuIHNldCB0byBgdHJ1ZWAsIHRpbGVzIHdpbGwgYmUgcmVxdWVzdGVkIGZvciBvbmVcbiAqIHdvcmxkIG9ubHksIGJ1dCB0aGV5IHdpbGwgYmUgd3JhcHBlZCBob3Jpem9udGFsbHkgdG8gcmVuZGVyIG11bHRpcGxlIHdvcmxkcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl0gRHVyYXRpb24gb2YgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbiBmb3IgcmVuZGVyaW5nLlxuICogVG8gZGlzYWJsZSB0aGUgb3BhY2l0eSB0cmFuc2l0aW9uLCBwYXNzIGB0cmFuc2l0aW9uOiAwYC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBba2V5XSBPcHRpb25hbCB0aWxlIGtleSBmb3IgcHJvcGVyIGNhY2hlIGZldGNoaW5nXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3pEaXJlY3Rpb249MF0gSW5kaWNhdGUgd2hpY2ggcmVzb2x1dGlvbiBzaG91bGQgYmUgdXNlZFxuICogYnkgYSByZW5kZXJlciBpZiB0aGUgdmlldyByZXNvbHV0aW9uIGRvZXMgbm90IG1hdGNoIGFueSByZXNvbHV0aW9uIG9mIHRoZSB0aWxlIHNvdXJjZS5cbiAqIElmIDAsIHRoZSBuZWFyZXN0IHJlc29sdXRpb24gd2lsbCBiZSB1c2VkLiBJZiAxLCB0aGUgbmVhcmVzdCBsb3dlciByZXNvbHV0aW9uXG4gKiB3aWxsIGJlIHVzZWQuIElmIC0xLCB0aGUgbmVhcmVzdCBoaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuXG4gKi9cblxuLyoqXG4gKiBAY2xhc3NkZXNjXG4gKiBCYXNlIGNsYXNzIGZvciBzb3VyY2VzIHByb3ZpZGluZyBpbWFnZXMgZGl2aWRlZCBpbnRvIGEgdGlsZSBncmlkLlxuICpcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL1RpbGUuanNcIikuVGlsZVNvdXJjZUV2ZW50XG4gKiBAYXBpXG4gKi9cblxudmFyIFRpbGVJbWFnZSA9XG4vKiogQGNsYXNzICovXG5mdW5jdGlvbiAoX3N1cGVyKSB7XG4gIF9fZXh0ZW5kcyhUaWxlSW1hZ2UsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0geyFPcHRpb25zfSBvcHRpb25zIEltYWdlIHRpbGUgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUaWxlSW1hZ2Uob3B0aW9ucykge1xuICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGF0dHJpYnV0aW9uczogb3B0aW9ucy5hdHRyaWJ1dGlvbnMsXG4gICAgICBjYWNoZVNpemU6IG9wdGlvbnMuY2FjaGVTaXplLFxuICAgICAgb3BhcXVlOiBvcHRpb25zLm9wYXF1ZSxcbiAgICAgIHByb2plY3Rpb246IG9wdGlvbnMucHJvamVjdGlvbixcbiAgICAgIHN0YXRlOiBvcHRpb25zLnN0YXRlLFxuICAgICAgdGlsZUdyaWQ6IG9wdGlvbnMudGlsZUdyaWQsXG4gICAgICB0aWxlTG9hZEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gPyBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gOiBkZWZhdWx0VGlsZUxvYWRGdW5jdGlvbixcbiAgICAgIHRpbGVQaXhlbFJhdGlvOiBvcHRpb25zLnRpbGVQaXhlbFJhdGlvLFxuICAgICAgdGlsZVVybEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVVcmxGdW5jdGlvbixcbiAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWCxcbiAgICAgIHRyYW5zaXRpb246IG9wdGlvbnMudHJhbnNpdGlvbixcbiAgICAgIGtleTogb3B0aW9ucy5rZXksXG4gICAgICBhdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZTogb3B0aW9ucy5hdHRyaWJ1dGlvbnNDb2xsYXBzaWJsZSxcbiAgICAgIHpEaXJlY3Rpb246IG9wdGlvbnMuekRpcmVjdGlvblxuICAgIH0pIHx8IHRoaXM7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHs/c3RyaW5nfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5jcm9zc09yaWdpbiA9IG9wdGlvbnMuY3Jvc3NPcmlnaW4gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY3Jvc3NPcmlnaW4gOiBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7dHlwZW9mIEltYWdlVGlsZX1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVDbGFzcyA9IG9wdGlvbnMudGlsZUNsYXNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLnRpbGVDbGFzcyA6IEltYWdlVGlsZTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBUaWxlQ2FjaGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbiA9IHt9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMudGlsZUdyaWRGb3JQcm9qZWN0aW9uID0ge307XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlcHJvamVjdGlvbkVycm9yVGhyZXNob2xkXyA9IG9wdGlvbnMucmVwcm9qZWN0aW9uRXJyb3JUaHJlc2hvbGQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7b2JqZWN0fHVuZGVmaW5lZH1cbiAgICAgKi9cblxuICAgIF90aGlzLmNvbnRleHRPcHRpb25zXyA9IG9wdGlvbnMuaW1hZ2VTbW9vdGhpbmcgPT09IGZhbHNlID8gSU1BR0VfU01PT1RISU5HX0RJU0FCTEVEIDogdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5yZW5kZXJSZXByb2plY3Rpb25FZGdlc18gPSBmYWxzZTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IENhbiBleHBpcmUgY2FjaGUuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5jYW5FeHBpcmVDYWNoZSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIUVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OKSB7XG4gICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5jYW5FeHBpcmVDYWNoZS5jYWxsKHRoaXMpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRpbGVDYWNoZS5jYW5FeHBpcmVDYWNoZSgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbikge1xuICAgICAgICBpZiAodGhpcy50aWxlQ2FjaGVGb3JQcm9qZWN0aW9uW2tleV0uY2FuRXhwaXJlQ2FjaGUoKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0geyFPYmplY3Q8c3RyaW5nLCBib29sZWFuPn0gdXNlZFRpbGVzIFVzZWQgdGlsZXMuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5leHBpcmVDYWNoZSA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uLCB1c2VkVGlsZXMpIHtcbiAgICBpZiAoIUVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OKSB7XG4gICAgICBfc3VwZXIucHJvdG90eXBlLmV4cGlyZUNhY2hlLmNhbGwodGhpcywgcHJvamVjdGlvbiwgdXNlZFRpbGVzKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB1c2VkVGlsZUNhY2hlID0gdGhpcy5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHRoaXMudGlsZUNhY2hlLmV4cGlyZUNhY2hlKHRoaXMudGlsZUNhY2hlID09IHVzZWRUaWxlQ2FjaGUgPyB1c2VkVGlsZXMgOiB7fSk7XG5cbiAgICBmb3IgKHZhciBpZCBpbiB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb24pIHtcbiAgICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb25baWRdO1xuICAgICAgdGlsZUNhY2hlLmV4cGlyZUNhY2hlKHRpbGVDYWNoZSA9PSB1c2VkVGlsZUNhY2hlID8gdXNlZFRpbGVzIDoge30pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge09iamVjdHx1bmRlZmluZWR9IENvbnRleHQgb3B0aW9ucy5cbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldENvbnRleHRPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRleHRPcHRpb25zXztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7bnVtYmVyfSBHdXR0ZXIuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRHdXR0ZXJGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICBpZiAoRU5BQkxFX1JBU1RFUl9SRVBST0pFQ1RJT04gJiYgdGhpcy5nZXRQcm9qZWN0aW9uKCkgJiYgcHJvamVjdGlvbiAmJiAhZXF1aXZhbGVudCh0aGlzLmdldFByb2plY3Rpb24oKSwgcHJvamVjdGlvbikpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRHdXR0ZXIoKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEd1dHRlci5cbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldEd1dHRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gMDtcbiAgfTtcbiAgLyoqXG4gICAqIFJldHVybiB0aGUga2V5IHRvIGJlIHVzZWQgZm9yIGFsbCB0aWxlcyBpbiB0aGUgc291cmNlLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBrZXkgZm9yIGFsbCB0aWxlcy5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZ2V0S2V5ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmdldEtleS5jYWxsKHRoaXMpICsgKHRoaXMuY29udGV4dE9wdGlvbnNfID8gJ1xcbicgKyBKU09OLnN0cmluZ2lmeSh0aGlzLmNvbnRleHRPcHRpb25zXykgOiAnJyk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IE9wYXF1ZS5cbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldE9wYXF1ZSA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgaWYgKEVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OICYmIHRoaXMuZ2V0UHJvamVjdGlvbigpICYmIHByb2plY3Rpb24gJiYgIWVxdWl2YWxlbnQodGhpcy5nZXRQcm9qZWN0aW9uKCksIHByb2plY3Rpb24pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLmdldE9wYXF1ZS5jYWxsKHRoaXMsIHByb2plY3Rpb24pO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLmdldFRpbGVHcmlkRm9yUHJvamVjdGlvbiA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uKSB7XG4gICAgaWYgKCFFTkFCTEVfUkFTVEVSX1JFUFJPSkVDVElPTikge1xuICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uLmNhbGwodGhpcywgcHJvamVjdGlvbik7XG4gICAgfVxuXG4gICAgdmFyIHRoaXNQcm9qID0gdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG5cbiAgICBpZiAodGhpcy50aWxlR3JpZCAmJiAoIXRoaXNQcm9qIHx8IGVxdWl2YWxlbnQodGhpc1Byb2osIHByb2plY3Rpb24pKSkge1xuICAgICAgcmV0dXJuIHRoaXMudGlsZUdyaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBwcm9qS2V5ID0gZ2V0VWlkKHByb2plY3Rpb24pO1xuXG4gICAgICBpZiAoIShwcm9qS2V5IGluIHRoaXMudGlsZUdyaWRGb3JQcm9qZWN0aW9uKSkge1xuICAgICAgICB0aGlzLnRpbGVHcmlkRm9yUHJvamVjdGlvbltwcm9qS2V5XSA9IGdldFRpbGVHcmlkRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMudGlsZUdyaWRGb3JQcm9qZWN0aW9uW3Byb2pLZXldO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vVGlsZUNhY2hlLmpzXCIpLmRlZmF1bHR9IFRpbGUgY2FjaGUuXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24pIHtcbiAgICBpZiAoIUVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OKSB7XG4gICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5nZXRUaWxlQ2FjaGVGb3JQcm9qZWN0aW9uLmNhbGwodGhpcywgcHJvamVjdGlvbik7XG4gICAgfVxuXG4gICAgdmFyIHRoaXNQcm9qID0gdGhpcy5nZXRQcm9qZWN0aW9uKCk7XG5cbiAgICBpZiAoIXRoaXNQcm9qIHx8IGVxdWl2YWxlbnQodGhpc1Byb2osIHByb2plY3Rpb24pKSB7XG4gICAgICByZXR1cm4gdGhpcy50aWxlQ2FjaGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBwcm9qS2V5ID0gZ2V0VWlkKHByb2plY3Rpb24pO1xuXG4gICAgICBpZiAoIShwcm9qS2V5IGluIHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbikpIHtcbiAgICAgICAgdGhpcy50aWxlQ2FjaGVGb3JQcm9qZWN0aW9uW3Byb2pLZXldID0gbmV3IFRpbGVDYWNoZSh0aGlzLnRpbGVDYWNoZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbltwcm9qS2V5XTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgc2V0IG9uIHRoZSB0aWxlLlxuICAgKiBAcmV0dXJuIHshaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSBUaWxlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuY3JlYXRlVGlsZV8gPSBmdW5jdGlvbiAoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwga2V5KSB7XG4gICAgdmFyIHRpbGVDb29yZCA9IFt6LCB4LCB5XTtcbiAgICB2YXIgdXJsVGlsZUNvb3JkID0gdGhpcy5nZXRUaWxlQ29vcmRGb3JUaWxlVXJsRnVuY3Rpb24odGlsZUNvb3JkLCBwcm9qZWN0aW9uKTtcbiAgICB2YXIgdGlsZVVybCA9IHVybFRpbGVDb29yZCA/IHRoaXMudGlsZVVybEZ1bmN0aW9uKHVybFRpbGVDb29yZCwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikgOiB1bmRlZmluZWQ7XG4gICAgdmFyIHRpbGUgPSBuZXcgdGhpcy50aWxlQ2xhc3ModGlsZUNvb3JkLCB0aWxlVXJsICE9PSB1bmRlZmluZWQgPyBUaWxlU3RhdGUuSURMRSA6IFRpbGVTdGF0ZS5FTVBUWSwgdGlsZVVybCAhPT0gdW5kZWZpbmVkID8gdGlsZVVybCA6ICcnLCB0aGlzLmNyb3NzT3JpZ2luLCB0aGlzLnRpbGVMb2FkRnVuY3Rpb24sIHRoaXMudGlsZU9wdGlvbnMpO1xuICAgIHRpbGUua2V5ID0ga2V5O1xuICAgIHRpbGUuYWRkRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0hBTkdFLCB0aGlzLmhhbmRsZVRpbGVDaGFuZ2UuYmluZCh0aGlzKSk7XG4gICAgcmV0dXJuIHRpbGU7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHshaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSBUaWxlLlxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuZ2V0VGlsZSA9IGZ1bmN0aW9uICh6LCB4LCB5LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKSB7XG4gICAgdmFyIHNvdXJjZVByb2plY3Rpb24gPSB0aGlzLmdldFByb2plY3Rpb24oKTtcblxuICAgIGlmICghRU5BQkxFX1JBU1RFUl9SRVBST0pFQ1RJT04gfHwgIXNvdXJjZVByb2plY3Rpb24gfHwgIXByb2plY3Rpb24gfHwgZXF1aXZhbGVudChzb3VyY2VQcm9qZWN0aW9uLCBwcm9qZWN0aW9uKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VGlsZUludGVybmFsKHosIHgsIHksIHBpeGVsUmF0aW8sIHNvdXJjZVByb2plY3Rpb24gfHwgcHJvamVjdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBjYWNoZSA9IHRoaXMuZ2V0VGlsZUNhY2hlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uKTtcbiAgICAgIHZhciB0aWxlQ29vcmQgPSBbeiwgeCwgeV07XG4gICAgICB2YXIgdGlsZSA9IHZvaWQgMDtcbiAgICAgIHZhciB0aWxlQ29vcmRLZXkgPSBnZXRLZXkodGlsZUNvb3JkKTtcblxuICAgICAgaWYgKGNhY2hlLmNvbnRhaW5zS2V5KHRpbGVDb29yZEtleSkpIHtcbiAgICAgICAgdGlsZSA9IGNhY2hlLmdldCh0aWxlQ29vcmRLZXkpO1xuICAgICAgfVxuXG4gICAgICB2YXIga2V5ID0gdGhpcy5nZXRLZXkoKTtcblxuICAgICAgaWYgKHRpbGUgJiYgdGlsZS5rZXkgPT0ga2V5KSB7XG4gICAgICAgIHJldHVybiB0aWxlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gdGhpcy5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24oc291cmNlUHJvamVjdGlvbik7XG4gICAgICAgIHZhciB0YXJnZXRUaWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgICAgICB2YXIgd3JhcHBlZFRpbGVDb29yZCA9IHRoaXMuZ2V0VGlsZUNvb3JkRm9yVGlsZVVybEZ1bmN0aW9uKHRpbGVDb29yZCwgcHJvamVjdGlvbik7XG4gICAgICAgIHZhciBuZXdUaWxlID0gbmV3IFJlcHJvalRpbGUoc291cmNlUHJvamVjdGlvbiwgc291cmNlVGlsZUdyaWQsIHByb2plY3Rpb24sIHRhcmdldFRpbGVHcmlkLCB0aWxlQ29vcmQsIHdyYXBwZWRUaWxlQ29vcmQsIHRoaXMuZ2V0VGlsZVBpeGVsUmF0aW8ocGl4ZWxSYXRpbyksIHRoaXMuZ2V0R3V0dGVyKCksIGZ1bmN0aW9uICh6LCB4LCB5LCBwaXhlbFJhdGlvKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGlsZUludGVybmFsKHosIHgsIHksIHBpeGVsUmF0aW8sIHNvdXJjZVByb2plY3Rpb24pO1xuICAgICAgICB9LmJpbmQodGhpcyksIHRoaXMucmVwcm9qZWN0aW9uRXJyb3JUaHJlc2hvbGRfLCB0aGlzLnJlbmRlclJlcHJvamVjdGlvbkVkZ2VzXywgdGhpcy5jb250ZXh0T3B0aW9uc18pO1xuICAgICAgICBuZXdUaWxlLmtleSA9IGtleTtcblxuICAgICAgICBpZiAodGlsZSkge1xuICAgICAgICAgIG5ld1RpbGUuaW50ZXJpbVRpbGUgPSB0aWxlO1xuICAgICAgICAgIG5ld1RpbGUucmVmcmVzaEludGVyaW1DaGFpbigpO1xuICAgICAgICAgIGNhY2hlLnJlcGxhY2UodGlsZUNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYWNoZS5zZXQodGlsZUNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXdUaWxlO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFRpbGUgY29vcmRpbmF0ZSB6LlxuICAgKiBAcGFyYW0ge251bWJlcn0geCBUaWxlIGNvb3JkaW5hdGUgeC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHkgVGlsZSBjb29yZGluYXRlIHkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0geyFpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHshaW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5kZWZhdWx0fSBUaWxlLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgVGlsZUltYWdlLnByb3RvdHlwZS5nZXRUaWxlSW50ZXJuYWwgPSBmdW5jdGlvbiAoeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciB0aWxlID0gbnVsbDtcbiAgICB2YXIgdGlsZUNvb3JkS2V5ID0gZ2V0S2V5WlhZKHosIHgsIHkpO1xuICAgIHZhciBrZXkgPSB0aGlzLmdldEtleSgpO1xuXG4gICAgaWYgKCF0aGlzLnRpbGVDYWNoZS5jb250YWluc0tleSh0aWxlQ29vcmRLZXkpKSB7XG4gICAgICB0aWxlID0gdGhpcy5jcmVhdGVUaWxlXyh6LCB4LCB5LCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uLCBrZXkpO1xuICAgICAgdGhpcy50aWxlQ2FjaGUuc2V0KHRpbGVDb29yZEtleSwgdGlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRpbGUgPSB0aGlzLnRpbGVDYWNoZS5nZXQodGlsZUNvb3JkS2V5KTtcblxuICAgICAgaWYgKHRpbGUua2V5ICE9IGtleSkge1xuICAgICAgICAvLyBUaGUgc291cmNlJ3MgcGFyYW1zIGNoYW5nZWQuIElmIHRoZSB0aWxlIGhhcyBhbiBpbnRlcmltIHRpbGUgYW5kIGlmIHdlXG4gICAgICAgIC8vIGNhbiB1c2UgaXQgdGhlbiB3ZSB1c2UgaXQuIE90aGVyd2lzZSB3ZSBjcmVhdGUgYSBuZXcgdGlsZS4gIEluIGJvdGhcbiAgICAgICAgLy8gY2FzZXMgd2UgYXR0ZW1wdCB0byBhc3NpZ24gYW4gaW50ZXJpbSB0aWxlIHRvIHRoZSBuZXcgdGlsZS5cbiAgICAgICAgdmFyIGludGVyaW1UaWxlID0gdGlsZTtcbiAgICAgICAgdGlsZSA9IHRoaXMuY3JlYXRlVGlsZV8oeiwgeCwgeSwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbiwga2V5KTsgLy9tYWtlIHRoZSBuZXcgdGlsZSB0aGUgaGVhZCBvZiB0aGUgbGlzdCxcblxuICAgICAgICBpZiAoaW50ZXJpbVRpbGUuZ2V0U3RhdGUoKSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgICAgIC8vdGhlIG9sZCB0aWxlIGhhc24ndCBiZWd1biBsb2FkaW5nIHlldCwgYW5kIGlzIG5vdyBvdXRkYXRlZCwgc28gd2UgY2FuIHNpbXBseSBkaXNjYXJkIGl0XG4gICAgICAgICAgdGlsZS5pbnRlcmltVGlsZSA9IGludGVyaW1UaWxlLmludGVyaW1UaWxlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRpbGUuaW50ZXJpbVRpbGUgPSBpbnRlcmltVGlsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRpbGUucmVmcmVzaEludGVyaW1DaGFpbigpO1xuICAgICAgICB0aGlzLnRpbGVDYWNoZS5yZXBsYWNlKHRpbGVDb29yZEtleSwgdGlsZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRpbGU7XG4gIH07XG4gIC8qKlxuICAgKiBTZXRzIHdoZXRoZXIgdG8gcmVuZGVyIHJlcHJvamVjdGlvbiBlZGdlcyBvciBub3QgKHVzdWFsbHkgZm9yIGRlYnVnZ2luZykuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVuZGVyIFJlbmRlciB0aGUgZWRnZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBUaWxlSW1hZ2UucHJvdG90eXBlLnNldFJlbmRlclJlcHJvamVjdGlvbkVkZ2VzID0gZnVuY3Rpb24gKHJlbmRlcikge1xuICAgIGlmICghRU5BQkxFX1JBU1RFUl9SRVBST0pFQ1RJT04gfHwgdGhpcy5yZW5kZXJSZXByb2plY3Rpb25FZGdlc18gPT0gcmVuZGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXJSZXByb2plY3Rpb25FZGdlc18gPSByZW5kZXI7XG5cbiAgICBmb3IgKHZhciBpZCBpbiB0aGlzLnRpbGVDYWNoZUZvclByb2plY3Rpb24pIHtcbiAgICAgIHRoaXMudGlsZUNhY2hlRm9yUHJvamVjdGlvbltpZF0uY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldHMgdGhlIHRpbGUgZ3JpZCB0byB1c2Ugd2hlbiByZXByb2plY3RpbmcgdGhlIHRpbGVzIHRvIHRoZSBnaXZlblxuICAgKiBwcm9qZWN0aW9uIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgdGlsZSBncmlkIGZvciB0aGUgcHJvamVjdGlvbi5cbiAgICpcbiAgICogVGhpcyBjYW4gYmUgdXNlZnVsIHdoZW4gdGhlIGRlZmF1bHQgdGlsZSBncmlkIGNhbm5vdCBiZSBjcmVhdGVkXG4gICAqIChlLmcuIHByb2plY3Rpb24gaGFzIG5vIGV4dGVudCBkZWZpbmVkKSBvclxuICAgKiBmb3Igb3B0aW1pemF0aW9uIHJlYXNvbnMgKGN1c3RvbSB0aWxlIHNpemUsIHJlc29sdXRpb25zLCAuLi4pLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ouanNcIikuUHJvamVjdGlvbkxpa2V9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0aWxlZ3JpZCBUaWxlIGdyaWQgdG8gdXNlIGZvciB0aGUgcHJvamVjdGlvbi5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVJbWFnZS5wcm90b3R5cGUuc2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uID0gZnVuY3Rpb24gKHByb2plY3Rpb24sIHRpbGVncmlkKSB7XG4gICAgaWYgKEVOQUJMRV9SQVNURVJfUkVQUk9KRUNUSU9OKSB7XG4gICAgICB2YXIgcHJvaiA9IGdldFByb2plY3Rpb24ocHJvamVjdGlvbik7XG5cbiAgICAgIGlmIChwcm9qKSB7XG4gICAgICAgIHZhciBwcm9qS2V5ID0gZ2V0VWlkKHByb2opO1xuXG4gICAgICAgIGlmICghKHByb2pLZXkgaW4gdGhpcy50aWxlR3JpZEZvclByb2plY3Rpb24pKSB7XG4gICAgICAgICAgdGhpcy50aWxlR3JpZEZvclByb2plY3Rpb25bcHJvaktleV0gPSB0aWxlZ3JpZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gVGlsZUltYWdlO1xufShVcmxUaWxlKTtcbi8qKlxuICogQHBhcmFtIHtJbWFnZVRpbGV9IGltYWdlVGlsZSBJbWFnZSB0aWxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHNyYyBTb3VyY2UuXG4gKi9cblxuXG5mdW5jdGlvbiBkZWZhdWx0VGlsZUxvYWRGdW5jdGlvbihpbWFnZVRpbGUsIHNyYykge1xuICAvKiogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR8SFRNTFZpZGVvRWxlbWVudH0gKi9cbiAgaW1hZ2VUaWxlLmdldEltYWdlKCkuc3JjID0gc3JjO1xufVxuXG5leHBvcnQgZGVmYXVsdCBUaWxlSW1hZ2U7IiwiLyoqXG4gKiBAbW9kdWxlIG9sL25ldFxuICovXG5pbXBvcnQgeyBnZXRVaWQgfSBmcm9tICcuL3V0aWwuanMnO1xuLyoqXG4gKiBTaW1wbGUgSlNPTlAgaGVscGVyLiBTdXBwb3J0cyBlcnJvciBjYWxsYmFja3MgYW5kIGEgY3VzdG9tIGNhbGxiYWNrIHBhcmFtLlxuICogVGhlIGVycm9yIGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHdoZW4gbm8gSlNPTlAgaXMgZXhlY3V0ZWQgYWZ0ZXIgMTAgc2Vjb25kcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFJlcXVlc3QgdXJsLiBBICdjYWxsYmFjaycgcXVlcnkgcGFyYW1ldGVyIHdpbGwgYmVcbiAqICAgICBhcHBlbmRlZC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIENhbGxiYWNrIG9uIHN1Y2Nlc3MuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk9fSBvcHRfZXJyYmFjayBDYWxsYmFjayBvbiBlcnJvci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X2NhbGxiYWNrUGFyYW0gQ3VzdG9tIHF1ZXJ5IHBhcmFtZXRlciBmb3IgdGhlIEpTT05QXG4gKiAgICAgY2FsbGJhY2suIERlZmF1bHQgaXMgJ2NhbGxiYWNrJy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24ganNvbnAodXJsLCBjYWxsYmFjaywgb3B0X2VycmJhY2ssIG9wdF9jYWxsYmFja1BhcmFtKSB7XG4gIHZhciBzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgdmFyIGtleSA9ICdvbGNfJyArIGdldFVpZChjYWxsYmFjayk7XG5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBkZWxldGUgd2luZG93W2tleV07XG4gICAgc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB1cmwgKyAodXJsLmluZGV4T2YoJz8nKSA9PSAtMSA/ICc/JyA6ICcmJykgKyAob3B0X2NhbGxiYWNrUGFyYW0gfHwgJ2NhbGxiYWNrJykgKyAnPScgKyBrZXk7XG4gIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGNsZWFudXAoKTtcblxuICAgIGlmIChvcHRfZXJyYmFjaykge1xuICAgICAgb3B0X2VycmJhY2soKTtcbiAgICB9XG4gIH0sIDEwMDAwKTtcblxuICB3aW5kb3dba2V5XSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICBjbGVhbnVwKCk7XG4gICAgY2FsbGJhY2soZGF0YSk7XG4gIH07XG5cbiAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzY3JpcHQpO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvVGlsZUpTT05cbiAqL1xuLy8gRklYTUUgY2hlY2sgb3JkZXIgb2YgYXN5bmMgY2FsbGJhY2tzXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBTZWUgaHR0cHM6Ly9tYXBib3guY29tL2RldmVsb3BlcnMvYXBpLy5cbiAqL1xuXG5cbmltcG9ydCBTb3VyY2VTdGF0ZSBmcm9tICcuL1N0YXRlLmpzJztcbmltcG9ydCBUaWxlSW1hZ2UgZnJvbSAnLi9UaWxlSW1hZ2UuanMnO1xuaW1wb3J0IHsgYXBwbHlUcmFuc2Zvcm0sIGludGVyc2VjdHMgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSAnLi4vYXNzZXJ0cy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVGcm9tVGVtcGxhdGVzIH0gZnJvbSAnLi4vdGlsZXVybGZ1bmN0aW9uLmpzJztcbmltcG9ydCB7IGNyZWF0ZVhZWiwgZXh0ZW50RnJvbVByb2plY3Rpb24gfSBmcm9tICcuLi90aWxlZ3JpZC5qcyc7XG5pbXBvcnQgeyBnZXQgYXMgZ2V0UHJvamVjdGlvbiwgZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zIH0gZnJvbSAnLi4vcHJvai5qcyc7XG5pbXBvcnQgeyBqc29ucCBhcyByZXF1ZXN0SlNPTlAgfSBmcm9tICcuLi9uZXQuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBDb25maWdcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbmFtZV0gVGhlIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2Rlc2NyaXB0aW9uXSBUaGUgZGVzY3JpcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3ZlcnNpb25dIFRoZSB2ZXJzaW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFthdHRyaWJ1dGlvbl0gVGhlIGF0dHJpYnV0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFt0ZW1wbGF0ZV0gVGhlIHRlbXBsYXRlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtsZWdlbmRdIFRoZSBsZWdlbmQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3NjaGVtZV0gVGhlIHNjaGVtZS5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gdGlsZXMgVGhlIHRpbGUgVVJMIHRlbXBsYXRlcy5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gW2dyaWRzXSBPcHRpb25hbCBncmlkcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluem9vbV0gTWluaW11bSB6b29tIGxldmVsLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXh6b29tXSBNYXhpbXVtIHpvb20gbGV2ZWwuXG4gKiBAcHJvcGVydHkge0FycmF5PG51bWJlcj59IFtib3VuZHNdIE9wdGlvbmFsIGJvdW5kcy5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8bnVtYmVyPn0gW2NlbnRlcl0gT3B0aW9uYWwgY2VudGVyLlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gT3B0aW9uc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1NvdXJjZS5qc1wiKS5BdHRyaWJ1dGlvbkxpa2V9IFthdHRyaWJ1dGlvbnNdIEF0dHJpYnV0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbY2FjaGVTaXplXSBJbml0aWFsIHRpbGUgY2FjaGUgc2l6ZS4gV2lsbCBhdXRvLWdyb3cgdG8gaG9sZCBhdCBsZWFzdCB0aGUgbnVtYmVyIG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydC5cbiAqIEBwcm9wZXJ0eSB7bnVsbHxzdHJpbmd9IFtjcm9zc09yaWdpbl0gVGhlIGBjcm9zc09yaWdpbmAgYXR0cmlidXRlIGZvciBsb2FkZWQgaW1hZ2VzLiAgTm90ZSB0aGF0XG4gKiB5b3UgbXVzdCBwcm92aWRlIGEgYGNyb3NzT3JpZ2luYCB2YWx1ZSBpZiB5b3Ugd2FudCB0byBhY2Nlc3MgcGl4ZWwgZGF0YSB3aXRoIHRoZSBDYW52YXMgcmVuZGVyZXIuXG4gKiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9DT1JTX2VuYWJsZWRfaW1hZ2UgZm9yIG1vcmUgZGV0YWlsLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbaW1hZ2VTbW9vdGhpbmc9dHJ1ZV0gRW5hYmxlIGltYWdlIHNtb290aGluZy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2pzb25wPWZhbHNlXSBVc2UgSlNPTlAgd2l0aCBjYWxsYmFjayB0byBsb2FkIHRoZSBUaWxlSlNPTi5cbiAqIFVzZWZ1bCB3aGVuIHRoZSBzZXJ2ZXIgZG9lcyBub3Qgc3VwcG9ydCBDT1JTLi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmVwcm9qZWN0aW9uRXJyb3JUaHJlc2hvbGQ9MC41XSBNYXhpbXVtIGFsbG93ZWQgcmVwcm9qZWN0aW9uIGVycm9yIChpbiBwaXhlbHMpLlxuICogSGlnaGVyIHZhbHVlcyBjYW4gaW5jcmVhc2UgcmVwcm9qZWN0aW9uIHBlcmZvcm1hbmNlLCBidXQgZGVjcmVhc2UgcHJlY2lzaW9uLlxuICogQHByb3BlcnR5IHtDb25maWd9IFt0aWxlSlNPTl0gVGlsZUpTT04gY29uZmlndXJhdGlvbiBmb3IgdGhpcyBzb3VyY2UuXG4gKiBJZiBub3QgcHJvdmlkZWQsIGB1cmxgIG11c3QgYmUgY29uZmlndXJlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5Mb2FkRnVuY3Rpb259IFt0aWxlTG9hZEZ1bmN0aW9uXSBPcHRpb25hbCBmdW5jdGlvbiB0byBsb2FkIGEgdGlsZSBnaXZlbiBhIFVSTC4gVGhlIGRlZmF1bHQgaXNcbiAqIGBgYGpzXG4gKiBmdW5jdGlvbihpbWFnZVRpbGUsIHNyYykge1xuICogICBpbWFnZVRpbGUuZ2V0SW1hZ2UoKS5zcmMgPSBzcmM7XG4gKiB9O1xuICogYGBgXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFt0aWxlU2l6ZT1bMjU2LCAyNTZdXSBUaGUgdGlsZSBzaXplIHVzZWQgYnkgdGhlIHRpbGUgc2VydmljZS5cbiAqIE5vdGU6IGB0aWxlU2l6ZWAgYW5kIG90aGVyIG5vbi1zdGFuZGFyZCBUaWxlSlNPTiBwcm9wZXJ0aWVzIGFyZSBjdXJyZW50bHkgaWdub3JlZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdXJsXSBVUkwgdG8gdGhlIFRpbGVKU09OIGZpbGUuIElmIG5vdCBwcm92aWRlZCwgYHRpbGVKU09OYCBtdXN0IGJlIGNvbmZpZ3VyZWQuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFt3cmFwWD10cnVlXSBXaGV0aGVyIHRvIHdyYXAgdGhlIHdvcmxkIGhvcml6b250YWxseS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl0gRHVyYXRpb24gb2YgdGhlIG9wYWNpdHkgdHJhbnNpdGlvbiBmb3IgcmVuZGVyaW5nLlxuICogVG8gZGlzYWJsZSB0aGUgb3BhY2l0eSB0cmFuc2l0aW9uLCBwYXNzIGB0cmFuc2l0aW9uOiAwYC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIExheWVyIHNvdXJjZSBmb3IgdGlsZSBkYXRhIGluIFRpbGVKU09OIGZvcm1hdC5cbiAqIEBhcGlcbiAqL1xuXG52YXIgVGlsZUpTT04gPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVGlsZUpTT04sIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgVGlsZUpTT04gb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBUaWxlSlNPTihvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGNhY2hlU2l6ZTogb3B0aW9ucy5jYWNoZVNpemUsXG4gICAgICBjcm9zc09yaWdpbjogb3B0aW9ucy5jcm9zc09yaWdpbixcbiAgICAgIGltYWdlU21vb3RoaW5nOiBvcHRpb25zLmltYWdlU21vb3RoaW5nLFxuICAgICAgcHJvamVjdGlvbjogZ2V0UHJvamVjdGlvbignRVBTRzozODU3JyksXG4gICAgICByZXByb2plY3Rpb25FcnJvclRocmVzaG9sZDogb3B0aW9ucy5yZXByb2plY3Rpb25FcnJvclRocmVzaG9sZCxcbiAgICAgIHN0YXRlOiBTb3VyY2VTdGF0ZS5MT0FESU5HLFxuICAgICAgdGlsZUxvYWRGdW5jdGlvbjogb3B0aW9ucy50aWxlTG9hZEZ1bmN0aW9uLFxuICAgICAgd3JhcFg6IG9wdGlvbnMud3JhcFggIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMud3JhcFggOiB0cnVlLFxuICAgICAgdHJhbnNpdGlvbjogb3B0aW9ucy50cmFuc2l0aW9uXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Q29uZmlnfVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cblxuICAgIF90aGlzLnRpbGVKU09OXyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVTaXplXyA9IG9wdGlvbnMudGlsZVNpemU7XG5cbiAgICBpZiAob3B0aW9ucy51cmwpIHtcbiAgICAgIGlmIChvcHRpb25zLmpzb25wKSB7XG4gICAgICAgIHJlcXVlc3RKU09OUChvcHRpb25zLnVybCwgX3RoaXMuaGFuZGxlVGlsZUpTT05SZXNwb25zZS5iaW5kKF90aGlzKSwgX3RoaXMuaGFuZGxlVGlsZUpTT05FcnJvci5iaW5kKF90aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgY2xpZW50ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIGNsaWVudC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgX3RoaXMub25YSFJMb2FkXy5iaW5kKF90aGlzKSk7XG4gICAgICAgIGNsaWVudC5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIF90aGlzLm9uWEhSRXJyb3JfLmJpbmQoX3RoaXMpKTtcbiAgICAgICAgY2xpZW50Lm9wZW4oJ0dFVCcsIG9wdGlvbnMudXJsKTtcbiAgICAgICAgY2xpZW50LnNlbmQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMudGlsZUpTT04pIHtcbiAgICAgIF90aGlzLmhhbmRsZVRpbGVKU09OUmVzcG9uc2Uob3B0aW9ucy50aWxlSlNPTik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFzc2VydChmYWxzZSwgNTEpOyAvLyBFaXRoZXIgYHVybGAgb3IgYHRpbGVKU09OYCBvcHRpb25zIG11c3QgYmUgcHJvdmlkZWRcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBsb2FkIGV2ZW50LlxuICAgKi9cblxuXG4gIFRpbGVKU09OLnByb3RvdHlwZS5vblhIUkxvYWRfID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGNsaWVudCA9XG4gICAgLyoqIEB0eXBlIHtYTUxIdHRwUmVxdWVzdH0gKi9cbiAgICBldmVudC50YXJnZXQ7IC8vIHN0YXR1cyB3aWxsIGJlIDAgZm9yIGZpbGU6Ly8gdXJsc1xuXG4gICAgaWYgKCFjbGllbnQuc3RhdHVzIHx8IGNsaWVudC5zdGF0dXMgPj0gMjAwICYmIGNsaWVudC5zdGF0dXMgPCAzMDApIHtcbiAgICAgIHZhciByZXNwb25zZSA9IHZvaWQgMDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzcG9uc2UgPVxuICAgICAgICAvKiogQHR5cGUge1RpbGVKU09OfSAqL1xuICAgICAgICBKU09OLnBhcnNlKGNsaWVudC5yZXNwb25zZVRleHQpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlVGlsZUpTT05FcnJvcigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGFuZGxlVGlsZUpTT05SZXNwb25zZShyZXNwb25zZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGFuZGxlVGlsZUpTT05FcnJvcigpO1xuICAgIH1cbiAgfTtcbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IFRoZSBlcnJvciBldmVudC5cbiAgICovXG5cblxuICBUaWxlSlNPTi5wcm90b3R5cGUub25YSFJFcnJvcl8gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB0aGlzLmhhbmRsZVRpbGVKU09ORXJyb3IoKTtcbiAgfTtcbiAgLyoqXG4gICAqIEByZXR1cm4ge0NvbmZpZ30gVGhlIHRpbGVqc29uIG9iamVjdC5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFRpbGVKU09OLnByb3RvdHlwZS5nZXRUaWxlSlNPTiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy50aWxlSlNPTl87XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB7Q29uZmlnfSB0aWxlSlNPTiBUaWxlIEpTT04uXG4gICAqL1xuXG5cbiAgVGlsZUpTT04ucHJvdG90eXBlLmhhbmRsZVRpbGVKU09OUmVzcG9uc2UgPSBmdW5jdGlvbiAodGlsZUpTT04pIHtcbiAgICB2YXIgZXBzZzQzMjZQcm9qZWN0aW9uID0gZ2V0UHJvamVjdGlvbignRVBTRzo0MzI2Jyk7XG4gICAgdmFyIHNvdXJjZVByb2plY3Rpb24gPSB0aGlzLmdldFByb2plY3Rpb24oKTtcbiAgICB2YXIgZXh0ZW50O1xuXG4gICAgaWYgKHRpbGVKU09OWydib3VuZHMnXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgdHJhbnNmb3JtID0gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKGVwc2c0MzI2UHJvamVjdGlvbiwgc291cmNlUHJvamVjdGlvbik7XG4gICAgICBleHRlbnQgPSBhcHBseVRyYW5zZm9ybSh0aWxlSlNPTlsnYm91bmRzJ10sIHRyYW5zZm9ybSk7XG4gICAgfVxuXG4gICAgdmFyIG1pblpvb20gPSB0aWxlSlNPTlsnbWluem9vbSddIHx8IDA7XG4gICAgdmFyIG1heFpvb20gPSB0aWxlSlNPTlsnbWF4em9vbSddIHx8IDIyO1xuICAgIHZhciB0aWxlR3JpZCA9IGNyZWF0ZVhZWih7XG4gICAgICBleHRlbnQ6IGV4dGVudEZyb21Qcm9qZWN0aW9uKHNvdXJjZVByb2plY3Rpb24pLFxuICAgICAgbWF4Wm9vbTogbWF4Wm9vbSxcbiAgICAgIG1pblpvb206IG1pblpvb20sXG4gICAgICB0aWxlU2l6ZTogdGhpcy50aWxlU2l6ZV9cbiAgICB9KTtcbiAgICB0aGlzLnRpbGVHcmlkID0gdGlsZUdyaWQ7XG4gICAgdGhpcy50aWxlVXJsRnVuY3Rpb24gPSBjcmVhdGVGcm9tVGVtcGxhdGVzKHRpbGVKU09OWyd0aWxlcyddLCB0aWxlR3JpZCk7XG5cbiAgICBpZiAodGlsZUpTT05bJ2F0dHJpYnV0aW9uJ10gIT09IHVuZGVmaW5lZCAmJiAhdGhpcy5nZXRBdHRyaWJ1dGlvbnMoKSkge1xuICAgICAgdmFyIGF0dHJpYnV0aW9uRXh0ZW50XzEgPSBleHRlbnQgIT09IHVuZGVmaW5lZCA/IGV4dGVudCA6IGVwc2c0MzI2UHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRpb25zKGZ1bmN0aW9uIChmcmFtZVN0YXRlKSB7XG4gICAgICAgIGlmIChpbnRlcnNlY3RzKGF0dHJpYnV0aW9uRXh0ZW50XzEsIGZyYW1lU3RhdGUuZXh0ZW50KSkge1xuICAgICAgICAgIHJldHVybiBbdGlsZUpTT05bJ2F0dHJpYnV0aW9uJ11dO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnRpbGVKU09OXyA9IHRpbGVKU09OO1xuICAgIHRoaXMuc2V0U3RhdGUoU291cmNlU3RhdGUuUkVBRFkpO1xuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIFRpbGVKU09OLnByb3RvdHlwZS5oYW5kbGVUaWxlSlNPTkVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoU291cmNlU3RhdGUuRVJST1IpO1xuICB9O1xuXG4gIHJldHVybiBUaWxlSlNPTjtcbn0oVGlsZUltYWdlKTtcblxuZXhwb3J0IGRlZmF1bHQgVGlsZUpTT047IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9WZWN0b3JUaWxlXG4gKi9cblxuXG5pbXBvcnQgVGlsZSBmcm9tICcuL1RpbGUuanMnO1xuaW1wb3J0IFRpbGVTdGF0ZSBmcm9tICcuL1RpbGVTdGF0ZS5qcyc7XG5cbnZhciBWZWN0b3JUaWxlID1cbi8qKiBAY2xhc3MgKi9cbmZ1bmN0aW9uIChfc3VwZXIpIHtcbiAgX19leHRlbmRzKFZlY3RvclRpbGUsIF9zdXBlcik7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdGlsZUNvb3JkIFRpbGUgY29vcmRpbmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL1RpbGVTdGF0ZS5qc1wiKS5kZWZhdWx0fSBzdGF0ZSBTdGF0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNyYyBEYXRhIHNvdXJjZSB1cmwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9mb3JtYXQvRmVhdHVyZS5qc1wiKS5kZWZhdWx0fSBmb3JtYXQgRmVhdHVyZSBmb3JtYXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn0gdGlsZUxvYWRGdW5jdGlvbiBUaWxlIGxvYWQgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLk9wdGlvbnM9fSBvcHRfb3B0aW9ucyBUaWxlIG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gVmVjdG9yVGlsZSh0aWxlQ29vcmQsIHN0YXRlLCBzcmMsIGZvcm1hdCwgdGlsZUxvYWRGdW5jdGlvbiwgb3B0X29wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlQ29vcmQsIHN0YXRlLCBvcHRfb3B0aW9ucykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBFeHRlbnQgb2YgdGhpcyB0aWxlOyBzZXQgYnkgdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5leHRlbnQgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH1cbiAgICAgKi9cblxuICAgIF90aGlzLmZvcm1hdF8gPSBmb3JtYXQ7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZmVhdHVyZXNfID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZUxvYWRlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxvYWRlcl87XG4gICAgLyoqXG4gICAgICogRmVhdHVyZSBwcm9qZWN0aW9uIG9mIHRoaXMgdGlsZTsgc2V0IGJ5IHRoZSBzb3VyY2UuXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5wcm9qZWN0aW9uID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBSZXNvbHV0aW9uIG9mIHRoaXMgdGlsZTsgc2V0IGJ5IHRoZSBzb3VyY2UuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cblxuICAgIF90aGlzLnJlc29sdXRpb247XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9UaWxlLmpzXCIpLkxvYWRGdW5jdGlvbn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVMb2FkRnVuY3Rpb25fID0gdGlsZUxvYWRGdW5jdGlvbjtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG5cbiAgICBfdGhpcy51cmxfID0gc3JjO1xuICAgIF90aGlzLmtleSA9IHNyYztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZSBmb3JtYXQgYXNzaWduZWQgZm9yIHJlYWRpbmcgdGhpcyB0aWxlJ3MgZmVhdHVyZXMuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gRmVhdHVyZSBmb3JtYXQuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRGb3JtYXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgZmVhdHVyZXMgZm9yIHRoaXMgdGlsZS4gR2VvbWV0cmllcyB3aWxsIGJlIGluIHRoZSB2aWV3IHByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge0FycmF5PGltcG9ydChcIi4vRmVhdHVyZS5qc1wiKS5GZWF0dXJlTGlrZT59IEZlYXR1cmVzLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZS5wcm90b3R5cGUuZ2V0RmVhdHVyZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmVhdHVyZXNfO1xuICB9O1xuICAvKipcbiAgICogTG9hZCBub3QgeWV0IGxvYWRlZCBVUkkuXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZSA9PSBUaWxlU3RhdGUuSURMRSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZShUaWxlU3RhdGUuTE9BRElORyk7XG4gICAgICB0aGlzLnRpbGVMb2FkRnVuY3Rpb25fKHRoaXMsIHRoaXMudXJsXyk7XG5cbiAgICAgIGlmICh0aGlzLmxvYWRlcl8pIHtcbiAgICAgICAgdGhpcy5sb2FkZXJfKHRoaXMuZXh0ZW50LCB0aGlzLnJlc29sdXRpb24sIHRoaXMucHJvamVjdGlvbik7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogSGFuZGxlciBmb3Igc3VjY2Vzc2Z1bCB0aWxlIGxvYWQuXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSBmZWF0dXJlcyBUaGUgbG9hZGVkIGZlYXR1cmVzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IGRhdGFQcm9qZWN0aW9uIERhdGEgcHJvamVjdGlvbi5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoZmVhdHVyZXMsIGRhdGFQcm9qZWN0aW9uKSB7XG4gICAgdGhpcy5zZXRGZWF0dXJlcyhmZWF0dXJlcyk7XG4gIH07XG4gIC8qKlxuICAgKiBIYW5kbGVyIGZvciB0aWxlIGxvYWQgZXJyb3JzLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZShUaWxlU3RhdGUuRVJST1IpO1xuICB9O1xuICAvKipcbiAgICogRnVuY3Rpb24gZm9yIHVzZSBpbiBhbiB7QGxpbmsgbW9kdWxlOm9sL3NvdXJjZS9WZWN0b3JUaWxlflZlY3RvclRpbGV9J3MgYHRpbGVMb2FkRnVuY3Rpb25gLlxuICAgKiBTZXRzIHRoZSBmZWF0dXJlcyBmb3IgdGhlIHRpbGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9GZWF0dXJlLmpzXCIpLmRlZmF1bHQ+fSBmZWF0dXJlcyBGZWF0dXJlcy5cbiAgICogQGFwaVxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLnNldEZlYXR1cmVzID0gZnVuY3Rpb24gKGZlYXR1cmVzKSB7XG4gICAgdGhpcy5mZWF0dXJlc18gPSBmZWF0dXJlcztcbiAgICB0aGlzLnNldFN0YXRlKFRpbGVTdGF0ZS5MT0FERUQpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBmZWF0dXJlIGxvYWRlciBmb3IgcmVhZGluZyB0aGlzIHRpbGUncyBmZWF0dXJlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2ZlYXR1cmVsb2FkZXIuanNcIikuRmVhdHVyZUxvYWRlcn0gbG9hZGVyIEZlYXR1cmUgbG9hZGVyLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgVmVjdG9yVGlsZS5wcm90b3R5cGUuc2V0TG9hZGVyID0gZnVuY3Rpb24gKGxvYWRlcikge1xuICAgIHRoaXMubG9hZGVyXyA9IGxvYWRlcjtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yVGlsZTtcbn0oVGlsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvclRpbGU7IiwidmFyIF9fZXh0ZW5kcyA9IHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMgfHwgZnVuY3Rpb24gKCkge1xuICB2YXIgX2V4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiBleHRlbmRTdGF0aWNzKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCB7XG4gICAgICBfX3Byb3RvX186IFtdXG4gICAgfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBkLl9fcHJvdG9fXyA9IGI7XG4gICAgfSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgICAgZm9yICh2YXIgcCBpbiBiKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gX2V4dGVuZFN0YXRpY3MoZCwgYik7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgX2V4dGVuZFN0YXRpY3MoZCwgYik7XG5cbiAgICBmdW5jdGlvbiBfXygpIHtcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgPSBkO1xuICAgIH1cblxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbiAgfTtcbn0oKTtcbi8qKlxuICogQG1vZHVsZSBvbC9WZWN0b3JSZW5kZXJUaWxlXG4gKi9cblxuXG5pbXBvcnQgVGlsZSBmcm9tICcuL1RpbGUuanMnO1xuaW1wb3J0IHsgY3JlYXRlQ2FudmFzQ29udGV4dDJEIH0gZnJvbSAnLi9kb20uanMnO1xuaW1wb3J0IHsgZ2V0VWlkIH0gZnJvbSAnLi91dGlsLmpzJztcbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUmVwbGF5U3RhdGVcbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlydHlcbiAqIEBwcm9wZXJ0eSB7bnVsbHxpbXBvcnQoXCIuL3JlbmRlci5qc1wiKS5PcmRlckZ1bmN0aW9ufSByZW5kZXJlZFJlbmRlck9yZGVyXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRUaWxlUmV2aXNpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByZW5kZXJlZFJlc29sdXRpb25cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSByZW5kZXJlZFJldmlzaW9uXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRaXG4gKiBAcHJvcGVydHkge251bWJlcn0gcmVuZGVyZWRUaWxlUmVzb2x1dGlvblxuICogQHByb3BlcnR5IHtudW1iZXJ9IHJlbmRlcmVkVGlsZVpcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtBcnJheTxIVE1MQ2FudmFzRWxlbWVudD59XG4gKi9cblxudmFyIGNhbnZhc1Bvb2wgPSBbXTtcblxudmFyIFZlY3RvclJlbmRlclRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yUmVuZGVyVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi90aWxlY29vcmQuanNcIikuVGlsZUNvb3JkfSB0aWxlQ29vcmQgVGlsZSBjb29yZGluYXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vVGlsZVN0YXRlLmpzXCIpLmRlZmF1bHR9IHN0YXRlIFN0YXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH0gdXJsVGlsZUNvb3JkIFdyYXBwZWQgdGlsZSBjb29yZGluYXRlIGZvciBzb3VyY2UgdXJscy5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihWZWN0b3JSZW5kZXJUaWxlKTpBcnJheTxpbXBvcnQoXCIuL1ZlY3RvclRpbGVcIikuZGVmYXVsdD59IGdldFNvdXJjZVRpbGVzIEZ1bmN0aW9uXG4gICAqIHRvIGdldCBzb3VyY2UgdGlsZXMgZm9yIHRoaXMgdGlsZS5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JSZW5kZXJUaWxlKHRpbGVDb29yZCwgc3RhdGUsIHVybFRpbGVDb29yZCwgZ2V0U291cmNlVGlsZXMpIHtcbiAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCB0aWxlQ29vcmQsIHN0YXRlLCB7XG4gICAgICB0cmFuc2l0aW9uOiAwXG4gICAgfSkgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgQ2FudmFzUmVuZGVyaW5nQ29udGV4dDJEPn1cbiAgICAgKi9cblxuXG4gICAgX3RoaXMuY29udGV4dF8gPSB7fTtcbiAgICAvKipcbiAgICAgKiBFeGVjdXRvciBncm91cHMgYnkgbGF5ZXIgdWlkLiBFbnRyaWVzIGFyZSByZWFkL3dyaXR0ZW4gYnkgdGhlIHJlbmRlcmVyLlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBBcnJheTxpbXBvcnQoXCIuL3JlbmRlci9jYW52YXMvRXhlY3V0b3JHcm91cC5qc1wiKS5kZWZhdWx0Pj59XG4gICAgICovXG5cbiAgICBfdGhpcy5leGVjdXRvckdyb3VwcyA9IHt9O1xuICAgIC8qKlxuICAgICAqIEV4ZWN1dG9yIGdyb3VwcyBmb3IgZGVjbHV0dGVyaW5nLCBieSBsYXllciB1aWQuIEVudHJpZXMgYXJlIHJlYWQvd3JpdHRlbiBieSB0aGUgcmVuZGVyZXIuXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIEFycmF5PGltcG9ydChcIi4vcmVuZGVyL2NhbnZhcy9FeGVjdXRvckdyb3VwLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmRlY2x1dHRlckV4ZWN1dG9yR3JvdXBzID0ge307XG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGxvYWRpbmcgc291cmNlIHRpbGVzLiBSZWFkL3dyaXR0ZW4gYnkgdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMubG9hZGluZ1NvdXJjZVRpbGVzID0gMDtcbiAgICAvKipcbiAgICAgKiBUaWxlIGtleXMgb2YgZXJyb3Igc291cmNlIHRpbGVzLiBSZWFkL3dyaXR0ZW4gYnkgdGhlIHNvdXJjZS5cbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgYm9vbGVhbj59XG4gICAgICovXG5cbiAgICBfdGhpcy5lcnJvclNvdXJjZVRpbGVLZXlzID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxudW1iZXIsIEltYWdlRGF0YT59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaXREZXRlY3Rpb25JbWFnZURhdGEgPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHshT2JqZWN0PHN0cmluZywgUmVwbGF5U3RhdGU+fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVwbGF5U3RhdGVfID0ge307XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGltcG9ydChcIi4vVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnNvdXJjZVRpbGVzID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuXG4gICAgX3RoaXMud2FudGVkUmVzb2x1dGlvbjtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7IWZ1bmN0aW9uKCk6QXJyYXk8aW1wb3J0KFwiLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHQ+fVxuICAgICAqL1xuXG4gICAgX3RoaXMuZ2V0U291cmNlVGlsZXMgPSBnZXRTb3VyY2VUaWxlcy5iaW5kKHVuZGVmaW5lZCwgX3RoaXMpO1xuICAgIC8qKlxuICAgICAqIHogb2YgdGhlIHNvdXJjZSB0aWxlcyBvZiB0aGUgbGFzdCBnZXRTb3VyY2VUaWxlcyBjYWxsLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VaID0gLTE7XG4gICAgLyoqXG4gICAgICogVHJ1ZSB3aGVuIGFsbCB0aWxlcyBmb3IgdGhpcyB0aWxlJ3Mgbm9taW5hbCByZXNvbHV0aW9uIGFyZSBhdmFpbGFibGUuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5oaWZpID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4vdGlsZWNvb3JkLmpzXCIpLlRpbGVDb29yZH1cbiAgICAgKi9cblxuICAgIF90aGlzLndyYXBwZWRUaWxlQ29vcmQgPSB1cmxUaWxlQ29vcmQ7XG4gICAgcmV0dXJuIF90aGlzO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEByZXR1cm4ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gVGhlIHJlbmRlcmluZyBjb250ZXh0LlxuICAgKi9cblxuXG4gIFZlY3RvclJlbmRlclRpbGUucHJvdG90eXBlLmdldENvbnRleHQgPSBmdW5jdGlvbiAobGF5ZXIpIHtcbiAgICB2YXIga2V5ID0gZ2V0VWlkKGxheWVyKTtcblxuICAgIGlmICghKGtleSBpbiB0aGlzLmNvbnRleHRfKSkge1xuICAgICAgdGhpcy5jb250ZXh0X1trZXldID0gY3JlYXRlQ2FudmFzQ29udGV4dDJEKDEsIDEsIGNhbnZhc1Bvb2wpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnRleHRfW2tleV07XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbGF5ZXIvTGF5ZXIuanNcIikuZGVmYXVsdH0gbGF5ZXIgTGF5ZXIuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRpbGUgaGFzIGEgcmVuZGVyaW5nIGNvbnRleHQgZm9yIHRoZSBnaXZlbiBsYXllci5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5oYXNDb250ZXh0ID0gZnVuY3Rpb24gKGxheWVyKSB7XG4gICAgcmV0dXJuIGdldFVpZChsYXllcikgaW4gdGhpcy5jb250ZXh0XztcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgQ2FudmFzIGZvciB0aGlzIHRpbGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9sYXllci9MYXllci5qc1wiKS5kZWZhdWx0fSBsYXllciBMYXllci5cbiAgICogQHJldHVybiB7SFRNTENhbnZhc0VsZW1lbnR9IENhbnZhcy5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5nZXRJbWFnZSA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgIHJldHVybiB0aGlzLmhhc0NvbnRleHQobGF5ZXIpID8gdGhpcy5nZXRDb250ZXh0KGxheWVyKS5jYW52YXMgOiBudWxsO1xuICB9O1xuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2xheWVyL0xheWVyLmpzXCIpLmRlZmF1bHR9IGxheWVyIExheWVyLlxuICAgKiBAcmV0dXJuIHtSZXBsYXlTdGF0ZX0gVGhlIHJlcGxheSBzdGF0ZS5cbiAgICovXG5cblxuICBWZWN0b3JSZW5kZXJUaWxlLnByb3RvdHlwZS5nZXRSZXBsYXlTdGF0ZSA9IGZ1bmN0aW9uIChsYXllcikge1xuICAgIHZhciBrZXkgPSBnZXRVaWQobGF5ZXIpO1xuXG4gICAgaWYgKCEoa2V5IGluIHRoaXMucmVwbGF5U3RhdGVfKSkge1xuICAgICAgdGhpcy5yZXBsYXlTdGF0ZV9ba2V5XSA9IHtcbiAgICAgICAgZGlydHk6IGZhbHNlLFxuICAgICAgICByZW5kZXJlZFJlbmRlck9yZGVyOiBudWxsLFxuICAgICAgICByZW5kZXJlZFJlc29sdXRpb246IE5hTixcbiAgICAgICAgcmVuZGVyZWRSZXZpc2lvbjogLTEsXG4gICAgICAgIHJlbmRlcmVkVGlsZVJlc29sdXRpb246IE5hTixcbiAgICAgICAgcmVuZGVyZWRUaWxlUmV2aXNpb246IC0xLFxuICAgICAgICByZW5kZXJlZFo6IC0xLFxuICAgICAgICByZW5kZXJlZFRpbGVaOiAtMVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXBsYXlTdGF0ZV9ba2V5XTtcbiAgfTtcbiAgLyoqXG4gICAqIExvYWQgdGhlIHRpbGUuXG4gICAqL1xuXG5cbiAgVmVjdG9yUmVuZGVyVGlsZS5wcm90b3R5cGUubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmdldFNvdXJjZVRpbGVzKCk7XG4gIH07XG4gIC8qKlxuICAgKiBSZW1vdmUgZnJvbSB0aGUgY2FjaGUgZHVlIHRvIGV4cGlyeVxuICAgKi9cblxuXG4gIFZlY3RvclJlbmRlclRpbGUucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuY29udGV4dF8pIHtcbiAgICAgIGNhbnZhc1Bvb2wucHVzaCh0aGlzLmNvbnRleHRfW2tleV0uY2FudmFzKTtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbnRleHRfW2tleV07XG4gICAgfVxuXG4gICAgX3N1cGVyLnByb3RvdHlwZS5yZWxlYXNlLmNhbGwodGhpcyk7XG4gIH07XG5cbiAgcmV0dXJuIFZlY3RvclJlbmRlclRpbGU7XG59KFRpbGUpO1xuXG5leHBvcnQgZGVmYXVsdCBWZWN0b3JSZW5kZXJUaWxlOyIsIi8qKlxuICogQG1vZHVsZSBvbC9zb3VyY2UvVmVjdG9yVGlsZVxuICovXG52YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuXG5pbXBvcnQgRXZlbnRUeXBlIGZyb20gJy4uL2V2ZW50cy9FdmVudFR5cGUuanMnO1xuaW1wb3J0IFRpbGUgZnJvbSAnLi4vVmVjdG9yVGlsZS5qcyc7XG5pbXBvcnQgVGlsZUNhY2hlIGZyb20gJy4uL1RpbGVDYWNoZS5qcyc7XG5pbXBvcnQgVGlsZVN0YXRlIGZyb20gJy4uL1RpbGVTdGF0ZS5qcyc7XG5pbXBvcnQgVXJsVGlsZSBmcm9tICcuL1VybFRpbGUuanMnO1xuaW1wb3J0IFZlY3RvclJlbmRlclRpbGUgZnJvbSAnLi4vVmVjdG9yUmVuZGVyVGlsZS5qcyc7XG5pbXBvcnQgeyBidWZmZXIgYXMgYnVmZmVyRXh0ZW50LCBnZXRJbnRlcnNlY3Rpb24sIGludGVyc2VjdHMgfSBmcm9tICcuLi9leHRlbnQuanMnO1xuaW1wb3J0IHsgY3JlYXRlRm9yUHJvamVjdGlvbiwgY3JlYXRlWFlaLCBleHRlbnRGcm9tUHJvamVjdGlvbiB9IGZyb20gJy4uL3RpbGVncmlkLmpzJztcbmltcG9ydCB7IGVxdWFscyB9IGZyb20gJy4uL2FycmF5LmpzJztcbmltcG9ydCB7IGZyb21LZXksIGdldEtleVpYWSB9IGZyb20gJy4uL3RpbGVjb29yZC5qcyc7XG5pbXBvcnQgeyBsb2FkRmVhdHVyZXNYaHIgfSBmcm9tICcuLi9mZWF0dXJlbG9hZGVyLmpzJztcbmltcG9ydCB7IHRvU2l6ZSB9IGZyb20gJy4uL3NpemUuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vU291cmNlLmpzXCIpLkF0dHJpYnV0aW9uTGlrZX0gW2F0dHJpYnV0aW9uc10gQXR0cmlidXRpb25zLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYXR0cmlidXRpb25zQ29sbGFwc2libGU9dHJ1ZV0gQXR0cmlidXRpb25zIGFyZSBjb2xsYXBzaWJsZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbY2FjaGVTaXplXSBJbml0aWFsIHRpbGUgY2FjaGUgc2l6ZS4gV2lsbCBhdXRvLWdyb3cgdG8gaG9sZCBhdCBsZWFzdCB0d2ljZSB0aGUgbnVtYmVyIG9mIHRpbGVzIGluIHRoZSB2aWV3cG9ydC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gW2V4dGVudF1cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vZm9ybWF0L0ZlYXR1cmUuanNcIikuZGVmYXVsdH0gW2Zvcm1hdF0gRmVhdHVyZSBmb3JtYXQgZm9yIHRpbGVzLiBVc2VkIGFuZCByZXF1aXJlZCBieSB0aGUgZGVmYXVsdC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW292ZXJsYXBzPXRydWVdIFRoaXMgc291cmNlIG1heSBoYXZlIG92ZXJsYXBwaW5nIGdlb21ldHJpZXMuIFNldHRpbmcgdGhpc1xuICogdG8gYGZhbHNlYCAoZS5nLiBmb3Igc291cmNlcyB3aXRoIHBvbHlnb25zIHRoYXQgcmVwcmVzZW50IGFkbWluaXN0cmF0aXZlXG4gKiBib3VuZGFyaWVzIG9yIFRvcG9KU09OIHNvdXJjZXMpIGFsbG93cyB0aGUgcmVuZGVyZXIgdG8gb3B0aW1pc2UgZmlsbCBhbmRcbiAqIHN0cm9rZSBvcGVyYXRpb25zLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9wcm9qLmpzXCIpLlByb2plY3Rpb25MaWtlfSBbcHJvamVjdGlvbj0nRVBTRzozODU3J10gUHJvamVjdGlvbiBvZiB0aGUgdGlsZSBncmlkLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL1N0YXRlLmpzXCIpLmRlZmF1bHR9IFtzdGF0ZV0gU291cmNlIHN0YXRlLlxuICogQHByb3BlcnR5IHt0eXBlb2YgaW1wb3J0KFwiLi4vVmVjdG9yVGlsZS5qc1wiKS5kZWZhdWx0fSBbdGlsZUNsYXNzXSBDbGFzcyB1c2VkIHRvIGluc3RhbnRpYXRlIGltYWdlIHRpbGVzLlxuICogRGVmYXVsdCBpcyB7QGxpbmsgbW9kdWxlOm9sL1ZlY3RvclRpbGV9LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXhab29tPTIyXSBPcHRpb25hbCBtYXggem9vbSBsZXZlbC4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWluWm9vbV0gT3B0aW9uYWwgbWluIHpvb20gbGV2ZWwuIE5vdCB1c2VkIGlmIGB0aWxlR3JpZGAgaXMgcHJvdmlkZWQuXG4gKiBAcHJvcGVydHkge251bWJlcnxpbXBvcnQoXCIuLi9zaXplLmpzXCIpLlNpemV9IFt0aWxlU2l6ZT01MTJdIE9wdGlvbmFsIHRpbGUgc2l6ZS4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbWF4UmVzb2x1dGlvbl0gT3B0aW9uYWwgdGlsZSBncmlkIHJlc29sdXRpb24gYXQgbGV2ZWwgemVyby4gTm90IHVzZWQgaWYgYHRpbGVHcmlkYCBpcyBwcm92aWRlZC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vdGlsZWdyaWQvVGlsZUdyaWQuanNcIikuZGVmYXVsdH0gW3RpbGVHcmlkXSBUaWxlIGdyaWQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL1RpbGUuanNcIikuTG9hZEZ1bmN0aW9ufSBbdGlsZUxvYWRGdW5jdGlvbl1cbiAqIE9wdGlvbmFsIGZ1bmN0aW9uIHRvIGxvYWQgYSB0aWxlIGdpdmVuIGEgVVJMLiBDb3VsZCBsb29rIGxpa2UgdGhpcyBmb3IgcGJmIHRpbGVzOlxuICogYGBganNcbiAqIGZ1bmN0aW9uKHRpbGUsIHVybCkge1xuICogICB0aWxlLnNldExvYWRlcihmdW5jdGlvbihleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIHtcbiAqICAgICBmZXRjaCh1cmwpLnRoZW4oZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAqICAgICAgIHJlc3BvbnNlLmFycmF5QnVmZmVyKCkudGhlbihmdW5jdGlvbihkYXRhKSB7XG4gKiAgICAgICAgIGNvbnN0IGZvcm1hdCA9IHRpbGUuZ2V0Rm9ybWF0KCkgLy8gb2wvZm9ybWF0L01WVCBjb25maWd1cmVkIGFzIHNvdXJjZSBmb3JtYXRcbiAqICAgICAgICAgY29uc3QgZmVhdHVyZXMgPSBmb3JtYXQucmVhZEZlYXR1cmVzKGRhdGEsIHtcbiAqICAgICAgICAgICBleHRlbnQ6IGV4dGVudCxcbiAqICAgICAgICAgICBmZWF0dXJlUHJvamVjdGlvbjogcHJvamVjdGlvblxuICogICAgICAgICB9KTtcbiAqICAgICAgICAgdGlsZS5zZXRGZWF0dXJlcyhmZWF0dXJlcyk7XG4gKiAgICAgICB9KTtcbiAqICAgICB9KTtcbiAqICAgfSk7XG4gKiB9XG4gKiBgYGBcbiAqIElmIHlvdSBkbyBub3QgbmVlZCBleHRlbnQsIHJlc29sdXRpb24gYW5kIHByb2plY3Rpb24gdG8gZ2V0IHRoZSBmZWF0dXJlcyBmb3IgYSB0aWxlIChlLmcuXG4gKiBmb3IgR2VvSlNPTiB0aWxlcyksIHlvdXIgYHRpbGVMb2FkRnVuY3Rpb25gIGRvZXMgbm90IG5lZWQgYSBgc2V0TG9hZGVyKClgIGNhbGwuIE9ubHkgbWFrZSBzdXJlXG4gKiB0byBjYWxsIGBzZXRGZWF0dXJlcygpYCBvbiB0aGUgdGlsZTpcbiAqIGBgYGpzXG4gKiBjb25zdCBmb3JtYXQgPSBuZXcgR2VvSlNPTih7ZmVhdHVyZVByb2plY3Rpb246IG1hcC5nZXRWaWV3KCkuZ2V0UHJvamVjdGlvbigpfSk7XG4gKiBhc3luYyBmdW5jdGlvbiB0aWxlTG9hZEZ1bmN0aW9uKHRpbGUsIHVybCkge1xuICogICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gKiAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gKiAgIHRpbGUuc2V0RmVhdHVyZXMoZm9ybWF0LnJlYWRGZWF0dXJlcyhkYXRhKSk7XG4gKiB9XG4gKiBgYGBcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vVGlsZS5qc1wiKS5VcmxGdW5jdGlvbn0gW3RpbGVVcmxGdW5jdGlvbl0gT3B0aW9uYWwgZnVuY3Rpb24gdG8gZ2V0IHRpbGUgVVJMIGdpdmVuIGEgdGlsZSBjb29yZGluYXRlIGFuZCB0aGUgcHJvamVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdXJsXSBVUkwgdGVtcGxhdGUuIE11c3QgaW5jbHVkZSBge3h9YCwgYHt5fWAgb3IgYHsteX1gLCBhbmQgYHt6fWAgcGxhY2Vob2xkZXJzLlxuICogQSBgez8tP31gIHRlbXBsYXRlIHBhdHRlcm4sIGZvciBleGFtcGxlIGBzdWJkb21haW57YS1mfS5kb21haW4uY29tYCwgbWF5IGJlXG4gKiB1c2VkIGluc3RlYWQgb2YgZGVmaW5pbmcgZWFjaCBvbmUgc2VwYXJhdGVseSBpbiB0aGUgYHVybHNgIG9wdGlvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdHJhbnNpdGlvbl0gQSBkdXJhdGlvbiBmb3IgdGlsZSBvcGFjaXR5XG4gKiB0cmFuc2l0aW9ucyBpbiBtaWxsaXNlY29uZHMuIEEgZHVyYXRpb24gb2YgMCBkaXNhYmxlcyB0aGUgb3BhY2l0eSB0cmFuc2l0aW9uLlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbdXJsc10gQW4gYXJyYXkgb2YgVVJMIHRlbXBsYXRlcy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3dyYXBYPXRydWVdIFdoZXRoZXIgdG8gd3JhcCB0aGUgd29ybGQgaG9yaXpvbnRhbGx5LlxuICogV2hlbiBzZXQgdG8gYGZhbHNlYCwgb25seSBvbmUgd29ybGRcbiAqIHdpbGwgYmUgcmVuZGVyZWQuIFdoZW4gc2V0IHRvIGB0cnVlYCwgdGlsZXMgd2lsbCBiZSB3cmFwcGVkIGhvcml6b250YWxseSB0b1xuICogcmVuZGVyIG11bHRpcGxlIHdvcmxkcy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbekRpcmVjdGlvbj0xXSBJbmRpY2F0ZSB3aGljaCByZXNvbHV0aW9uIHNob3VsZCBiZSB1c2VkXG4gKiBieSBhIHJlbmRlcmVyIGlmIHRoZSB2aWV3IHJlc29sdXRpb24gZG9lcyBub3QgbWF0Y2ggYW55IHJlc29sdXRpb24gb2YgdGhlIHRpbGUgc291cmNlLlxuICogSWYgMCwgdGhlIG5lYXJlc3QgcmVzb2x1dGlvbiB3aWxsIGJlIHVzZWQuIElmIDEsIHRoZSBuZWFyZXN0IGxvd2VyIHJlc29sdXRpb25cbiAqIHdpbGwgYmUgdXNlZC4gSWYgLTEsIHRoZSBuZWFyZXN0IGhpZ2hlciByZXNvbHV0aW9uIHdpbGwgYmUgdXNlZC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIENsYXNzIGZvciBsYXllciBzb3VyY2VzIHByb3ZpZGluZyB2ZWN0b3IgZGF0YSBkaXZpZGVkIGludG8gYSB0aWxlIGdyaWQsIHRvIGJlXG4gKiB1c2VkIHdpdGgge0BsaW5rIG1vZHVsZTpvbC9sYXllci9WZWN0b3JUaWxlflZlY3RvclRpbGV9LiBBbHRob3VnaCB0aGlzIHNvdXJjZSByZWNlaXZlcyB0aWxlc1xuICogd2l0aCB2ZWN0b3IgZmVhdHVyZXMgZnJvbSB0aGUgc2VydmVyLCBpdCBpcyBub3QgbWVhbnQgZm9yIGZlYXR1cmUgZWRpdGluZy5cbiAqIEZlYXR1cmVzIGFyZSBvcHRpbWl6ZWQgZm9yIHJlbmRlcmluZywgdGhlaXIgZ2VvbWV0cmllcyBhcmUgY2xpcHBlZCBhdCBvciBuZWFyXG4gKiB0aWxlIGJvdW5kYXJpZXMgYW5kIHNpbXBsaWZpZWQgZm9yIGEgdmlldyByZXNvbHV0aW9uLiBTZWVcbiAqIHtAbGluayBtb2R1bGU6b2wvc291cmNlL1ZlY3Rvcn0gZm9yIHZlY3RvciBzb3VyY2VzIHRoYXQgYXJlIHN1aXRhYmxlIGZvciBmZWF0dXJlXG4gKiBlZGl0aW5nLlxuICpcbiAqIEBmaXJlcyBpbXBvcnQoXCIuL1RpbGUuanNcIikuVGlsZVNvdXJjZUV2ZW50XG4gKiBAYXBpXG4gKi9cblxudmFyIFZlY3RvclRpbGUgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoVmVjdG9yVGlsZSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7IU9wdGlvbnN9IG9wdGlvbnMgVmVjdG9yIHRpbGUgb3B0aW9ucy5cbiAgICovXG5cblxuICBmdW5jdGlvbiBWZWN0b3JUaWxlKG9wdGlvbnMpIHtcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgdmFyIHByb2plY3Rpb24gPSBvcHRpb25zLnByb2plY3Rpb24gfHwgJ0VQU0c6Mzg1Nyc7XG4gICAgdmFyIGV4dGVudCA9IG9wdGlvbnMuZXh0ZW50IHx8IGV4dGVudEZyb21Qcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlR3JpZCA9IG9wdGlvbnMudGlsZUdyaWQgfHwgY3JlYXRlWFlaKHtcbiAgICAgIGV4dGVudDogZXh0ZW50LFxuICAgICAgbWF4UmVzb2x1dGlvbjogb3B0aW9ucy5tYXhSZXNvbHV0aW9uLFxuICAgICAgbWF4Wm9vbTogb3B0aW9ucy5tYXhab29tICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1heFpvb20gOiAyMixcbiAgICAgIG1pblpvb206IG9wdGlvbnMubWluWm9vbSxcbiAgICAgIHRpbGVTaXplOiBvcHRpb25zLnRpbGVTaXplIHx8IDUxMlxuICAgIH0pO1xuICAgIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywge1xuICAgICAgYXR0cmlidXRpb25zOiBvcHRpb25zLmF0dHJpYnV0aW9ucyxcbiAgICAgIGF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlOiBvcHRpb25zLmF0dHJpYnV0aW9uc0NvbGxhcHNpYmxlLFxuICAgICAgY2FjaGVTaXplOiBvcHRpb25zLmNhY2hlU2l6ZSxcbiAgICAgIG9wYXF1ZTogZmFsc2UsXG4gICAgICBwcm9qZWN0aW9uOiBwcm9qZWN0aW9uLFxuICAgICAgc3RhdGU6IG9wdGlvbnMuc3RhdGUsXG4gICAgICB0aWxlR3JpZDogdGlsZUdyaWQsXG4gICAgICB0aWxlTG9hZEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gPyBvcHRpb25zLnRpbGVMb2FkRnVuY3Rpb24gOiBkZWZhdWx0TG9hZEZ1bmN0aW9uLFxuICAgICAgdGlsZVVybEZ1bmN0aW9uOiBvcHRpb25zLnRpbGVVcmxGdW5jdGlvbixcbiAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICB3cmFwWDogb3B0aW9ucy53cmFwWCA9PT0gdW5kZWZpbmVkID8gdHJ1ZSA6IG9wdGlvbnMud3JhcFgsXG4gICAgICB0cmFuc2l0aW9uOiBvcHRpb25zLnRyYW5zaXRpb24sXG4gICAgICB6RGlyZWN0aW9uOiBvcHRpb25zLnpEaXJlY3Rpb24gPT09IHVuZGVmaW5lZCA/IDEgOiBvcHRpb25zLnpEaXJlY3Rpb25cbiAgICB9KSB8fCB0aGlzO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL2Zvcm1hdC9GZWF0dXJlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy5mb3JtYXRfID0gb3B0aW9ucy5mb3JtYXQgPyBvcHRpb25zLmZvcm1hdCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsIGltcG9ydChcIi4vVmVjdG9yVGlsZVwiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLmxvYWRpbmdUaWxlc18gPSB7fTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtUaWxlQ2FjaGV9XG4gICAgICovXG5cbiAgICBfdGhpcy5zb3VyY2VUaWxlQ2FjaGUgPSBuZXcgVGlsZUNhY2hlKF90aGlzLnRpbGVDYWNoZS5oaWdoV2F0ZXJNYXJrKTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMub3ZlcmxhcHNfID0gb3B0aW9ucy5vdmVybGFwcyA9PSB1bmRlZmluZWQgPyB0cnVlIDogb3B0aW9ucy5vdmVybGFwcztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICBfdGhpcy50aWxlQ2xhc3MgPSBvcHRpb25zLnRpbGVDbGFzcyA/IG9wdGlvbnMudGlsZUNsYXNzIDogVGlsZTtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLCBpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0Pn1cbiAgICAgKi9cblxuICAgIF90aGlzLnRpbGVHcmlkc18gPSB7fTtcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCBmZWF0dXJlcyB3aG9zZSBib3VuZGluZyBib3ggaW50ZXJzZWN0cyB0aGUgcHJvdmlkZWQgZXh0ZW50LiBPbmx5IGZlYXR1cmVzIGZvciBjYWNoZWRcbiAgICogdGlsZXMgZm9yIHRoZSBsYXN0IHJlbmRlcmVkIHpvb20gbGV2ZWwgYXJlIGF2YWlsYWJsZSBpbiB0aGUgc291cmNlLiBTbyB0aGlzIG1ldGhvZCBpcyBvbmx5XG4gICAqIHN1aXRhYmxlIGZvciByZXF1ZXN0aW5nIHRpbGVzIGZvciBleHRlbnRzIHRoYXQgYXJlIGN1cnJlbnRseSByZW5kZXJlZC5cbiAgICpcbiAgICogRmVhdHVyZXMgYXJlIHJldHVybmVkIGluIHJhbmRvbSB0aWxlIG9yZGVyIGFuZCBhcyB0aGV5IGFyZSBpbmNsdWRlZCBpbiB0aGUgdGlsZXMuIFRoaXMgbWVhbnNcbiAgICogdGhleSBjYW4gYmUgY2xpcHBlZCwgZHVwbGljYXRlZCBhY3Jvc3MgdGlsZXMsIGFuZCBzaW1wbGlmaWVkIHRvIHRoZSByZW5kZXIgcmVzb2x1dGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICAgKiBAcmV0dXJuIHtBcnJheTxpbXBvcnQoXCIuLi9GZWF0dXJlLmpzXCIpLkZlYXR1cmVMaWtlPn0gRmVhdHVyZXMuXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRGZWF0dXJlc0luRXh0ZW50ID0gZnVuY3Rpb24gKGV4dGVudCkge1xuICAgIHZhciBmZWF0dXJlcyA9IFtdO1xuICAgIHZhciB0aWxlQ2FjaGUgPSB0aGlzLnRpbGVDYWNoZTtcblxuICAgIGlmICh0aWxlQ2FjaGUuZ2V0Q291bnQoKSA9PT0gMCkge1xuICAgICAgcmV0dXJuIGZlYXR1cmVzO1xuICAgIH1cblxuICAgIHZhciB6ID0gZnJvbUtleSh0aWxlQ2FjaGUucGVla0ZpcnN0S2V5KCkpWzBdO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMudGlsZUdyaWQ7XG4gICAgdGlsZUNhY2hlLmZvckVhY2goZnVuY3Rpb24gKHRpbGUpIHtcbiAgICAgIGlmICh0aWxlLnRpbGVDb29yZFswXSAhPT0geiB8fCB0aWxlLmdldFN0YXRlKCkgIT09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgc291cmNlVGlsZXMgPSB0aWxlLmdldFNvdXJjZVRpbGVzKCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHNvdXJjZVRpbGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgdmFyIHNvdXJjZVRpbGUgPSBzb3VyY2VUaWxlc1tpXTtcbiAgICAgICAgdmFyIHRpbGVDb29yZCA9IHNvdXJjZVRpbGUudGlsZUNvb3JkO1xuXG4gICAgICAgIGlmIChpbnRlcnNlY3RzKGV4dGVudCwgdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHRpbGVDb29yZCkpKSB7XG4gICAgICAgICAgdmFyIHRpbGVGZWF0dXJlcyA9IHNvdXJjZVRpbGUuZ2V0RmVhdHVyZXMoKTtcblxuICAgICAgICAgIGlmICh0aWxlRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IHRpbGVGZWF0dXJlcy5sZW5ndGg7IGogPCBqajsgKytqKSB7XG4gICAgICAgICAgICAgIHZhciBjYW5kaWRhdGUgPSB0aWxlRmVhdHVyZXNbal07XG4gICAgICAgICAgICAgIHZhciBnZW9tZXRyeSA9IGNhbmRpZGF0ZS5nZXRHZW9tZXRyeSgpO1xuXG4gICAgICAgICAgICAgIGlmIChpbnRlcnNlY3RzKGV4dGVudCwgZ2VvbWV0cnkuZ2V0RXh0ZW50KCkpKSB7XG4gICAgICAgICAgICAgICAgZmVhdHVyZXMucHVzaChjYW5kaWRhdGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGZlYXR1cmVzO1xuICB9O1xuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNvdXJjZSBjYW4gaGF2ZSBvdmVybGFwcGluZyBnZW9tZXRyaWVzLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldE92ZXJsYXBzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXBzXztcbiAgfTtcbiAgLyoqXG4gICAqIGNsZWFyIHtAbGluayBtb2R1bGU6b2wvVGlsZUNhY2hlflRpbGVDYWNoZX0gYW5kIGRlbGV0ZSBhbGwgc291cmNlIHRpbGVzXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRpbGVDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMuc291cmNlVGlsZUNhY2hlLmNsZWFyKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7IU9iamVjdDxzdHJpbmcsIGJvb2xlYW4+fSB1c2VkVGlsZXMgVXNlZCB0aWxlcy5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5leHBpcmVDYWNoZSA9IGZ1bmN0aW9uIChwcm9qZWN0aW9uLCB1c2VkVGlsZXMpIHtcbiAgICBfc3VwZXIucHJvdG90eXBlLmV4cGlyZUNhY2hlLmNhbGwodGhpcywgcHJvamVjdGlvbiwgdXNlZFRpbGVzKTtcblxuICAgIHRoaXMuc291cmNlVGlsZUNhY2hlLmV4cGlyZUNhY2hlKHt9KTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvblwiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEBwYXJhbSB7VmVjdG9yUmVuZGVyVGlsZX0gdGlsZSBWZWN0b3IgaW1hZ2UgdGlsZS5cbiAgICogQHJldHVybiB7QXJyYXk8aW1wb3J0KFwiLi4vVmVjdG9yVGlsZVwiKS5kZWZhdWx0Pn0gVGlsZSBrZXlzLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFNvdXJjZVRpbGVzID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8sIHByb2plY3Rpb24sIHRpbGUpIHtcbiAgICB2YXIgdXJsVGlsZUNvb3JkID0gdGlsZS53cmFwcGVkVGlsZUNvb3JkO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciBleHRlbnQgPSB0aWxlR3JpZC5nZXRUaWxlQ29vcmRFeHRlbnQodXJsVGlsZUNvb3JkKTtcbiAgICB2YXIgeiA9IHVybFRpbGVDb29yZFswXTtcbiAgICB2YXIgcmVzb2x1dGlvbiA9IHRpbGVHcmlkLmdldFJlc29sdXRpb24oeik7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgIGJ1ZmZlckV4dGVudChleHRlbnQsIC1yZXNvbHV0aW9uLCBleHRlbnQpO1xuICAgIHZhciBzb3VyY2VUaWxlR3JpZCA9IHRoaXMudGlsZUdyaWQ7XG4gICAgdmFyIHNvdXJjZUV4dGVudCA9IHNvdXJjZVRpbGVHcmlkLmdldEV4dGVudCgpO1xuXG4gICAgaWYgKHNvdXJjZUV4dGVudCkge1xuICAgICAgZ2V0SW50ZXJzZWN0aW9uKGV4dGVudCwgc291cmNlRXh0ZW50LCBleHRlbnQpO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2VaID0gc291cmNlVGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbiwgMSk7XG4gICAgdmFyIG1pblpvb20gPSBzb3VyY2VUaWxlR3JpZC5nZXRNaW5ab29tKCk7XG4gICAgdmFyIHByZXZpb3VzU291cmNlVGlsZXMgPSB0aWxlLnNvdXJjZVRpbGVzO1xuICAgIHZhciBzb3VyY2VUaWxlcywgY292ZXJlZCwgbG9hZGVkWjtcblxuICAgIGlmIChwcmV2aW91c1NvdXJjZVRpbGVzICYmIHByZXZpb3VzU291cmNlVGlsZXMubGVuZ3RoID4gMCAmJiBwcmV2aW91c1NvdXJjZVRpbGVzWzBdLnRpbGVDb29yZFswXSA9PT0gc291cmNlWikge1xuICAgICAgc291cmNlVGlsZXMgPSBwcmV2aW91c1NvdXJjZVRpbGVzO1xuICAgICAgY292ZXJlZCA9IHRydWU7XG4gICAgICBsb2FkZWRaID0gc291cmNlWjtcbiAgICB9IGVsc2Uge1xuICAgICAgc291cmNlVGlsZXMgPSBbXTtcbiAgICAgIGxvYWRlZFogPSBzb3VyY2VaICsgMTtcblxuICAgICAgZG8ge1xuICAgICAgICAtLWxvYWRlZFo7XG4gICAgICAgIGNvdmVyZWQgPSB0cnVlO1xuICAgICAgICBzb3VyY2VUaWxlR3JpZC5mb3JFYWNoVGlsZUNvb3JkKGV4dGVudCwgbG9hZGVkWiwgZnVuY3Rpb24gKHNvdXJjZVRpbGVDb29yZCkge1xuICAgICAgICAgIHZhciB0aWxlVXJsID0gdGhpcy50aWxlVXJsRnVuY3Rpb24oc291cmNlVGlsZUNvb3JkLCBwaXhlbFJhdGlvLCBwcm9qZWN0aW9uKTtcbiAgICAgICAgICB2YXIgc291cmNlVGlsZTtcblxuICAgICAgICAgIGlmICh0aWxlVXJsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZVRpbGVDYWNoZS5jb250YWluc0tleSh0aWxlVXJsKSkge1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlID0gdGhpcy5zb3VyY2VUaWxlQ2FjaGUuZ2V0KHRpbGVVcmwpO1xuICAgICAgICAgICAgICB2YXIgc3RhdGUgPSBzb3VyY2VUaWxlLmdldFN0YXRlKCk7XG5cbiAgICAgICAgICAgICAgaWYgKHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IgfHwgc3RhdGUgPT09IFRpbGVTdGF0ZS5FTVBUWSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVRpbGVzLnB1c2goc291cmNlVGlsZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGxvYWRlZFogPT09IHNvdXJjZVopIHtcbiAgICAgICAgICAgICAgc291cmNlVGlsZSA9IG5ldyB0aGlzLnRpbGVDbGFzcyhzb3VyY2VUaWxlQ29vcmQsIFRpbGVTdGF0ZS5JRExFLCB0aWxlVXJsLCB0aGlzLmZvcm1hdF8sIHRoaXMudGlsZUxvYWRGdW5jdGlvbik7XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUuZXh0ZW50ID0gc291cmNlVGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHNvdXJjZVRpbGVDb29yZCk7XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUucHJvamVjdGlvbiA9IHByb2plY3Rpb247XG4gICAgICAgICAgICAgIHNvdXJjZVRpbGUucmVzb2x1dGlvbiA9IHNvdXJjZVRpbGVHcmlkLmdldFJlc29sdXRpb24oc291cmNlVGlsZUNvb3JkWzBdKTtcbiAgICAgICAgICAgICAgdGhpcy5zb3VyY2VUaWxlQ2FjaGUuc2V0KHRpbGVVcmwsIHNvdXJjZVRpbGUpO1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlLmFkZEV2ZW50TGlzdGVuZXIoRXZlbnRUeXBlLkNIQU5HRSwgdGhpcy5oYW5kbGVUaWxlQ2hhbmdlLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICBzb3VyY2VUaWxlLmxvYWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb3ZlcmVkID0gY292ZXJlZCAmJiBzb3VyY2VUaWxlICYmIHNvdXJjZVRpbGUuZ2V0U3RhdGUoKSA9PT0gVGlsZVN0YXRlLkxPQURFRDtcblxuICAgICAgICAgIGlmICghc291cmNlVGlsZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChzb3VyY2VUaWxlLmdldFN0YXRlKCkgIT09IFRpbGVTdGF0ZS5FTVBUWSAmJiB0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICAgICAgICB0aWxlLmxvYWRpbmdTb3VyY2VUaWxlcysrO1xuICAgICAgICAgICAgc291cmNlVGlsZS5hZGRFdmVudExpc3RlbmVyKEV2ZW50VHlwZS5DSEFOR0UsIGZ1bmN0aW9uIGxpc3RlbkNoYW5nZSgpIHtcbiAgICAgICAgICAgICAgdmFyIHN0YXRlID0gc291cmNlVGlsZS5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgICB2YXIgc291cmNlVGlsZUtleSA9IHNvdXJjZVRpbGUuZ2V0S2V5KCk7XG5cbiAgICAgICAgICAgICAgaWYgKHN0YXRlID09PSBUaWxlU3RhdGUuTE9BREVEIHx8IHN0YXRlID09PSBUaWxlU3RhdGUuRVJST1IpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT09IFRpbGVTdGF0ZS5MT0FERUQpIHtcbiAgICAgICAgICAgICAgICAgIHNvdXJjZVRpbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihFdmVudFR5cGUuQ0hBTkdFLCBsaXN0ZW5DaGFuZ2UpO1xuICAgICAgICAgICAgICAgICAgdGlsZS5sb2FkaW5nU291cmNlVGlsZXMtLTtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aWxlLmVycm9yU291cmNlVGlsZUtleXNbc291cmNlVGlsZUtleV07XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gVGlsZVN0YXRlLkVSUk9SKSB7XG4gICAgICAgICAgICAgICAgICB0aWxlLmVycm9yU291cmNlVGlsZUtleXNbc291cmNlVGlsZUtleV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBlcnJvclRpbGVDb3VudCA9IE9iamVjdC5rZXlzKHRpbGUuZXJyb3JTb3VyY2VUaWxlS2V5cykubGVuZ3RoO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRpbGUubG9hZGluZ1NvdXJjZVRpbGVzIC0gZXJyb3JUaWxlQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgIHRpbGUuaGlmaSA9IGVycm9yVGlsZUNvdW50ID09PSAwO1xuICAgICAgICAgICAgICAgICAgdGlsZS5zb3VyY2VaID0gc291cmNlWjtcbiAgICAgICAgICAgICAgICAgIHRpbGUuc2V0U3RhdGUoVGlsZVN0YXRlLkxPQURFRCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKCFjb3ZlcmVkKSB7XG4gICAgICAgICAgc291cmNlVGlsZXMubGVuZ3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgfSB3aGlsZSAoIWNvdmVyZWQgJiYgbG9hZGVkWiA+IG1pblpvb20pO1xuICAgIH1cblxuICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPT09IFRpbGVTdGF0ZS5JRExFKSB7XG4gICAgICB0aWxlLnNldFN0YXRlKFRpbGVTdGF0ZS5MT0FESU5HKTtcbiAgICB9XG5cbiAgICBpZiAoY292ZXJlZCkge1xuICAgICAgdGlsZS5oaWZpID0gc291cmNlWiA9PT0gbG9hZGVkWjtcbiAgICAgIHRpbGUuc291cmNlWiA9IGxvYWRlZFo7XG5cbiAgICAgIGlmICh0aWxlLmdldFN0YXRlKCkgPCBUaWxlU3RhdGUuTE9BREVEKSB7XG4gICAgICAgIHRpbGUuc2V0U3RhdGUoVGlsZVN0YXRlLkxPQURFRCk7XG4gICAgICB9IGVsc2UgaWYgKCFwcmV2aW91c1NvdXJjZVRpbGVzIHx8ICFlcXVhbHMoc291cmNlVGlsZXMsIHByZXZpb3VzU291cmNlVGlsZXMpKSB7XG4gICAgICAgIHRpbGUuc291cmNlVGlsZXMgPSBzb3VyY2VUaWxlcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc291cmNlVGlsZXM7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0geiBUaWxlIGNvb3JkaW5hdGUgei5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHggVGlsZSBjb29yZGluYXRlIHguXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB5IFRpbGUgY29vcmRpbmF0ZSB5LlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uLlxuICAgKiBAcmV0dXJuIHshVmVjdG9yUmVuZGVyVGlsZX0gVGlsZS5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRUaWxlID0gZnVuY3Rpb24gKHosIHgsIHksIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pIHtcbiAgICB2YXIgY29vcmRLZXkgPSBnZXRLZXlaWFkoeiwgeCwgeSk7XG4gICAgdmFyIGtleSA9IHRoaXMuZ2V0S2V5KCk7XG4gICAgdmFyIHRpbGU7XG5cbiAgICBpZiAodGhpcy50aWxlQ2FjaGUuY29udGFpbnNLZXkoY29vcmRLZXkpKSB7XG4gICAgICB0aWxlID0gdGhpcy50aWxlQ2FjaGUuZ2V0KGNvb3JkS2V5KTtcblxuICAgICAgaWYgKHRpbGUua2V5ID09PSBrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRpbGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRpbGVDb29yZCA9IFt6LCB4LCB5XTtcbiAgICB2YXIgdXJsVGlsZUNvb3JkID0gdGhpcy5nZXRUaWxlQ29vcmRGb3JUaWxlVXJsRnVuY3Rpb24odGlsZUNvb3JkLCBwcm9qZWN0aW9uKTtcbiAgICB2YXIgc291cmNlRXh0ZW50ID0gdGhpcy5nZXRUaWxlR3JpZCgpLmdldEV4dGVudCgpO1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuXG4gICAgaWYgKHVybFRpbGVDb29yZCAmJiBzb3VyY2VFeHRlbnQpIHtcbiAgICAgIHZhciB0aWxlRXh0ZW50ID0gdGlsZUdyaWQuZ2V0VGlsZUNvb3JkRXh0ZW50KHVybFRpbGVDb29yZCk7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgICAgYnVmZmVyRXh0ZW50KHRpbGVFeHRlbnQsIC10aWxlR3JpZC5nZXRSZXNvbHV0aW9uKHopLCB0aWxlRXh0ZW50KTtcblxuICAgICAgaWYgKCFpbnRlcnNlY3RzKHNvdXJjZUV4dGVudCwgdGlsZUV4dGVudCkpIHtcbiAgICAgICAgdXJsVGlsZUNvb3JkID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZW1wdHkgPSB0cnVlO1xuXG4gICAgaWYgKHVybFRpbGVDb29yZCAhPT0gbnVsbCkge1xuICAgICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gdGhpcy50aWxlR3JpZDtcbiAgICAgIHZhciByZXNvbHV0aW9uID0gdGlsZUdyaWQuZ2V0UmVzb2x1dGlvbih6KTtcbiAgICAgIHZhciBzb3VyY2VaID0gc291cmNlVGlsZUdyaWQuZ2V0WkZvclJlc29sdXRpb24ocmVzb2x1dGlvbiwgMSk7IC8vIG1ha2UgZXh0ZW50IDEgcGl4ZWwgc21hbGxlciBzbyB3ZSBkb24ndCBsb2FkIHRpbGVzIGZvciA8IDAuNSBwaXhlbCByZW5kZXIgc3BhY2VcblxuICAgICAgdmFyIGV4dGVudCA9IHRpbGVHcmlkLmdldFRpbGVDb29yZEV4dGVudCh1cmxUaWxlQ29vcmQpO1xuICAgICAgYnVmZmVyRXh0ZW50KGV4dGVudCwgLXJlc29sdXRpb24sIGV4dGVudCk7XG4gICAgICBzb3VyY2VUaWxlR3JpZC5mb3JFYWNoVGlsZUNvb3JkKGV4dGVudCwgc291cmNlWiwgZnVuY3Rpb24gKHNvdXJjZVRpbGVDb29yZCkge1xuICAgICAgICBlbXB0eSA9IGVtcHR5ICYmICF0aGlzLnRpbGVVcmxGdW5jdGlvbihzb3VyY2VUaWxlQ29vcmQsIHBpeGVsUmF0aW8sIHByb2plY3Rpb24pO1xuICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9XG5cbiAgICB2YXIgbmV3VGlsZSA9IG5ldyBWZWN0b3JSZW5kZXJUaWxlKHRpbGVDb29yZCwgZW1wdHkgPyBUaWxlU3RhdGUuRU1QVFkgOiBUaWxlU3RhdGUuSURMRSwgdXJsVGlsZUNvb3JkLCB0aGlzLmdldFNvdXJjZVRpbGVzLmJpbmQodGhpcywgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikpO1xuICAgIG5ld1RpbGUua2V5ID0ga2V5O1xuXG4gICAgaWYgKHRpbGUpIHtcbiAgICAgIG5ld1RpbGUuaW50ZXJpbVRpbGUgPSB0aWxlO1xuICAgICAgbmV3VGlsZS5yZWZyZXNoSW50ZXJpbUNoYWluKCk7XG4gICAgICB0aGlzLnRpbGVDYWNoZS5yZXBsYWNlKGNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50aWxlQ2FjaGUuc2V0KGNvb3JkS2V5LCBuZXdUaWxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3VGlsZTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICogQHJldHVybiB7IWltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9IFRpbGUgZ3JpZC5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS5nZXRUaWxlR3JpZEZvclByb2plY3Rpb24gPSBmdW5jdGlvbiAocHJvamVjdGlvbikge1xuICAgIHZhciBjb2RlID0gcHJvamVjdGlvbi5nZXRDb2RlKCk7XG4gICAgdmFyIHRpbGVHcmlkID0gdGhpcy50aWxlR3JpZHNfW2NvZGVdO1xuXG4gICAgaWYgKCF0aWxlR3JpZCkge1xuICAgICAgLy8gQSB0aWxlIGdyaWQgdGhhdCBtYXRjaGVzIHRoZSB0aWxlIHNpemUgb2YgdGhlIHNvdXJjZSB0aWxlIGdyaWQgaXMgbW9yZVxuICAgICAgLy8gbGlrZWx5IHRvIGhhdmUgMToxIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBzb3VyY2UgdGlsZXMgYW5kIHJlbmRlcmVkIHRpbGVzLlxuICAgICAgdmFyIHNvdXJjZVRpbGVHcmlkID0gdGhpcy50aWxlR3JpZDtcbiAgICAgIHRpbGVHcmlkID0gY3JlYXRlRm9yUHJvamVjdGlvbihwcm9qZWN0aW9uLCB1bmRlZmluZWQsIHNvdXJjZVRpbGVHcmlkID8gc291cmNlVGlsZUdyaWQuZ2V0VGlsZVNpemUoc291cmNlVGlsZUdyaWQuZ2V0TWluWm9vbSgpKSA6IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLnRpbGVHcmlkc19bY29kZV0gPSB0aWxlR3JpZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGlsZUdyaWQ7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIHRpbGUgcGl4ZWwgcmF0aW8gZm9yIHRoaXMgc291cmNlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gcGl4ZWxSYXRpbyBQaXhlbCByYXRpby5cbiAgICogQHJldHVybiB7bnVtYmVyfSBUaWxlIHBpeGVsIHJhdGlvLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFRpbGVQaXhlbFJhdGlvID0gZnVuY3Rpb24gKHBpeGVsUmF0aW8pIHtcbiAgICByZXR1cm4gcGl4ZWxSYXRpbztcbiAgfTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB6IFouXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwaXhlbFJhdGlvIFBpeGVsIHJhdGlvLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3Byb2ovUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBwcm9qZWN0aW9uIFByb2plY3Rpb24uXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3NpemUuanNcIikuU2l6ZX0gVGlsZSBzaXplLlxuICAgKi9cblxuXG4gIFZlY3RvclRpbGUucHJvdG90eXBlLmdldFRpbGVQaXhlbFNpemUgPSBmdW5jdGlvbiAoeiwgcGl4ZWxSYXRpbywgcHJvamVjdGlvbikge1xuICAgIHZhciB0aWxlR3JpZCA9IHRoaXMuZ2V0VGlsZUdyaWRGb3JQcm9qZWN0aW9uKHByb2plY3Rpb24pO1xuICAgIHZhciB0aWxlU2l6ZSA9IHRvU2l6ZSh0aWxlR3JpZC5nZXRUaWxlU2l6ZSh6KSwgdGhpcy50bXBTaXplKTtcbiAgICByZXR1cm4gW01hdGgucm91bmQodGlsZVNpemVbMF0gKiBwaXhlbFJhdGlvKSwgTWF0aC5yb3VuZCh0aWxlU2l6ZVsxXSAqIHBpeGVsUmF0aW8pXTtcbiAgfTtcbiAgLyoqXG4gICAqIEluY3JlYXNlcyB0aGUgY2FjaGUgc2l6ZSBpZiBuZWVkZWRcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbGVDb3VudCBNaW5pbXVtIG51bWJlciBvZiB0aWxlcyBuZWVkZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICovXG5cblxuICBWZWN0b3JUaWxlLnByb3RvdHlwZS51cGRhdGVDYWNoZVNpemUgPSBmdW5jdGlvbiAodGlsZUNvdW50LCBwcm9qZWN0aW9uKSB7XG4gICAgX3N1cGVyLnByb3RvdHlwZS51cGRhdGVDYWNoZVNpemUuY2FsbCh0aGlzLCB0aWxlQ291bnQgKiAyLCBwcm9qZWN0aW9uKTtcbiAgfTtcblxuICByZXR1cm4gVmVjdG9yVGlsZTtcbn0oVXJsVGlsZSk7XG5cbmV4cG9ydCBkZWZhdWx0IFZlY3RvclRpbGU7XG4vKipcbiAqIFNldHMgdGhlIGxvYWRlciBmb3IgYSB0aWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9WZWN0b3JUaWxlLmpzXCIpLmRlZmF1bHR9IHRpbGUgVmVjdG9yIHRpbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIFVSTC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdExvYWRGdW5jdGlvbih0aWxlLCB1cmwpIHtcbiAgdGlsZS5zZXRMb2FkZXIoXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIChleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24pIHtcbiAgICBsb2FkRmVhdHVyZXNYaHIodXJsLCB0aWxlLmdldEZvcm1hdCgpLCBleHRlbnQsIHJlc29sdXRpb24sIHByb2plY3Rpb24sIHRpbGUub25Mb2FkLmJpbmQodGlsZSksIHRpbGUub25FcnJvci5iaW5kKHRpbGUpKTtcbiAgfSk7XG59IiwiLypcbm9sLW1hcGJveC1zdHlsZSAtIFVzZSBNYXBib3ggU3R5bGUgb2JqZWN0cyB3aXRoIE9wZW5MYXllcnNcbkNvcHlyaWdodCAyMDE2LXByZXNlbnQgb2wtbWFwYm94LXN0eWxlIGNvbnRyaWJ1dG9yc1xuTGljZW5zZTogaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29wZW5sYXllcnMvb2wtbWFwYm94LXN0eWxlL21hc3Rlci9MSUNFTlNFXG4qL1xuaW1wb3J0IG1iMmNzcyBmcm9tICdtYXBib3gtdG8tY3NzLWZvbnQnO1xuaW1wb3J0IGFwcGx5U3R5bGVGdW5jdGlvbiwgeyBnZXRWYWx1ZSB9IGZyb20gJy4vc3R5bGVmdW5jdGlvbic7XG5pbXBvcnQgZ29vZ2xlRm9udHMgZnJvbSAnd2ViZm9udC1tYXRjaGVyL2xpYi9mb250cy9nb29nbGUnO1xuaW1wb3J0IHsgZnJvbUxvbkxhdCB9IGZyb20gJ29sL3Byb2onO1xuaW1wb3J0IHsgY3JlYXRlWFlaIH0gZnJvbSAnb2wvdGlsZWdyaWQnO1xuaW1wb3J0IFRpbGVHcmlkIGZyb20gJ29sL3RpbGVncmlkL1RpbGVHcmlkJztcbmltcG9ydCBNYXAgZnJvbSAnb2wvTWFwJztcbmltcG9ydCBWaWV3IGZyb20gJ29sL1ZpZXcnO1xuaW1wb3J0IEdlb0pTT04gZnJvbSAnb2wvZm9ybWF0L0dlb0pTT04nO1xuaW1wb3J0IE1WVCBmcm9tICdvbC9mb3JtYXQvTVZUJztcbmltcG9ydCB7IHVuQnlLZXkgfSBmcm9tICdvbC9PYnNlcnZhYmxlJztcbmltcG9ydCBUaWxlTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVGlsZSc7XG5pbXBvcnQgVmVjdG9yTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVmVjdG9yJztcbmltcG9ydCBWZWN0b3JUaWxlTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVmVjdG9yVGlsZSc7XG5pbXBvcnQgVGlsZUpTT04gZnJvbSAnb2wvc291cmNlL1RpbGVKU09OJztcbmltcG9ydCBWZWN0b3JTb3VyY2UgZnJvbSAnb2wvc291cmNlL1ZlY3Rvcic7XG5pbXBvcnQgVmVjdG9yVGlsZVNvdXJjZSBmcm9tICdvbC9zb3VyY2UvVmVjdG9yVGlsZSc7XG5pbXBvcnQgeyBDb2xvciB9IGZyb20gJ0BtYXBib3gvbWFwYm94LWdsLXN0eWxlLXNwZWMnO1xuaW1wb3J0IHsgYXNzaWduLCBkZWZhdWx0UmVzb2x1dGlvbnMgfSBmcm9tICcuL3V0aWwnO1xuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwib2wvTWFwXCIpLmRlZmF1bHR9IFBsdWdnYWJsZU1hcFxuICogQHR5cGVkZWYge2ltcG9ydChcIm9sL2xheWVyL0xheWVyXCIpLmRlZmF1bHR9IExheWVyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwib2wvc291cmNlL1NvdXJjZVwiKS5kZWZhdWx0fSBTb3VyY2VcbiAqIEBwcml2YXRlXG4gKi9cblxudmFyIHRpbGVqc29uQ2FjaGUgPSB7fTtcbnZhciBmb250RmFtaWx5UmVnRXggPSAvZm9udC1mYW1pbHk6ID8oW147XSopOy87XG52YXIgc3RyaXBRdW90ZXNSZWdFeCA9IC8oXCJ8JykvZztcbnZhciBsb2FkZWRGb250RmFtaWxpZXM7XG5cbmZ1bmN0aW9uIGhhc0ZvbnRGYW1pbHkoZmFtaWx5KSB7XG4gIGlmICghbG9hZGVkRm9udEZhbWlsaWVzKSB7XG4gICAgbG9hZGVkRm9udEZhbWlsaWVzID0ge307XG4gICAgdmFyIHN0eWxlU2hlZXRzID0gZG9jdW1lbnQuc3R5bGVTaGVldHM7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgaWkgPSBzdHlsZVNoZWV0cy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgICB2YXIgc3R5bGVTaGVldCA9XG4gICAgICAvKiogQHR5cGUge0NTU1N0eWxlU2hlZXR9ICovXG4gICAgICBzdHlsZVNoZWV0c1tpXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIGNzc1J1bGVzID0gc3R5bGVTaGVldC5ydWxlcyB8fCBzdHlsZVNoZWV0LmNzc1J1bGVzO1xuXG4gICAgICAgIGlmIChjc3NSdWxlcykge1xuICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqaiA9IGNzc1J1bGVzLmxlbmd0aDsgaiA8IGpqOyArK2opIHtcbiAgICAgICAgICAgIHZhciBjc3NSdWxlID0gY3NzUnVsZXNbal07XG5cbiAgICAgICAgICAgIGlmIChjc3NSdWxlLnR5cGUgPT0gNSkge1xuICAgICAgICAgICAgICB2YXIgbWF0Y2ggPSBjc3NSdWxlLmNzc1RleHQubWF0Y2goZm9udEZhbWlseVJlZ0V4KTtcbiAgICAgICAgICAgICAgbG9hZGVkRm9udEZhbWlsaWVzW21hdGNoWzFdLnJlcGxhY2Uoc3RyaXBRdW90ZXNSZWdFeCwgJycpXSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7Ly8gZW1wdHkgY2F0Y2ggYmxvY2tcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFtaWx5IGluIGxvYWRlZEZvbnRGYW1pbGllcztcbn1cblxudmFyIHByb2Nlc3NlZEZvbnRGYW1pbGllcyA9IHt9O1xudmFyIGdvb2dsZUZhbWlsaWVzID0gZ29vZ2xlRm9udHMuZ2V0TmFtZXMoKTtcbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGZvbnRzIEZvbnRzLlxuICogQHJldHVybiB7QXJyYXl9IFByb2Nlc3NlZCBmb250cy5cbiAqL1xuXG5mdW5jdGlvbiBnZXRGb250cyhmb250cykge1xuICB2YXIgZm9udHNLZXkgPSBmb250cy50b1N0cmluZygpO1xuXG4gIGlmIChmb250c0tleSBpbiBwcm9jZXNzZWRGb250RmFtaWxpZXMpIHtcbiAgICByZXR1cm4gZm9udHM7XG4gIH1cblxuICB2YXIgZ29vZ2xlRm9udERlc2NyaXB0aW9ucyA9IGZvbnRzLm1hcChmdW5jdGlvbiAoZm9udCkge1xuICAgIHZhciBwYXJ0cyA9IG1iMmNzcyhmb250LCAxKS5zcGxpdCgnICcpO1xuICAgIHJldHVybiBbcGFydHMuc2xpY2UoMykuam9pbignICcpLnJlcGxhY2UoL1wiL2csICcnKSwgcGFydHNbMV0gKyBwYXJ0c1swXV07XG4gIH0pO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGdvb2dsZUZvbnREZXNjcmlwdGlvbnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBnb29nbGVGb250RGVzY3JpcHRpb24gPSBnb29nbGVGb250RGVzY3JpcHRpb25zW2ldO1xuICAgIHZhciBmYW1pbHkgPSBnb29nbGVGb250RGVzY3JpcHRpb25bMF07XG5cbiAgICBpZiAoIWhhc0ZvbnRGYW1pbHkoZmFtaWx5KSAmJiBnb29nbGVGYW1pbGllcy5pbmRleE9mKGZhbWlseSkgIT09IC0xKSB7XG4gICAgICB2YXIgZm9udFVybCA9ICdodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9JyArIGZhbWlseS5yZXBsYWNlKC8gL2csICcrJykgKyAnOicgKyBnb29nbGVGb250RGVzY3JpcHRpb25bMV07XG5cbiAgICAgIGlmICghZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbGlua1tocmVmPVwiJyArIGZvbnRVcmwgKyAnXCJdJykpIHtcbiAgICAgICAgdmFyIG1hcmt1cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcbiAgICAgICAgbWFya3VwLmhyZWYgPSBmb250VXJsO1xuICAgICAgICBtYXJrdXAucmVsID0gJ3N0eWxlc2hlZXQnO1xuICAgICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKG1hcmt1cCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvY2Vzc2VkRm9udEZhbWlsaWVzW2ZvbnRzS2V5XSA9IHRydWU7XG4gIHJldHVybiBmb250cztcbn1cblxudmFyIHNwcml0ZVJlZ0V4ID0gL14oLiopKFxcPy4qKSQvO1xuXG5mdW5jdGlvbiB3aXRoUGF0aCh1cmwsIHBhdGgpIHtcbiAgaWYgKHBhdGggJiYgdXJsLmluZGV4T2YoJy4nKSA9PT0gMCkge1xuICAgIHVybCA9IHBhdGggKyB1cmw7XG4gIH1cblxuICByZXR1cm4gdXJsO1xufVxuXG5mdW5jdGlvbiB0b1Nwcml0ZVVybCh1cmwsIHBhdGgsIGV4dGVuc2lvbikge1xuICB1cmwgPSB3aXRoUGF0aCh1cmwsIHBhdGgpO1xuICB2YXIgcGFydHMgPSB1cmwubWF0Y2goc3ByaXRlUmVnRXgpO1xuICByZXR1cm4gcGFydHMgPyBwYXJ0c1sxXSArIGV4dGVuc2lvbiArIChwYXJ0cy5sZW5ndGggPiAyID8gcGFydHNbMl0gOiAnJykgOiB1cmwgKyBleHRlbnNpb247XG59XG4vKipcbiAqIGBgYGpzXG4gKiBpbXBvcnQge2FwcGx5U3R5bGV9IGZyb20gJ29sLW1hcGJveC1zdHlsZSc7XG4gKiBgYGBcbiAqXG4gKiBBcHBsaWVzIGEgc3R5bGUgZnVuY3Rpb24gdG8gYW4gYG9sLmxheWVyLlZlY3RvclRpbGVgIG9yIGBvbC5sYXllci5WZWN0b3JgXG4gKiB3aXRoIGFuIGBvbC5zb3VyY2UuVmVjdG9yVGlsZWAgb3IgYW4gYG9sLnNvdXJjZS5WZWN0b3JgLiBUaGUgc3R5bGUgZnVuY3Rpb25cbiAqIHdpbGwgcmVuZGVyIGFsbCBsYXllcnMgZnJvbSB0aGUgYGdsU3R5bGVgIG9iamVjdCB0aGF0IHVzZSB0aGUgc3BlY2lmaWVkXG4gKiBgc291cmNlYCwgb3IgYSBzdWJzZXQgb2YgbGF5ZXJzIGZyb20gdGhlIHNhbWUgc291cmNlLiBUaGUgc291cmNlIG5lZWRzIHRvIGJlXG4gKiBhIGBcInR5cGVcIjogXCJ2ZWN0b3JcImAgb3IgYFwidHlwZVwiOiBcImdlb2pzb25cImAgc291cmNlLlxuICpcbiAqIFR3byBhZGRpdGlvbmFsIHByb3BlcnRpZXMgd2lsbCBiZSBzZXQgb24gdGhlIHByb3ZpZGVkIGxheWVyOlxuICpcbiAqICAqIGBtYXBib3gtc291cmNlYDogVGhlIGBpZGAgb2YgdGhlIE1hcGJveCBTdHlsZSBkb2N1bWVudCdzIHNvdXJjZSB0aGF0IHRoZVxuICogICAgT3BlbkxheWVycyBsYXllciB3YXMgY3JlYXRlZCBmcm9tLiBVc3VhbGx5IGBhcHBseSgpYCBjcmVhdGVzIG9uZVxuICogICAgT3BlbkxheWVycyBsYXllciBwZXIgTWFwYm94IFN0eWxlIHNvdXJjZSwgdW5sZXNzIHRoZSBsYXllciBzdGFjayBoYXNcbiAqICAgIGxheWVycyBmcm9tIGRpZmZlcmVudCBzb3VyY2VzIGluIGJldHdlZW4uXG4gKiAgKiBgbWFwYm94LWxheWVyc2A6IFRoZSBgaWRgcyBvZiB0aGUgTWFwYm94IFN0eWxlIGRvY3VtZW50J3MgbGF5ZXJzIHRoYXQgYXJlXG4gKiAgICBpbmNsdWRlZCBpbiB0aGUgT3BlbkxheWVycyBsYXllci5cbiAqXG4gKiBAcGFyYW0ge1ZlY3RvclRpbGVMYXllcnxWZWN0b3JMYXllcn0gbGF5ZXIgT3BlbkxheWVycyBsYXllci5cbiAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdH0gZ2xTdHlsZSBNYXBib3ggU3R5bGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gc291cmNlIGBzb3VyY2VgIGtleSBvciBhbiBhcnJheSBvZiBsYXllciBgaWRgcyBmcm9tIHRoZVxuICogTWFwYm94IFN0eWxlIG9iamVjdC4gV2hlbiBhIGBzb3VyY2VgIGtleSBpcyBwcm92aWRlZCwgYWxsIGxheWVycyBmb3IgdGhlXG4gKiBzcGVjaWZpZWQgc291cmNlIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIHN0eWxlIGZ1bmN0aW9uLiBXaGVuIGxheWVyIGBpZGBzXG4gKiBhcmUgcHJvdmlkZWQsIHRoZXkgbXVzdCBiZSBmcm9tIGxheWVycyB0aGF0IHVzZSB0aGUgc2FtZSBzb3VyY2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGg9dW5kZWZpbmVkXSBQYXRoIG9mIHRoZSBzdHlsZSBmaWxlLiBPbmx5IHJlcXVpcmVkIHdoZW5cbiAqIGEgcmVsYXRpdmUgcGF0aCBpcyB1c2VkIHdpdGggdGhlIGBcInNwcml0ZVwiYCBwcm9wZXJ0eSBvZiB0aGUgc3R5bGUuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IFtyZXNvbHV0aW9ucz11bmRlZmluZWRdIFJlc29sdXRpb25zIGZvciBtYXBwaW5nIHJlc29sdXRpb24gdG8gem9vbSBsZXZlbC5cbiAqIEByZXR1cm4ge1Byb21pc2V9IFByb21pc2Ugd2hpY2ggd2lsbCBiZSByZXNvbHZlZCB3aGVuIHRoZSBzdHlsZSBjYW4gYmUgdXNlZFxuICogZm9yIHJlbmRlcmluZy5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseVN0eWxlKGxheWVyLCBnbFN0eWxlLCBzb3VyY2UsIHBhdGgsIHJlc29sdXRpb25zKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgLy8gVE9ETzogZmlndXJlIG91dCB3aGVyZSBiZXN0IHBsYWNlIHRvIGNoZWNrIHNvdXJjZSB0eXBlIGlzXG4gICAgLy8gTm90ZSB0aGF0IHRoZSBzb3VyY2UgYXJnIGlzIGFuIGFycmF5IG9mIGdsIGxheWVyIGlkcyBhbmQgZWFjaCBtdXN0IGJlXG4gICAgLy8gZGVyZWZlcmVuY2VkIHRvIGdldCBzb3VyY2UgdHlwZSB0byB2YWxpZGF0ZVxuICAgIGlmICh0eXBlb2YgZ2xTdHlsZSAhPSAnb2JqZWN0Jykge1xuICAgICAgZ2xTdHlsZSA9IEpTT04ucGFyc2UoZ2xTdHlsZSk7XG4gICAgfVxuXG4gICAgaWYgKGdsU3R5bGUudmVyc2lvbiAhPSA4KSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignZ2xTdHlsZSB2ZXJzaW9uIDggcmVxdWlyZWQuJykpO1xuICAgIH1cblxuICAgIGlmICghKGxheWVyIGluc3RhbmNlb2YgVmVjdG9yTGF5ZXIgfHwgbGF5ZXIgaW5zdGFuY2VvZiBWZWN0b3JUaWxlTGF5ZXIpKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignQ2FuIG9ubHkgYXBwbHkgdG8gVmVjdG9yTGF5ZXIgb3IgVmVjdG9yVGlsZUxheWVyJykpO1xuICAgIH1cblxuICAgIHZhciBzcHJpdGVTY2FsZSwgc3ByaXRlRGF0YSwgc3ByaXRlSW1hZ2VVcmwsIHN0eWxlO1xuXG4gICAgZnVuY3Rpb24gb25DaGFuZ2UoKSB7XG4gICAgICBpZiAoIXN0eWxlICYmICghZ2xTdHlsZS5zcHJpdGUgfHwgc3ByaXRlRGF0YSkpIHtcbiAgICAgICAgc3R5bGUgPSBhcHBseVN0eWxlRnVuY3Rpb24obGF5ZXIsIGdsU3R5bGUsIHNvdXJjZSwgcmVzb2x1dGlvbnMsIHNwcml0ZURhdGEsIHNwcml0ZUltYWdlVXJsLCBnZXRGb250cyk7XG5cbiAgICAgICAgaWYgKCFsYXllci5nZXRTdHlsZSgpKSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIk5vdGhpbmcgdG8gc2hvdyBmb3Igc291cmNlIFtcIiArIHNvdXJjZSArIFwiXVwiKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN0eWxlKSB7XG4gICAgICAgIGxheWVyLnNldFN0eWxlKHN0eWxlKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignU29tZXRoaW5nIHdlbnQgd3JvbmcgdHJ5aW5nIHRvIGFwcGx5IHN0eWxlLicpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZ2xTdHlsZS5zcHJpdGUpIHtcbiAgICAgIHNwcml0ZVNjYWxlID0gd2luZG93LmRldmljZVBpeGVsUmF0aW8gPj0gMS41ID8gMC41IDogMTtcbiAgICAgIHZhciBzaXplRmFjdG9yXzEgPSBzcHJpdGVTY2FsZSA9PSAwLjUgPyAnQDJ4JyA6ICcnO1xuICAgICAgdmFyIHNwcml0ZVVybF8xID0gdG9TcHJpdGVVcmwoZ2xTdHlsZS5zcHJpdGUsIHBhdGgsIHNpemVGYWN0b3JfMSArICcuanNvbicpO1xuICAgICAgZmV0Y2goc3ByaXRlVXJsXzEsIHtcbiAgICAgICAgY3JlZGVudGlhbHM6ICdzYW1lLW9yaWdpbidcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmICghcmVzcG9uc2Uub2sgJiYgc2l6ZUZhY3Rvcl8xICE9PSAnJykge1xuICAgICAgICAgIHNwcml0ZVVybF8xID0gdG9TcHJpdGVVcmwoZ2xTdHlsZS5zcHJpdGUsIHBhdGgsICcuanNvbicpO1xuICAgICAgICAgIHJldHVybiBmZXRjaChzcHJpdGVVcmxfMSwge1xuICAgICAgICAgICAgY3JlZGVudGlhbHM6ICdzYW1lLW9yaWdpbidcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH1cbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlByb2JsZW0gZmV0Y2hpbmcgc3ByaXRlIGZyb20gXCIgKyBzcHJpdGVVcmxfMSArIFwiOiBcIiArIHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcbiAgICAgICAgfVxuICAgICAgfSkudGhlbihmdW5jdGlvbiAoc3ByaXRlc0pzb24pIHtcbiAgICAgICAgaWYgKHNwcml0ZXNKc29uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignTm8gc3ByaXRlcyBmb3VuZC4nKSk7XG4gICAgICAgIH1cblxuICAgICAgICBzcHJpdGVEYXRhID0gc3ByaXRlc0pzb247XG4gICAgICAgIHNwcml0ZUltYWdlVXJsID0gdG9TcHJpdGVVcmwoZ2xTdHlsZS5zcHJpdGUsIHBhdGgsIHNpemVGYWN0b3JfMSArICcucG5nJyk7XG4gICAgICAgIG9uQ2hhbmdlKCk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJTcHJpdGVzIGNhbm5vdCBiZSBsb2FkZWQ6IFwiICsgc3ByaXRlVXJsXzEgKyBcIjogXCIgKyBlcnIubWVzc2FnZSkpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9uQ2hhbmdlKCk7XG4gICAgfVxuICB9KTtcbn1cbnZhciBlbXB0eU9iaiA9IHt9O1xuXG5mdW5jdGlvbiBzZXRCYWNrZ3JvdW5kKG1hcCwgbGF5ZXIpIHtcbiAgdmFyIGJhY2tncm91bmQgPSB7XG4gICAgdHlwZTogbGF5ZXIudHlwZVxuICB9O1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZVN0eWxlKCkge1xuICAgIHZhciBlbGVtZW50ID0gbWFwLmdldFRhcmdldEVsZW1lbnQoKTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBsYXlvdXQgPSBsYXllci5sYXlvdXQgfHwge307XG4gICAgdmFyIHBhaW50ID0gbGF5ZXIucGFpbnQgfHwge307XG4gICAgYmFja2dyb3VuZFsncGFpbnQnXSA9IHBhaW50O1xuICAgIGJhY2tncm91bmQuaWQgPSAnb2xtcy1iZy0nICsgcGFpbnRbJ2JhY2tncm91bmQtb3BhY2l0eSddICsgcGFpbnRbJ2JhY2tncm91bmQtY29sb3InXTtcbiAgICB2YXIgem9vbSA9IG1hcC5nZXRWaWV3KCkuZ2V0Wm9vbSgpO1xuXG4gICAgaWYgKHBhaW50WydiYWNrZ3JvdW5kLWNvbG9yJ10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIGJnID0gZ2V0VmFsdWUoYmFja2dyb3VuZCwgJ3BhaW50JywgJ2JhY2tncm91bmQtY29sb3InLCB6b29tLCBlbXB0eU9iaik7XG4gICAgICBlbGVtZW50LnN0eWxlLmJhY2tncm91bmQgPSBDb2xvci5wYXJzZShiZykudG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAocGFpbnRbJ2JhY2tncm91bmQtb3BhY2l0eSddICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGVsZW1lbnQuc3R5bGUub3BhY2l0eSA9IGdldFZhbHVlKGJhY2tncm91bmQsICdwYWludCcsICdiYWNrZ3JvdW5kLW9wYWNpdHknLCB6b29tLCBlbXB0eU9iaik7XG4gICAgfVxuXG4gICAgaWYgKGxheW91dC52aXNpYmlsaXR5ID09ICdub25lJykge1xuICAgICAgZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSAnJztcbiAgICAgIGVsZW1lbnQuc3R5bGUub3BhY2l0eSA9ICcnO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtYXAuZ2V0VGFyZ2V0RWxlbWVudCgpKSB7XG4gICAgdXBkYXRlU3R5bGUoKTtcbiAgfVxuXG4gIG1hcC5vbihbJ2NoYW5nZTpyZXNvbHV0aW9uJywgJ2NoYW5nZTp0YXJnZXQnXSwgdXBkYXRlU3R5bGUpO1xufVxuLyoqXG4gKiBgYGBqc1xuICogaW1wb3J0IHthcHBseUJhY2tncm91bmR9IGZyb20gJ29sLW1hcGJveC1zdHlsZSc7XG4gKiBgYGBcbiAqIEFwcGxpZXMgcHJvcGVydGllcyBvZiB0aGUgTWFwYm94IFN0eWxlJ3MgZmlyc3QgYGJhY2tncm91bmRgIGxheWVyIHRvIHRoZSBtYXAuXG4gKiBAcGFyYW0ge1BsdWdnYWJsZU1hcH0gbWFwIE9wZW5MYXllcnMgTWFwLlxuICogQHBhcmFtIHtPYmplY3R9IGdsU3R5bGUgTWFwYm94IFN0eWxlIG9iamVjdC5cbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUJhY2tncm91bmQobWFwLCBnbFN0eWxlKSB7XG4gIGdsU3R5bGUubGF5ZXJzLnNvbWUoZnVuY3Rpb24gKGwpIHtcbiAgICBpZiAobC50eXBlID09ICdiYWNrZ3JvdW5kJykge1xuICAgICAgc2V0QmFja2dyb3VuZChtYXAsIGwpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U291cmNlSWRCeVJlZihsYXllcnMsIHJlZikge1xuICB2YXIgc291cmNlSWQ7XG4gIGxheWVycy5zb21lKGZ1bmN0aW9uIChsYXllcikge1xuICAgIGlmIChsYXllci5pZCA9PSByZWYpIHtcbiAgICAgIHNvdXJjZUlkID0gbGF5ZXIuc291cmNlO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHNvdXJjZUlkO1xufVxuXG5mdW5jdGlvbiBleHRlbnRGcm9tVGlsZUpTT04odGlsZUpTT04pIHtcbiAgdmFyIGJvdW5kcyA9IHRpbGVKU09OLmJvdW5kcztcblxuICBpZiAoYm91bmRzKSB7XG4gICAgdmFyIGxsID0gZnJvbUxvbkxhdChbYm91bmRzWzBdLCBib3VuZHNbMV1dKTtcbiAgICB2YXIgdHIgPSBmcm9tTG9uTGF0KFtib3VuZHNbMl0sIGJvdW5kc1szXV0pO1xuICAgIHJldHVybiBbbGxbMF0sIGxsWzFdLCB0clswXSwgdHJbMV1dO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldHVwVmVjdG9yTGF5ZXIoZ2xTb3VyY2UsIGFjY2Vzc1Rva2VuLCB1cmwpIHtcbiAgZ2xTb3VyY2UgPSBhc3NpZ24oe30sIGdsU291cmNlKTtcbiAgdmFyIGxheWVyID0gbmV3IFZlY3RvclRpbGVMYXllcih7XG4gICAgZGVjbHV0dGVyOiB0cnVlLFxuICAgIHZpc2libGU6IGZhbHNlXG4gIH0pO1xuICB2YXIgY2FjaGVLZXkgPSBKU09OLnN0cmluZ2lmeShnbFNvdXJjZSk7XG4gIHZhciB0aWxlanNvbiA9IHRpbGVqc29uQ2FjaGVbY2FjaGVLZXldO1xuXG4gIGlmICghdGlsZWpzb24pIHtcbiAgICB0aWxlanNvbiA9IHRpbGVqc29uQ2FjaGVbY2FjaGVLZXldID0gbmV3IFRpbGVKU09OKHtcbiAgICAgIHVybDogZ2xTb3VyY2UudGlsZXMgPyB1bmRlZmluZWQgOiB1cmwsXG4gICAgICB0aWxlSlNPTjogZ2xTb3VyY2UudGlsZXMgPyBnbFNvdXJjZSA6IHVuZGVmaW5lZFxuICAgIH0pO1xuICB9XG5cbiAgdmFyIGtleSA9IHRpbGVqc29uLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHN0YXRlID0gdGlsZWpzb24uZ2V0U3RhdGUoKTtcblxuICAgIGlmIChzdGF0ZSA9PT0gJ3JlYWR5Jykge1xuICAgICAgdmFyIHRpbGVKU09ORG9jID0gdGlsZWpzb24uZ2V0VGlsZUpTT04oKTtcbiAgICAgIHZhciB0aWxlcyA9IEFycmF5LmlzQXJyYXkodGlsZUpTT05Eb2MudGlsZXMpID8gdGlsZUpTT05Eb2MudGlsZXMgOiBbdGlsZUpTT05Eb2MudGlsZXNdO1xuXG4gICAgICBpZiAodXJsKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHRpbGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgICAgICB2YXIgdGlsZSA9IHRpbGVzW2ldO1xuXG4gICAgICAgICAgaWYgKHRpbGUuaW5kZXhPZignaHR0cCcpICE9IDApIHtcbiAgICAgICAgICAgIHRpbGVzW2ldID0gdXJsLnJlcGxhY2UoL1xcLz8kLywgJy8nKSArIHRpbGUucmVwbGFjZSgvXlxcLy8sICcnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHRpbGVHcmlkID0gdGlsZWpzb24uZ2V0VGlsZUdyaWQoKTtcbiAgICAgIHZhciBleHRlbnQgPSBleHRlbnRGcm9tVGlsZUpTT04odGlsZUpTT05Eb2MpO1xuICAgICAgdmFyIG1pblpvb20gPSB0aWxlSlNPTkRvYy5taW56b29tIHx8IDA7XG4gICAgICB2YXIgbWF4Wm9vbSA9IHRpbGVKU09ORG9jLm1heHpvb20gfHwgMjI7XG4gICAgICB2YXIgc291cmNlID0gdGlsZWpzb24uZ2V0KCdvbC1zb3VyY2UnKTtcblxuICAgICAgaWYgKHNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNvdXJjZSA9IG5ldyBWZWN0b3JUaWxlU291cmNlKHtcbiAgICAgICAgICBhdHRyaWJ1dGlvbnM6IHRpbGVqc29uLmdldEF0dHJpYnV0aW9ucygpLFxuICAgICAgICAgIGZvcm1hdDogbmV3IE1WVCgpLFxuICAgICAgICAgIHRpbGVHcmlkOiBuZXcgVGlsZUdyaWQoe1xuICAgICAgICAgICAgb3JpZ2luOiB0aWxlR3JpZC5nZXRPcmlnaW4oMCksXG4gICAgICAgICAgICBleHRlbnQ6IGV4dGVudCB8fCB0aWxlR3JpZC5nZXRFeHRlbnQoKSxcbiAgICAgICAgICAgIG1pblpvb206IG1pblpvb20sXG4gICAgICAgICAgICByZXNvbHV0aW9uczogZGVmYXVsdFJlc29sdXRpb25zLnNsaWNlKDAsIG1heFpvb20gKyAxKSxcbiAgICAgICAgICAgIHRpbGVTaXplOiA1MTJcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB1cmxzOiB0aWxlc1xuICAgICAgICB9KTtcbiAgICAgICAgdGlsZWpzb24uc2V0KCdvbC1zb3VyY2UnLCBzb3VyY2UpO1xuICAgICAgfVxuXG4gICAgICB1bkJ5S2V5KGtleSk7XG4gICAgICBsYXllci5zZXRTb3VyY2Uoc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHN0YXRlID09PSAnZXJyb3InKSB7XG4gICAgICB0aWxlanNvbi5zZXQoJ29sLXNvdXJjZScsIG51bGwpO1xuICAgICAgdW5CeUtleShrZXkpO1xuICAgICAgbGF5ZXIuc2V0U291cmNlKHVuZGVmaW5lZCk7XG4gICAgfVxuICB9KTtcblxuICBpZiAodGlsZWpzb24uZ2V0U3RhdGUoKSA9PT0gJ3JlYWR5Jykge1xuICAgIHRpbGVqc29uLmNoYW5nZWQoKTtcbiAgfVxuXG4gIHJldHVybiBsYXllcjtcbn1cblxuZnVuY3Rpb24gc2V0dXBSYXN0ZXJMYXllcihnbFNvdXJjZSwgdXJsKSB7XG4gIHZhciBsYXllciA9IG5ldyBUaWxlTGF5ZXIoKTtcbiAgdmFyIHNvdXJjZSA9IG5ldyBUaWxlSlNPTih7XG4gICAgdHJhbnNpdGlvbjogMCxcbiAgICB1cmw6IGdsU291cmNlLnRpbGVzID8gdW5kZWZpbmVkIDogdXJsLFxuICAgIHRpbGVKU09OOiBnbFNvdXJjZS50aWxlcyA/IGdsU291cmNlIDogdW5kZWZpbmVkLFxuICAgIGNyb3NzT3JpZ2luOiAnYW5vbnltb3VzJ1xuICB9KTtcbiAgdmFyIGtleSA9IHNvdXJjZS5vbignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgIHZhciBzdGF0ZSA9IHNvdXJjZS5nZXRTdGF0ZSgpO1xuXG4gICAgaWYgKHN0YXRlID09PSAncmVhZHknKSB7XG4gICAgICB1bkJ5S2V5KGtleSk7XG4gICAgICB2YXIgdGlsZUpTT05Eb2MgPVxuICAgICAgLyoqIEB0eXBlIHtPYmplY3R9ICovXG4gICAgICBzb3VyY2UuZ2V0VGlsZUpTT04oKTtcbiAgICAgIHZhciBleHRlbnQgPSBleHRlbnRGcm9tVGlsZUpTT04odGlsZUpTT05Eb2MpO1xuICAgICAgdmFyIHRpbGVHcmlkID0gc291cmNlLmdldFRpbGVHcmlkKCk7XG4gICAgICB2YXIgdGlsZVNpemUgPSBnbFNvdXJjZS50aWxlU2l6ZSB8fCB0aWxlSlNPTkRvYy50aWxlU2l6ZSB8fCA1MTI7XG4gICAgICB2YXIgbWluWm9vbSA9IHRpbGVKU09ORG9jLm1pbnpvb20gfHwgMDtcbiAgICAgIHZhciBtYXhab29tID0gdGlsZUpTT05Eb2MubWF4em9vbSB8fCAyMjsgLy8gT25seSB3b3JrcyB3aGVuIHVzaW5nIEVTIG1vZHVsZXNcblxuICAgICAgc291cmNlLnRpbGVHcmlkID0gbmV3IFRpbGVHcmlkKHtcbiAgICAgICAgb3JpZ2luOiB0aWxlR3JpZC5nZXRPcmlnaW4oMCksXG4gICAgICAgIGV4dGVudDogZXh0ZW50IHx8IHRpbGVHcmlkLmdldEV4dGVudCgpLFxuICAgICAgICBtaW5ab29tOiBtaW5ab29tLFxuICAgICAgICByZXNvbHV0aW9uczogY3JlYXRlWFlaKHtcbiAgICAgICAgICBtYXhab29tOiBtYXhab29tLFxuICAgICAgICAgIHRpbGVTaXplOiB0aWxlU2l6ZVxuICAgICAgICB9KS5nZXRSZXNvbHV0aW9ucygpLFxuICAgICAgICB0aWxlU2l6ZTogdGlsZVNpemVcbiAgICAgIH0pO1xuICAgICAgbGF5ZXIuc2V0U291cmNlKHNvdXJjZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gJ2Vycm9yJykge1xuICAgICAgdW5CeUtleShrZXkpO1xuICAgICAgbGF5ZXIuc2V0U291cmNlKHVuZGVmaW5lZCk7XG4gICAgfVxuICB9KTtcbiAgc291cmNlLnNldFRpbGVMb2FkRnVuY3Rpb24oZnVuY3Rpb24gKHRpbGUsIHNyYykge1xuICAgIGlmIChzcmMuaW5kZXhPZigne2Jib3gtZXBzZy0zODU3fScpICE9IC0xKSB7XG4gICAgICB2YXIgYmJveCA9IHNvdXJjZS5nZXRUaWxlR3JpZCgpLmdldFRpbGVDb29yZEV4dGVudCh0aWxlLmdldFRpbGVDb29yZCgpKTtcbiAgICAgIHNyYyA9IHNyYy5yZXBsYWNlKCd7YmJveC1lcHNnLTM4NTd9JywgYmJveC50b1N0cmluZygpKTtcbiAgICB9XG5cbiAgICB2YXIgaW1nID1cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIm9sL0ltYWdlVGlsZVwiKS5kZWZhdWx0fSAqL1xuICAgIHRpbGUuZ2V0SW1hZ2UoKTtcbiAgICAvKiogQHR5cGUge0hUTUxJbWFnZUVsZW1lbnR9ICovXG5cbiAgICBpbWcuc3JjID0gc3JjO1xuICB9KTtcbiAgcmV0dXJuIGxheWVyO1xufVxuXG52YXIgZ2VvSnNvbkZvcm1hdCA9IG5ldyBHZW9KU09OKCk7XG5cbmZ1bmN0aW9uIHNldHVwR2VvSlNPTkxheWVyKGdsU291cmNlLCBwYXRoKSB7XG4gIHZhciBkYXRhID0gZ2xTb3VyY2UuZGF0YTtcbiAgdmFyIGZlYXR1cmVzLCBnZW9Kc29uVXJsO1xuXG4gIGlmICh0eXBlb2YgZGF0YSA9PSAnc3RyaW5nJykge1xuICAgIGdlb0pzb25VcmwgPSB3aXRoUGF0aChkYXRhLCBwYXRoKTtcbiAgfSBlbHNlIHtcbiAgICBmZWF0dXJlcyA9IGdlb0pzb25Gb3JtYXQucmVhZEZlYXR1cmVzKGRhdGEsIHtcbiAgICAgIGZlYXR1cmVQcm9qZWN0aW9uOiAnRVBTRzozODU3J1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBWZWN0b3JMYXllcih7XG4gICAgc291cmNlOiBuZXcgVmVjdG9yU291cmNlKHtcbiAgICAgIGF0dHJpYnV0aW9uczogZ2xTb3VyY2UuYXR0cmlidXRpb24sXG4gICAgICBmZWF0dXJlczogZmVhdHVyZXMsXG4gICAgICBmb3JtYXQ6IGdlb0pzb25Gb3JtYXQsXG4gICAgICB1cmw6IGdlb0pzb25VcmxcbiAgICB9KSxcbiAgICB2aXNpYmxlOiBmYWxzZVxuICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlUmFzdGVyTGF5ZXJQcm9wZXJ0aWVzKGdsTGF5ZXIsIGxheWVyLCB2aWV3KSB7XG4gIHZhciB6b29tID0gdmlldy5nZXRab29tKCk7XG4gIHZhciBvcGFjaXR5ID0gZ2V0VmFsdWUoZ2xMYXllciwgJ3BhaW50JywgJ3Jhc3Rlci1vcGFjaXR5Jywgem9vbSwgZW1wdHlPYmopO1xuICBsYXllci5zZXRPcGFjaXR5KG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzU3R5bGUoZ2xTdHlsZSwgbWFwLCBiYXNlVXJsLCBob3N0LCBwYXRoLCBhY2Nlc3NUb2tlbikge1xuICBpZiAoYWNjZXNzVG9rZW4gPT09IHZvaWQgMCkge1xuICAgIGFjY2Vzc1Rva2VuID0gJyc7XG4gIH1cblxuICB2YXIgcHJvbWlzZXMgPSBbXTtcbiAgdmFyIHZpZXcgPSBtYXAuZ2V0VmlldygpO1xuXG4gIGlmICghdmlldy5pc0RlZigpICYmICF2aWV3LmdldFJvdGF0aW9uKCkgJiYgIXZpZXcuZ2V0UmVzb2x1dGlvbnMoKSkge1xuICAgIHZpZXcgPSBuZXcgVmlldyh7XG4gICAgICBtYXhSZXNvbHV0aW9uOiBkZWZhdWx0UmVzb2x1dGlvbnNbMF1cbiAgICB9KTtcbiAgICBtYXAuc2V0Vmlldyh2aWV3KTtcbiAgfVxuXG4gIGlmICgnY2VudGVyJyBpbiBnbFN0eWxlICYmICF2aWV3LmdldENlbnRlcigpKSB7XG4gICAgdmlldy5zZXRDZW50ZXIoZnJvbUxvbkxhdChnbFN0eWxlLmNlbnRlcikpO1xuICB9XG5cbiAgaWYgKCd6b29tJyBpbiBnbFN0eWxlICYmIHZpZXcuZ2V0Wm9vbSgpID09PSB1bmRlZmluZWQpIHtcbiAgICB2aWV3LnNldFJlc29sdXRpb24oZGVmYXVsdFJlc29sdXRpb25zWzBdIC8gTWF0aC5wb3coMiwgZ2xTdHlsZS56b29tKSk7XG4gIH1cblxuICBpZiAoIXZpZXcuZ2V0Q2VudGVyKCkgfHwgdmlldy5nZXRab29tKCkgPT09IHVuZGVmaW5lZCkge1xuICAgIHZpZXcuZml0KHZpZXcuZ2V0UHJvamVjdGlvbigpLmdldEV4dGVudCgpLCB7XG4gICAgICBuZWFyZXN0OiB0cnVlLFxuICAgICAgc2l6ZTogbWFwLmdldFNpemUoKVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGdsU3R5bGUuc3ByaXRlKSB7XG4gICAgaWYgKGdsU3R5bGUuc3ByaXRlLmluZGV4T2YoJ21hcGJveDovLycpID09IDApIHtcbiAgICAgIGdsU3R5bGUuc3ByaXRlID0gYmFzZVVybCArICcvc3ByaXRlJyArIGFjY2Vzc1Rva2VuO1xuICAgIH0gZWxzZSBpZiAoZ2xTdHlsZS5zcHJpdGUuaW5kZXhPZignaHR0cCcpICE9IDApIHtcbiAgICAgIGdsU3R5bGUuc3ByaXRlID0gKGhvc3QgPyBob3N0ICsgcGF0aCA6ICcnKSArIGdsU3R5bGUuc3ByaXRlICsgYWNjZXNzVG9rZW47XG4gICAgfVxuICB9XG5cbiAgdmFyIGdsTGF5ZXJzID0gZ2xTdHlsZS5sYXllcnM7XG4gIHZhciBsYXllcklkcyA9IFtdO1xuICB2YXIgZ2xMYXllciwgZ2xTb3VyY2UsIGdsU291cmNlSWQsIGlkLCBsYXllciwgdXJsO1xuXG4gIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gX2xvb3BfMShpLCBpaSkge1xuICAgIGdsTGF5ZXIgPSBnbExheWVyc1tpXTtcbiAgICB2YXIgdHlwZSA9IGdsTGF5ZXIudHlwZTtcblxuICAgIGlmICh0eXBlID09ICdoZWF0bWFwJyB8fCB0eXBlID09ICdoaWxsc2hhZGUnKSB7Ly9GSVhNRSBVbnN1cHBvcnRlZCBsYXllciB0eXBlXG4gICAgfSBlbHNlIGlmICh0eXBlID09ICdiYWNrZ3JvdW5kJykge1xuICAgICAgc2V0QmFja2dyb3VuZChtYXAsIGdsTGF5ZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZCA9IGdsTGF5ZXIuc291cmNlIHx8IGdldFNvdXJjZUlkQnlSZWYoZ2xMYXllcnMsIGdsTGF5ZXIucmVmKTsgLy8gdGhpcyB0ZWNobmlxdWUgYXNzdW1lcyBnbCBsYXllcnMgd2lsbCBiZSBpbiBhIHBhcnRpY3VsYXIgb3JkZXJcblxuICAgICAgaWYgKGlkICE9IGdsU291cmNlSWQpIHtcbiAgICAgICAgaWYgKGxheWVySWRzLmxlbmd0aCkge1xuICAgICAgICAgIHByb21pc2VzLnB1c2goZmluYWxpemVMYXllcihsYXllciwgbGF5ZXJJZHMsIGdsU3R5bGUsIHBhdGgsIG1hcCkpO1xuICAgICAgICAgIGxheWVySWRzID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBnbFNvdXJjZSA9IGdsU3R5bGUuc291cmNlc1tpZF07XG4gICAgICAgIHVybCA9IGdsU291cmNlLnVybDtcblxuICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgdXJsID0gd2l0aFBhdGgodXJsLCBwYXRoKTtcblxuICAgICAgICAgIGlmICh1cmwuaW5kZXhPZignbWFwYm94Oi8vJykgPT0gMCkge1xuICAgICAgICAgICAgdmFyIG1hcGlkXzEgPSB1cmwucmVwbGFjZSgnbWFwYm94Oi8vJywgJycpO1xuICAgICAgICAgICAgZ2xTb3VyY2UudGlsZXMgPSBbJ2EnLCAnYicsICdjJywgJ2QnXS5tYXAoZnVuY3Rpb24gKGhvc3QpIHtcbiAgICAgICAgICAgICAgcmV0dXJuICdodHRwczovLycgKyBob3N0ICsgJy50aWxlcy5tYXBib3guY29tL3Y0LycgKyBtYXBpZF8xICsgJy97en0ve3h9L3t5fS4nICsgKGdsU291cmNlLnR5cGUgPT0gJ3ZlY3RvcicgPyAndmVjdG9yLnBiZicgOiAncG5nJykgKyBhY2Nlc3NUb2tlbjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAodXJsLmluZGV4T2YoJy8nKSA9PT0gMCAmJiBob3N0LmluZGV4T2YoJ2h0dHAnKSA9PT0gMCkge1xuICAgICAgICAgICAgdXJsID0gaG9zdCArIHVybDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ2xTb3VyY2UudGlsZXMpIHtcbiAgICAgICAgICBnbFNvdXJjZS50aWxlcyA9IGdsU291cmNlLnRpbGVzLm1hcChmdW5jdGlvbiAodXJsKSB7XG4gICAgICAgICAgICByZXR1cm4gd2l0aFBhdGgodXJsLCBwYXRoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnbFNvdXJjZS50eXBlID09ICd2ZWN0b3InKSB7XG4gICAgICAgICAgbGF5ZXIgPSBzZXR1cFZlY3RvckxheWVyKGdsU291cmNlLCBhY2Nlc3NUb2tlbiwgdXJsKTtcbiAgICAgICAgfSBlbHNlIGlmIChnbFNvdXJjZS50eXBlID09ICdyYXN0ZXInKSB7XG4gICAgICAgICAgbGF5ZXIgPSBzZXR1cFJhc3RlckxheWVyKGdsU291cmNlLCB1cmwpO1xuICAgICAgICAgIGxheWVyLnNldFZpc2libGUoZ2xMYXllci5sYXlvdXQgPyBnbExheWVyLmxheW91dC52aXNpYmlsaXR5ICE9PSAnbm9uZScgOiB0cnVlKTtcbiAgICAgICAgICB2aWV3Lm9uKCdjaGFuZ2U6cmVzb2x1dGlvbicsIHVwZGF0ZVJhc3RlckxheWVyUHJvcGVydGllcy5iaW5kKHRoaXNfMSwgZ2xMYXllciwgbGF5ZXIsIHZpZXcpKTtcbiAgICAgICAgICB1cGRhdGVSYXN0ZXJMYXllclByb3BlcnRpZXMoZ2xMYXllciwgbGF5ZXIsIHZpZXcpO1xuICAgICAgICB9IGVsc2UgaWYgKGdsU291cmNlLnR5cGUgPT0gJ2dlb2pzb24nKSB7XG4gICAgICAgICAgbGF5ZXIgPSBzZXR1cEdlb0pTT05MYXllcihnbFNvdXJjZSwgcGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBnbFNvdXJjZUlkID0gaWQ7XG5cbiAgICAgICAgaWYgKGxheWVyKSB7XG4gICAgICAgICAgbGF5ZXIuc2V0KCdtYXBib3gtc291cmNlJywgZ2xTb3VyY2VJZCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGF5ZXJJZHMucHVzaChnbExheWVyLmlkKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIHRoaXNfMSA9IHRoaXM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gZ2xMYXllcnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIF9sb29wXzEoaSwgaWkpO1xuICB9XG5cbiAgcHJvbWlzZXMucHVzaChmaW5hbGl6ZUxheWVyKGxheWVyLCBsYXllcklkcywgZ2xTdHlsZSwgcGF0aCwgbWFwKSk7XG4gIG1hcC5zZXQoJ21hcGJveC1zdHlsZScsIGdsU3R5bGUpO1xuICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufVxuLyoqXG4gKiBgYGBqc1xuICogaW1wb3J0IG9sbXMgZnJvbSAnb2wtbWFwYm94LXN0eWxlJztcbiAqIGBgYFxuICpcbiAqIExvYWRzIGFuZCBhcHBsaWVzIGEgTWFwYm94IFN0eWxlIG9iamVjdCB0byBhbiBPcGVuTGF5ZXJzIE1hcC4gVGhpcyBpbmNsdWRlc1xuICogdGhlIG1hcCBiYWNrZ3JvdW5kLCB0aGUgbGF5ZXJzLCB0aGUgY2VudGVyIGFuZCB0aGUgem9vbS5cbiAqXG4gKiBUaGUgY2VudGVyIGFuZCB6b29tIHdpbGwgb25seSBiZSBzZXQgaWYgcHJlc2VudCBpbiB0aGUgTWFwYm94IFN0eWxlIGRvY3VtZW50LFxuICogYW5kIGlmIG5vdCBhbHJlYWR5IHNldCBvbiB0aGUgT3BlbkxheWVycyBtYXAuXG4gKlxuICogTGF5ZXJzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIE9wZW5MYXllcnMgbWFwLCB3aXRob3V0IGFmZmVjdGluZyBhbnkgbGF5ZXJzIHRoYXRcbiAqIG1pZ2h0IGFscmVhZHkgYmUgc2V0IG9uIHRoZSBtYXAuXG4gKlxuICogTGF5ZXJzIGFkZGVkIGJ5IGBhcHBseSgpYCB3aWxsIGhhdmUgdHdvIGFkZGl0aW9uYWwgcHJvcGVydGllczpcbiAqXG4gKiAgKiBgbWFwYm94LXNvdXJjZWA6IFRoZSBgaWRgIG9mIHRoZSBNYXBib3ggU3R5bGUgZG9jdW1lbnQncyBzb3VyY2UgdGhhdCB0aGVcbiAqICAgIE9wZW5MYXllcnMgbGF5ZXIgd2FzIGNyZWF0ZWQgZnJvbS4gVXN1YWxseSBgYXBwbHkoKWAgY3JlYXRlcyBvbmVcbiAqICAgIE9wZW5MYXllcnMgbGF5ZXIgcGVyIE1hcGJveCBTdHlsZSBzb3VyY2UsIHVubGVzcyB0aGUgbGF5ZXIgc3RhY2sgaGFzXG4gKiAgICBsYXllcnMgZnJvbSBkaWZmZXJlbnQgc291cmNlcyBpbiBiZXR3ZWVuLlxuICogICogYG1hcGJveC1sYXllcnNgOiBUaGUgYGlkYHMgb2YgdGhlIE1hcGJveCBTdHlsZSBkb2N1bWVudCdzIGxheWVycyB0aGF0IGFyZVxuICogICAgaW5jbHVkZWQgaW4gdGhlIE9wZW5MYXllcnMgbGF5ZXIuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBzZXRzIGFuIGFkZGl0aW9uYWwgYG1hcGJveC1zdHlsZWAgcHJvcGVydHkgb24gdGhlIE9wZW5MYXllcnNcbiAqIG1hcCBpbnN0YW5jZSwgd2hpY2ggaG9sZHMgdGhlIE1hcGJveCBTdHlsZSBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtQbHVnZ2FibGVNYXB8SFRNTEVsZW1lbnR8c3RyaW5nfSBtYXAgRWl0aGVyIGFuIGV4aXN0aW5nIE9wZW5MYXllcnMgTWFwXG4gKiBpbnN0YW5jZSwgb3IgYSBIVE1MIGVsZW1lbnQsIG9yIHRoZSBpZCBvZiBhIEhUTUwgZWxlbWVudCB0aGF0IHdpbGwgYmUgdGhlXG4gKiB0YXJnZXQgb2YgYSBuZXcgT3BlbkxheWVycyBNYXAuXG4gKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R9IHN0eWxlIEpTT04gc3R5bGUgb2JqZWN0IG9yIHN0eWxlIHVybCBwb2ludGluZyB0byBhXG4gKiBNYXBib3ggU3R5bGUgb2JqZWN0LiBXaGVuIHVzaW5nIE1hcGJveCBBUElzLCB0aGUgdXJsIG11c3QgY29udGFpbiBhbiBhY2Nlc3NcbiAqIHRva2VuIGFuZCBsb29rIGxpa2VcbiAqIGBodHRwczovL2FwaS5tYXBib3guY29tL3N0eWxlcy92MS9tYXBib3gvYnJpZ2h0LXY5P2FjY2Vzc190b2tlbj1beW91cl9hY2Nlc3NfdG9rZW5faGVyZV1gLlxuICogV2hlbiBwYXNzZWQgYXMgSlNPTiBzdHlsZSBvYmplY3QsIGFsbCBPcGVuTGF5ZXJzIGxheWVycyBjcmVhdGVkIGJ5IGBhcHBseSgpYFxuICogd2lsbCBiZSBpbW1lZGlhdGVseSBhdmFpbGFibGUsIGJ1dCB0aGV5IG1heSBub3QgaGF2ZSBhIHNvdXJjZSB5ZXQgKGkuZS4gd2hlblxuICogdGhleSBhcmUgZGVmaW5lZCBieSBhIFRpbGVKU09OIHVybCBpbiB0aGUgTWFwYm94IFN0eWxlIGRvY3VtZW50KS4gV2hlbiBwYXNzZWRcbiAqIGFzIHN0eWxlIHVybCwgbGF5ZXJzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIG1hcCB3aGVuIHRoZSBNYXBib3ggU3R5bGUgZG9jdW1lbnRcbiAqIGlzIGxvYWRlZCBhbmQgcGFyc2VkLlxuICogQHJldHVybiB7UHJvbWlzZX0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgYWZ0ZXIgYWxsIGxheWVycyBoYXZlIGJlZW4gYWRkZWQgdG9cbiAqIHRoZSBPcGVuTGF5ZXJzIE1hcCBpbnN0YW5jZSwgdGhlaXIgc291cmNlcyBzZXQsIGFuZCB0aGVpciBzdHlsZXMgYXBwbGllZC4gdGhlXG4gKiBgcmVzb2x2ZWAgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgd2l0aCB0aGUgT3BlbkxheWVycyBNYXAgaW5zdGFuY2UgYXNcbiAqIGFyZ3VtZW50LlxuICovXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gb2xtcyhtYXAsIHN0eWxlKSB7XG4gIHZhciBhY2Nlc3NUb2tlbiwgYmFzZVVybCwgaG9zdCwgcGF0aCwgcHJvbWlzZTtcbiAgYWNjZXNzVG9rZW4gPSBiYXNlVXJsID0gaG9zdCA9IHBhdGggPSAnJztcblxuICBpZiAodHlwZW9mIG1hcCA9PT0gJ3N0cmluZycgfHwgbWFwIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICBtYXAgPSBuZXcgTWFwKHtcbiAgICAgIHRhcmdldDogbWFwXG4gICAgfSk7XG4gIH1cblxuICBpZiAodHlwZW9mIHN0eWxlID09PSAnc3RyaW5nJykge1xuICAgIHZhciBwYXJ0cyA9IHN0eWxlLm1hdGNoKHNwcml0ZVJlZ0V4KTtcblxuICAgIGlmIChwYXJ0cykge1xuICAgICAgYmFzZVVybCA9IHBhcnRzWzFdO1xuICAgICAgYWNjZXNzVG9rZW4gPSBwYXJ0cy5sZW5ndGggPiAyID8gcGFydHNbMl0gOiAnJztcbiAgICB9XG5cbiAgICBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgZmV0Y2goc3R5bGUsIHtcbiAgICAgICAgY3JlZGVudGlhbHM6ICdzYW1lLW9yaWdpbidcbiAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XG4gICAgICB9KS50aGVuKGZ1bmN0aW9uIChnbFN0eWxlKSB7XG4gICAgICAgIHZhciBhID1cbiAgICAgICAgLyoqIEB0eXBlIHtIVE1MQW5jaG9yRWxlbWVudH0gKi9cbiAgICAgICAgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnQScpO1xuICAgICAgICBhLmhyZWYgPSBzdHlsZTtcbiAgICAgICAgdmFyIGhyZWYgPSBhLmhyZWY7XG4gICAgICAgIHBhdGggPSBhLnBhdGhuYW1lLnNwbGl0KCcvJykuc2xpY2UoMCwgLTEpLmpvaW4oJy8nKSArICcvJztcbiAgICAgICAgaG9zdCA9IGhyZWYuc3Vic3RyKDAsIGhyZWYuaW5kZXhPZihwYXRoKSk7XG4gICAgICAgIHByb2Nlc3NTdHlsZShnbFN0eWxlLCBtYXAsIGJhc2VVcmwsIGhvc3QsIHBhdGgsIGFjY2Vzc1Rva2VuKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXNvbHZlKG1hcCk7XG4gICAgICAgIH0pLmNhdGNoKHJlamVjdCk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoXCJDb3VsZCBub3QgbG9hZCBcIiArIHN0eWxlICsgXCI6IFwiICsgZXJyLm1lc3NhZ2UpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBwcm9jZXNzU3R5bGUoc3R5bGUsIG1hcCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlc29sdmUobWFwKTtcbiAgICAgIH0pLmNhdGNoKHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcHJvbWlzZTtcbn1cbi8qKlxuICogYGBganNcbiAqIGltcG9ydCB7YXBwbHl9IGZyb20gJ29sLW1hcGJveC1zdHlsZSc7XG4gKiBgYGBcbiAqIExpa2UgYG9sbXNgLCBidXQgcmV0dXJucyBhbiBgb2wvTWFwYCBpbnN0YW5jZSBpbnN0ZWFkIG9mIGEgYFByb21pc2VgLlxuICpcbiAqIEBwYXJhbSB7UGx1Z2dhYmxlTWFwfEhUTUxFbGVtZW50fHN0cmluZ30gbWFwIEVpdGhlciBhbiBleGlzdGluZyBPcGVuTGF5ZXJzIE1hcFxuICogaW5zdGFuY2UsIG9yIGEgSFRNTCBlbGVtZW50LCBvciB0aGUgaWQgb2YgYSBIVE1MIGVsZW1lbnQgdGhhdCB3aWxsIGJlIHRoZVxuICogdGFyZ2V0IG9mIGEgbmV3IE9wZW5MYXllcnMgTWFwLlxuICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBzdHlsZSBKU09OIHN0eWxlIG9iamVjdCBvciBzdHlsZSB1cmwgcG9pbnRpbmcgdG8gYVxuICogTWFwYm94IFN0eWxlIG9iamVjdC4gV2hlbiB1c2luZyBNYXBib3ggQVBJcywgdGhlIHVybCBtdXN0IGNvbnRhaW4gYW4gYWNjZXNzXG4gKiB0b2tlbiBhbmQgbG9vayBsaWtlXG4gKiBgaHR0cHM6Ly9hcGkubWFwYm94LmNvbS9zdHlsZXMvdjEvbWFwYm94L2JyaWdodC12OT9hY2Nlc3NfdG9rZW49W3lvdXJfYWNjZXNzX3Rva2VuX2hlcmVdYC5cbiAqIFdoZW4gcGFzc2VkIGFzIEpTT04gc3R5bGUgb2JqZWN0LCBhbGwgT3BlbkxheWVycyBsYXllcnMgY3JlYXRlZCBieSBgYXBwbHkoKWBcbiAqIHdpbGwgYmUgaW1tZWRpYXRlbHkgYXZhaWxhYmxlLCBidXQgdGhleSBtYXkgbm90IGhhdmUgYSBzb3VyY2UgeWV0IChpLmUuIHdoZW5cbiAqIHRoZXkgYXJlIGRlZmluZWQgYnkgYSBUaWxlSlNPTiB1cmwgaW4gdGhlIE1hcGJveCBTdHlsZSBkb2N1bWVudCkuIFdoZW4gcGFzc2VkXG4gKiBhcyBzdHlsZSB1cmwsIGxheWVycyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBtYXAgd2hlbiB0aGUgTWFwYm94IFN0eWxlIGRvY3VtZW50XG4gKiBpcyBsb2FkZWQgYW5kIHBhcnNlZC5cbiAqIEByZXR1cm4ge1BsdWdnYWJsZU1hcH0gVGhlIE9wZW5MYXllcnMgTWFwIGluc3RhbmNlIHRoYXQgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCB0aGVcbiAqIGNvbnRlbnRzIGRlc2NyaWJlZCBpbiB0aGUgTWFwYm94IFN0eWxlIG9iamVjdC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHkobWFwLCBzdHlsZSkge1xuICBpZiAodHlwZW9mIG1hcCA9PT0gJ3N0cmluZycgfHwgbWFwIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICBtYXAgPSBuZXcgTWFwKHtcbiAgICAgIHRhcmdldDogbWFwXG4gICAgfSk7XG4gIH1cblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBvbG1zKG1hcCwgc3R5bGUpO1xuICB9LCAwKTtcbiAgcmV0dXJuIG1hcDtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqIElmIGxheWVySWRzIGlzIG5vdCBlbXB0eSwgYXBwbGllcyB0aGUgc3R5bGUgc3BlY2lmaWVkIGluIGdsU3R5bGUgdG8gdGhlIGxheWVyLFxuICogYW5kIGFkZHMgdGhlIGxheWVyIHRvIHRoZSBtYXAuXG4gKlxuICogVGhlIGxheWVyIG1heSBub3QgeWV0IGhhdmUgYSBzb3VyY2Ugd2hlbiB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLiAgSWYgc28sIHRoZSBzdHlsZVxuICogaXMgYXBwbGllZCB0byB0aGUgbGF5ZXIgdmlhIGEgb25jZSBsaXN0ZW5lciBvbiB0aGUgJ2NoYW5nZTpzb3VyY2UnIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7TGF5ZXJ9IGxheWVyIEFuIE9wZW5MYXllcnMgbGF5ZXIgaW5zdGFuY2UuXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGxheWVySWRzIEFycmF5IGNvbnRhaW5pbmcgbGF5ZXIgaWRzIG9mIGFscmVhZHktcHJvY2Vzc2VkIGxheWVycy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBnbFN0eWxlIFN0eWxlIGFzIGEgSlNPTiBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ3x1bmRlZmluZWR9IHBhdGggVGhlIHBhdGggcGFydCBvZiB0aGUgc3R5bGUgVVJMLiBPbmx5IHJlcXVpcmVkXG4gKiB3aGVuIGEgcmVsYXRpdmUgcGF0aCBpcyB1c2VkIHdpdGggdGhlIGBcInNwcml0ZVwiYCBwcm9wZXJ0eSBvZiB0aGUgc3R5bGUuXG4gKiBAcGFyYW0ge1BsdWdnYWJsZU1hcH0gbWFwIE9wZW5MYXllcnMgTWFwLlxuICogQHJldHVybiB7UHJvbWlzZX0gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciB0aGUgc291cmNlIGhhc1xuICogYmVlbiBzZXQgb24gdGhlIHNwZWNpZmllZCBsYXllciwgYW5kIHRoZSBzdHlsZSBoYXMgYmVlbiBhcHBsaWVkLlxuICovXG5cbmZ1bmN0aW9uIGZpbmFsaXplTGF5ZXIobGF5ZXIsIGxheWVySWRzLCBnbFN0eWxlLCBwYXRoLCBtYXApIHtcbiAgdmFyIG1pblpvb20gPSAyNDtcbiAgdmFyIG1heFpvb20gPSAwO1xuICB2YXIgZ2xMYXllcnMgPSBnbFN0eWxlLmxheWVycztcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBnbExheWVycy5sZW5ndGg7IGkgPCBpaTsgKytpKSB7XG4gICAgdmFyIGdsTGF5ZXIgPSBnbExheWVyc1tpXTtcblxuICAgIGlmIChsYXllcklkcy5pbmRleE9mKGdsTGF5ZXIuaWQpICE9PSAtMSkge1xuICAgICAgbWluWm9vbSA9IE1hdGgubWluKCdtaW56b29tJyBpbiBnbExheWVyID8gZ2xMYXllci5taW56b29tIDogMCwgbWluWm9vbSk7XG4gICAgICBtYXhab29tID0gTWF0aC5tYXgoJ21heHpvb20nIGluIGdsTGF5ZXIgPyBnbExheWVyLm1heHpvb20gOiAyNCwgbWF4Wm9vbSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgc2V0U3R5bGUgPSBmdW5jdGlvbiBzZXRTdHlsZSgpIHtcbiAgICAgIHZhciBzb3VyY2UgPSBsYXllci5nZXRTb3VyY2UoKTtcblxuICAgICAgaWYgKCFzb3VyY2UgfHwgc291cmNlLmdldFN0YXRlKCkgPT09ICdlcnJvcicpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignRXJyb3IgYWNjZXNzaW5nIGRhdGEgZm9yIHNvdXJjZSAnICsgbGF5ZXIuZ2V0KCdtYXBib3gtc291cmNlJykpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHNvdXJjZS5nZXRUaWxlR3JpZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB2YXIgdGlsZUdyaWQgPSBzb3VyY2UuZ2V0VGlsZUdyaWQoKTtcblxuICAgICAgICBpZiAodGlsZUdyaWQpIHtcbiAgICAgICAgICB2YXIgc291cmNlTWluWm9vbSA9IHRpbGVHcmlkLmdldE1pblpvb20oKTtcblxuICAgICAgICAgIGlmIChtaW5ab29tID4gMCB8fCBzb3VyY2VNaW5ab29tID4gMCkge1xuICAgICAgICAgICAgbGF5ZXIuc2V0TWF4UmVzb2x1dGlvbihNYXRoLm1pbihkZWZhdWx0UmVzb2x1dGlvbnNbbWluWm9vbV0sIHRpbGVHcmlkLmdldFJlc29sdXRpb24oc291cmNlTWluWm9vbSkpICsgMWUtOSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG1heFpvb20gPCAyNCkge1xuICAgICAgICAgICAgbGF5ZXIuc2V0TWluUmVzb2x1dGlvbihkZWZhdWx0UmVzb2x1dGlvbnNbbWF4Wm9vbV0gKyAxZS05KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFZlY3RvclNvdXJjZSB8fCBzb3VyY2UgaW5zdGFuY2VvZiBWZWN0b3JUaWxlU291cmNlKSB7XG4gICAgICAgIGFwcGx5U3R5bGUoXG4gICAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwib2wvbGF5ZXIvVmVjdG9yXCIpLmRlZmF1bHR8aW1wb3J0KFwib2wvbGF5ZXIvVmVjdG9yVGlsZVwiKS5kZWZhdWx0fSAqL1xuICAgICAgICBsYXllciwgZ2xTdHlsZSwgbGF5ZXJJZHMsIHBhdGgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGxheWVyLnNldFZpc2libGUodHJ1ZSk7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGxheWVyLnNldCgnbWFwYm94LWxheWVycycsIGxheWVySWRzKTtcblxuICAgIGlmIChtYXAuZ2V0TGF5ZXJzKCkuZ2V0QXJyYXkoKS5pbmRleE9mKGxheWVyKSA9PT0gLTEpIHtcbiAgICAgIG1hcC5hZGRMYXllcihsYXllcik7XG4gICAgfVxuXG4gICAgaWYgKGxheWVyLmdldFNvdXJjZSgpKSB7XG4gICAgICBzZXRTdHlsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsYXllci5vbmNlKCdjaGFuZ2U6c291cmNlJywgc2V0U3R5bGUpO1xuICAgIH1cbiAgfSk7XG59XG4vKipcbiAqIGBgYGpzXG4gKiBpbXBvcnQge2dldExheWVyfSBmcm9tICdvbC1tYXBib3gtc3R5bGUnO1xuICogYGBgXG4gKiBHZXQgdGhlIE9wZW5MYXllcnMgbGF5ZXIgaW5zdGFuY2UgdGhhdCBjb250YWlucyB0aGUgcHJvdmlkZWQgTWFwYm94IFN0eWxlXG4gKiBgbGF5ZXJgLiBOb3RlIHRoYXQgbXVsdGlwbGUgTWFwYm94IFN0eWxlIGxheWVycyBhcmUgY29tYmluZWQgaW4gYSBzaW5nbGVcbiAqIE9wZW5MYXllcnMgbGF5ZXIgaW5zdGFuY2Ugd2hlbiB0aGV5IHVzZSB0aGUgc2FtZSBNYXBib3ggU3R5bGUgYHNvdXJjZWAuXG4gKiBAcGFyYW0ge1BsdWdnYWJsZU1hcH0gbWFwIE9wZW5MYXllcnMgTWFwLlxuICogQHBhcmFtIHtzdHJpbmd9IGxheWVySWQgTWFwYm94IFN0eWxlIGxheWVyIGlkLlxuICogQHJldHVybiB7TGF5ZXJ9IE9wZW5MYXllcnMgbGF5ZXIgaW5zdGFuY2UuXG4gKi9cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF5ZXIobWFwLCBsYXllcklkKSB7XG4gIHZhciBsYXllcnMgPSBtYXAuZ2V0TGF5ZXJzKCkuZ2V0QXJyYXkoKTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllcnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBtYXBib3hMYXllcnMgPSBsYXllcnNbaV0uZ2V0KCdtYXBib3gtbGF5ZXJzJyk7XG5cbiAgICBpZiAobWFwYm94TGF5ZXJzICYmIG1hcGJveExheWVycy5pbmRleE9mKGxheWVySWQpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgLyoqIEB0eXBlIHtMYXllcn0gKi9cbiAgICAgICAgbGF5ZXJzW2ldXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBgYGBqc1xuICogaW1wb3J0IHtnZXRMYXllcnN9IGZyb20gJ29sLW1hcGJveC1zdHlsZSc7XG4gKiBgYGBcbiAqIEdldCB0aGUgT3BlbkxheWVycyBsYXllciBpbnN0YW5jZXMgZm9yIHRoZSBwcm92aWRlZCBNYXBib3ggU3R5bGUgYHNvdXJjZWAuXG4gKiBAcGFyYW0ge1BsdWdnYWJsZU1hcH0gbWFwIE9wZW5MYXllcnMgTWFwLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZUlkIE1hcGJveCBTdHlsZSBzb3VyY2UgaWQuXG4gKiBAcmV0dXJuIHtBcnJheTxMYXllcj59IE9wZW5MYXllcnMgbGF5ZXIgaW5zdGFuY2VzLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMYXllcnMobWFwLCBzb3VyY2VJZCkge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBsYXllcnMgPSBtYXAuZ2V0TGF5ZXJzKCkuZ2V0QXJyYXkoKTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllcnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGlmIChsYXllcnNbaV0uZ2V0KCdtYXBib3gtc291cmNlJykgPT09IHNvdXJjZUlkKSB7XG4gICAgICByZXN1bHQucHVzaChcbiAgICAgIC8qKiBAdHlwZSB7TGF5ZXJ9ICovXG4gICAgICBsYXllcnNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4vKipcbiAqIGBgYGpzXG4gKiBpbXBvcnQge2dldFNvdXJjZX0gZnJvbSAnb2wtbWFwYm94LXN0eWxlJztcbiAqIGBgYFxuICogR2V0IHRoZSBPcGVuTGF5ZXJzIHNvdXJjZSBpbnN0YW5jZSBmb3IgdGhlIHByb3ZpZGVkIE1hcGJveCBTdHlsZSBgc291cmNlYC5cbiAqIEBwYXJhbSB7UGx1Z2dhYmxlTWFwfSBtYXAgT3BlbkxheWVycyBNYXAuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlSWQgTWFwYm94IFN0eWxlIHNvdXJjZSBpZC5cbiAqIEByZXR1cm4ge1NvdXJjZX0gT3BlbkxheWVycyBzb3VyY2UgaW5zdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNvdXJjZShtYXAsIHNvdXJjZUlkKSB7XG4gIHZhciBsYXllcnMgPSBtYXAuZ2V0TGF5ZXJzKCkuZ2V0QXJyYXkoKTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBsYXllcnMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIHZhciBzb3VyY2UgPVxuICAgIC8qKiBAdHlwZSB7TGF5ZXJ9ICovXG4gICAgbGF5ZXJzW2ldLmdldFNvdXJjZSgpO1xuXG4gICAgaWYgKGxheWVyc1tpXS5nZXQoJ21hcGJveC1zb3VyY2UnKSA9PT0gc291cmNlSWQpIHtcbiAgICAgIHJldHVybiBzb3VyY2U7XG4gICAgfVxuICB9XG59XG5leHBvcnQgeyBmaW5hbGl6ZUxheWVyIGFzIF9maW5hbGl6ZUxheWVyLCBnZXRGb250cyBhcyBfZ2V0Rm9udHMgfTsiLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB2YXIgcG9wdXBDb250YWluZXIgPSBcIm9wZW5sYXllcnNQb3B1cC1tb2R1bGUtLXBvcHVwQ29udGFpbmVyLS0xYUMtUFwiO1xuZXhwb3J0IHZhciBwb3B1cENsb3NlciA9IFwib3BlbmxheWVyc1BvcHVwLW1vZHVsZS0tcG9wdXBDbG9zZXItLTFiMDRnXCI7XG5leHBvcnQgdmFyIHBvcHVwQ29udGVudCA9IFwib3BlbmxheWVyc1BvcHVwLW1vZHVsZS0tcG9wdXBDb250ZW50LS0yeEF5dFwiOyIsIi8qKlxuICogQG1vZHVsZSBvbC9PdmVybGF5UG9zaXRpb25pbmdcbiAqL1xuXG4vKipcbiAqIE92ZXJsYXkgcG9zaXRpb246IGAnYm90dG9tLWxlZnQnYCwgYCdib3R0b20tY2VudGVyJ2AsICBgJ2JvdHRvbS1yaWdodCdgLFxuICogYCdjZW50ZXItbGVmdCdgLCBgJ2NlbnRlci1jZW50ZXInYCwgYCdjZW50ZXItcmlnaHQnYCwgYCd0b3AtbGVmdCdgLFxuICogYCd0b3AtY2VudGVyJ2AsIGAndG9wLXJpZ2h0J2BcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IHtcbiAgQk9UVE9NX0xFRlQ6ICdib3R0b20tbGVmdCcsXG4gIEJPVFRPTV9DRU5URVI6ICdib3R0b20tY2VudGVyJyxcbiAgQk9UVE9NX1JJR0hUOiAnYm90dG9tLXJpZ2h0JyxcbiAgQ0VOVEVSX0xFRlQ6ICdjZW50ZXItbGVmdCcsXG4gIENFTlRFUl9DRU5URVI6ICdjZW50ZXItY2VudGVyJyxcbiAgQ0VOVEVSX1JJR0hUOiAnY2VudGVyLXJpZ2h0JyxcbiAgVE9QX0xFRlQ6ICd0b3AtbGVmdCcsXG4gIFRPUF9DRU5URVI6ICd0b3AtY2VudGVyJyxcbiAgVE9QX1JJR0hUOiAndG9wLXJpZ2h0J1xufTsiLCJ2YXIgX19leHRlbmRzID0gdGhpcyAmJiB0aGlzLl9fZXh0ZW5kcyB8fCBmdW5jdGlvbiAoKSB7XG4gIHZhciBfZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIGV4dGVuZFN0YXRpY3MoZCwgYikge1xuICAgIF9leHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHtcbiAgICAgIF9fcHJvdG9fXzogW11cbiAgICB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICAgIGQuX19wcm90b19fID0gYjtcbiAgICB9IHx8IGZ1bmN0aW9uIChkLCBiKSB7XG4gICAgICBmb3IgKHZhciBwIGluIGIpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBfZXh0ZW5kU3RhdGljcyhkLCBiKTtcblxuICAgIGZ1bmN0aW9uIF9fKCkge1xuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7XG4gICAgfVxuXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xuICB9O1xufSgpO1xuLyoqXG4gKiBAbW9kdWxlIG9sL092ZXJsYXlcbiAqL1xuXG5cbmltcG9ydCBCYXNlT2JqZWN0LCB7IGdldENoYW5nZUV2ZW50VHlwZSB9IGZyb20gJy4vT2JqZWN0LmpzJztcbmltcG9ydCBNYXBFdmVudFR5cGUgZnJvbSAnLi9NYXBFdmVudFR5cGUuanMnO1xuaW1wb3J0IE92ZXJsYXlQb3NpdGlvbmluZyBmcm9tICcuL092ZXJsYXlQb3NpdGlvbmluZy5qcyc7XG5pbXBvcnQgeyBDTEFTU19TRUxFQ1RBQkxFIH0gZnJvbSAnLi9jc3MuanMnO1xuaW1wb3J0IHsgY29udGFpbnNFeHRlbnQgfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBsaXN0ZW4sIHVubGlzdGVuQnlLZXkgfSBmcm9tICcuL2V2ZW50cy5qcyc7XG5pbXBvcnQgeyBvdXRlckhlaWdodCwgb3V0ZXJXaWR0aCwgcmVtb3ZlQ2hpbGRyZW4sIHJlbW92ZU5vZGUgfSBmcm9tICcuL2RvbS5qcyc7XG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfHN0cmluZ30gW2lkXSBTZXQgdGhlIG92ZXJsYXkgaWQuIFRoZSBvdmVybGF5IGlkIGNhbiBiZSB1c2VkXG4gKiB3aXRoIHRoZSB7QGxpbmsgbW9kdWxlOm9sL01hcH5NYXAjZ2V0T3ZlcmxheUJ5SWR9IG1ldGhvZC5cbiAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR9IFtlbGVtZW50XSBUaGUgb3ZlcmxheSBlbGVtZW50LlxuICogQHByb3BlcnR5IHtBcnJheTxudW1iZXI+fSBbb2Zmc2V0PVswLCAwXV0gT2Zmc2V0cyBpbiBwaXhlbHMgdXNlZCB3aGVuIHBvc2l0aW9uaW5nXG4gKiB0aGUgb3ZlcmxheS4gVGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlXG4gKiBhcnJheSBpcyB0aGUgaG9yaXpvbnRhbCBvZmZzZXQuIEEgcG9zaXRpdmUgdmFsdWUgc2hpZnRzIHRoZSBvdmVybGF5IHJpZ2h0LlxuICogVGhlIHNlY29uZCBlbGVtZW50IGluIHRoZSBhcnJheSBpcyB0aGUgdmVydGljYWwgb2Zmc2V0LiBBIHBvc2l0aXZlIHZhbHVlXG4gKiBzaGlmdHMgdGhlIG92ZXJsYXkgZG93bi5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IFtwb3NpdGlvbl0gVGhlIG92ZXJsYXkgcG9zaXRpb25cbiAqIGluIG1hcCBwcm9qZWN0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL092ZXJsYXlQb3NpdGlvbmluZy5qc1wiKS5kZWZhdWx0fSBbcG9zaXRpb25pbmc9J3RvcC1sZWZ0J10gRGVmaW5lcyBob3dcbiAqIHRoZSBvdmVybGF5IGlzIGFjdHVhbGx5IHBvc2l0aW9uZWQgd2l0aCByZXNwZWN0IHRvIGl0cyBgcG9zaXRpb25gIHByb3BlcnR5LlxuICogUG9zc2libGUgdmFsdWVzIGFyZSBgJ2JvdHRvbS1sZWZ0J2AsIGAnYm90dG9tLWNlbnRlcidgLCBgJ2JvdHRvbS1yaWdodCdgLFxuICogYCdjZW50ZXItbGVmdCdgLCBgJ2NlbnRlci1jZW50ZXInYCwgYCdjZW50ZXItcmlnaHQnYCwgYCd0b3AtbGVmdCdgLFxuICogYCd0b3AtY2VudGVyJ2AsIGFuZCBgJ3RvcC1yaWdodCdgLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbc3RvcEV2ZW50PXRydWVdIFdoZXRoZXIgZXZlbnQgcHJvcGFnYXRpb24gdG8gdGhlIG1hcFxuICogdmlld3BvcnQgc2hvdWxkIGJlIHN0b3BwZWQuIElmIGB0cnVlYCB0aGUgb3ZlcmxheSBpcyBwbGFjZWQgaW4gdGhlIHNhbWVcbiAqIGNvbnRhaW5lciBhcyB0aGF0IG9mIHRoZSBjb250cm9scyAoQ1NTIGNsYXNzIG5hbWVcbiAqIGBvbC1vdmVybGF5Y29udGFpbmVyLXN0b3BldmVudGApOyBpZiBgZmFsc2VgIGl0IGlzIHBsYWNlZCBpbiB0aGUgY29udGFpbmVyXG4gKiB3aXRoIENTUyBjbGFzcyBuYW1lIHNwZWNpZmllZCBieSB0aGUgYGNsYXNzTmFtZWAgcHJvcGVydHkuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtpbnNlcnRGaXJzdD10cnVlXSBXaGV0aGVyIHRoZSBvdmVybGF5IGlzIGluc2VydGVkIGZpcnN0XG4gKiBpbiB0aGUgb3ZlcmxheSBjb250YWluZXIsIG9yIGFwcGVuZGVkLiBJZiB0aGUgb3ZlcmxheSBpcyBwbGFjZWQgaW4gdGhlIHNhbWVcbiAqIGNvbnRhaW5lciBhcyB0aGF0IG9mIHRoZSBjb250cm9scyAoc2VlIHRoZSBgc3RvcEV2ZW50YCBvcHRpb24pIHlvdSB3aWxsXG4gKiBwcm9iYWJseSBzZXQgYGluc2VydEZpcnN0YCB0byBgdHJ1ZWAgc28gdGhlIG92ZXJsYXkgaXMgZGlzcGxheWVkIGJlbG93IHRoZVxuICogY29udHJvbHMuXG4gKiBAcHJvcGVydHkge1BhbkludG9WaWV3T3B0aW9uc3xib29sZWFufSBbYXV0b1Bhbj1mYWxzZV0gUGFuIHRoZSBtYXAgd2hlbiBjYWxsaW5nXG4gKiBgc2V0UG9zaXRpb25gLCBzbyB0aGF0IHRoZSBvdmVybGF5IGlzIGVudGlyZWx5IHZpc2libGUgaW4gdGhlIGN1cnJlbnQgdmlld3BvcnQ/XG4gKiBJZiBgdHJ1ZWAgKGRlcHJlY2F0ZWQpLCB0aGVuIGBhdXRvUGFuQW5pbWF0aW9uYCBhbmQgYGF1dG9QYW5NYXJnaW5gIHdpbGwgYmVcbiAqIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBwYW5uaW5nIHBhcmFtZXRlcnM7IGlmIGFuIG9iamVjdCBpcyBzdXBwbGllZCB0aGVuIG90aGVyXG4gKiBwYXJhbWV0ZXJzIGFyZSBpZ25vcmVkLlxuICogQHByb3BlcnR5IHtQYW5PcHRpb25zfSBbYXV0b1BhbkFuaW1hdGlvbl0gVGhlIGFuaW1hdGlvbiBvcHRpb25zIHVzZWQgdG8gcGFuXG4gKiB0aGUgb3ZlcmxheSBpbnRvIHZpZXcuIFRoaXMgYW5pbWF0aW9uIGlzIG9ubHkgdXNlZCB3aGVuIGBhdXRvUGFuYCBpcyBlbmFibGVkLlxuICogQSBgZHVyYXRpb25gIGFuZCBgZWFzaW5nYCBtYXkgYmUgcHJvdmlkZWQgdG8gY3VzdG9taXplIHRoZSBhbmltYXRpb24uXG4gKiBEZXByZWNhdGVkIGFuZCBpZ25vcmVkIGlmIGBhdXRvUGFuYCBpcyBzdXBwbGllZCBhcyBhbiBvYmplY3QuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2F1dG9QYW5NYXJnaW49MjBdIFRoZSBtYXJnaW4gKGluIHBpeGVscykgYmV0d2VlbiB0aGVcbiAqIG92ZXJsYXkgYW5kIHRoZSBib3JkZXJzIG9mIHRoZSBtYXAgd2hlbiBhdXRvcGFubmluZy4gRGVwcmVjYXRlZCBhbmQgaWdub3JlZFxuICogaWYgYGF1dG9QYW5gIGlzIHN1cHBsaWVkIGFzIGFuIG9iamVjdC5cbiAqIEBwcm9wZXJ0eSB7UGFuSW50b1ZpZXdPcHRpb25zfSBbYXV0b1Bhbk9wdGlvbnNdIFRoZSBvcHRpb25zIHRvIHVzZSBmb3IgdGhlXG4gKiBhdXRvUGFuLiBUaGlzIGlzIG9ubHkgdXNlZCB3aGVuIGBhdXRvUGFuYCBpcyBlbmFibGVkIGFuZCBoYXMgcHJlZmVyZW5jZSBvdmVyXG4gKiB0aGUgaW5kaXZpZHVhbCBgYXV0b1Bhbk1hcmdpbmAgYW5kIGBhdXRvUGFuT3B0aW9uc2AuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NsYXNzTmFtZT0nb2wtb3ZlcmxheS1jb250YWluZXIgb2wtc2VsZWN0YWJsZSddIENTUyBjbGFzc1xuICogbmFtZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBhbk9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbZHVyYXRpb249MTAwMF0gVGhlIGR1cmF0aW9uIG9mIHRoZSBhbmltYXRpb24gaW5cbiAqIG1pbGxpc2Vjb25kcy5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTpudW1iZXJ9IFtlYXNpbmddIFRoZSBlYXNpbmcgZnVuY3Rpb24gdG8gdXNlLiBDYW5cbiAqIGJlIG9uZSBmcm9tIHtAbGluayBtb2R1bGU6b2wvZWFzaW5nfSBvciBhIGN1c3RvbSBmdW5jdGlvbi5cbiAqIERlZmF1bHQgaXMge0BsaW5rIG1vZHVsZTpvbC9lYXNpbmd+aW5BbmRPdXR9LlxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gUGFuSW50b1ZpZXdPcHRpb25zXG4gKiBAcHJvcGVydHkge1Bhbk9wdGlvbnN9IFthbmltYXRpb249e31dIFRoZSBhbmltYXRpb24gcGFyYW1ldGVycyBmb3IgdGhlIHBhblxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttYXJnaW49MjBdIFRoZSBtYXJnaW4gKGluIHBpeGVscykgYmV0d2VlbiB0aGVcbiAqIG92ZXJsYXkgYW5kIHRoZSBib3JkZXJzIG9mIHRoZSBtYXAgd2hlbiBwYW5uaW5nIGludG8gdmlldy5cbiAqL1xuXG4vKipcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcHJvdGVjdGVkXG4gKi9cblxudmFyIFByb3BlcnR5ID0ge1xuICBFTEVNRU5UOiAnZWxlbWVudCcsXG4gIE1BUDogJ21hcCcsXG4gIE9GRlNFVDogJ29mZnNldCcsXG4gIFBPU0lUSU9OOiAncG9zaXRpb24nLFxuICBQT1NJVElPTklORzogJ3Bvc2l0aW9uaW5nJ1xufTtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogQW4gZWxlbWVudCB0byBiZSBkaXNwbGF5ZWQgb3ZlciB0aGUgbWFwIGFuZCBhdHRhY2hlZCB0byBhIHNpbmdsZSBtYXBcbiAqIGxvY2F0aW9uLiAgTGlrZSB7QGxpbmsgbW9kdWxlOm9sL2NvbnRyb2wvQ29udHJvbH5Db250cm9sfSwgT3ZlcmxheXMgYXJlXG4gKiB2aXNpYmxlIHdpZGdldHMuIFVubGlrZSBDb250cm9scywgdGhleSBhcmUgbm90IGluIGEgZml4ZWQgcG9zaXRpb24gb24gdGhlXG4gKiBzY3JlZW4sIGJ1dCBhcmUgdGllZCB0byBhIGdlb2dyYXBoaWNhbCBjb29yZGluYXRlLCBzbyBwYW5uaW5nIHRoZSBtYXAgd2lsbFxuICogbW92ZSBhbiBPdmVybGF5IGJ1dCBub3QgYSBDb250cm9sLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCBPdmVybGF5IGZyb20gJ29sL092ZXJsYXknO1xuICpcbiAqICAgICB2YXIgcG9wdXAgPSBuZXcgT3ZlcmxheSh7XG4gKiAgICAgICBlbGVtZW50OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncG9wdXAnKVxuICogICAgIH0pO1xuICogICAgIHBvcHVwLnNldFBvc2l0aW9uKGNvb3JkaW5hdGUpO1xuICogICAgIG1hcC5hZGRPdmVybGF5KHBvcHVwKTtcbiAqXG4gKiBAYXBpXG4gKi9cblxudmFyIE92ZXJsYXkgPVxuLyoqIEBjbGFzcyAqL1xuZnVuY3Rpb24gKF9zdXBlcikge1xuICBfX2V4dGVuZHMoT3ZlcmxheSwgX3N1cGVyKTtcbiAgLyoqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9ucyBPdmVybGF5IG9wdGlvbnMuXG4gICAqL1xuXG5cbiAgZnVuY3Rpb24gT3ZlcmxheShvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcykgfHwgdGhpcztcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge09wdGlvbnN9XG4gICAgICovXG5cblxuICAgIF90aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7bnVtYmVyfHN0cmluZ3x1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICBfdGhpcy5pZCA9IG9wdGlvbnMuaWQ7XG4gICAgLyoqXG4gICAgICogQHByb3RlY3RlZFxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuXG4gICAgX3RoaXMuaW5zZXJ0Rmlyc3QgPSBvcHRpb25zLmluc2VydEZpcnN0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmluc2VydEZpcnN0IDogdHJ1ZTtcbiAgICAvKipcbiAgICAgKiBAcHJvdGVjdGVkXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICBfdGhpcy5zdG9wRXZlbnQgPSBvcHRpb25zLnN0b3BFdmVudCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5zdG9wRXZlbnQgOiB0cnVlO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7SFRNTEVsZW1lbnR9XG4gICAgICovXG5cbiAgICBfdGhpcy5lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgX3RoaXMuZWxlbWVudC5jbGFzc05hbWUgPSBvcHRpb25zLmNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbGFzc05hbWUgOiAnb2wtb3ZlcmxheS1jb250YWluZXIgJyArIENMQVNTX1NFTEVDVEFCTEU7XG4gICAgX3RoaXMuZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgX3RoaXMuZWxlbWVudC5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgIHZhciBhdXRvUGFuID0gb3B0aW9ucy5hdXRvUGFuO1xuXG4gICAgaWYgKGF1dG9QYW4gJiYgJ29iamVjdCcgIT09IHR5cGVvZiBhdXRvUGFuKSB7XG4gICAgICBhdXRvUGFuID0ge1xuICAgICAgICBhbmltYXRpb246IG9wdGlvbnMuYXV0b1BhbkFuaW1hdGlvbixcbiAgICAgICAgbWFyZ2luOiBvcHRpb25zLmF1dG9QYW5NYXJnaW5cbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7UGFuSW50b1ZpZXdPcHRpb25zfGZhbHNlfVxuICAgICAqL1xuXG5cbiAgICBfdGhpcy5hdXRvUGFuID1cbiAgICAvKiogQHR5cGUge1BhbkludG9WaWV3T3B0aW9uc30gKi9cbiAgICBhdXRvUGFuIHx8IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7e3RyYW5zZm9ybV86IHN0cmluZyxcbiAgICAgKiAgICAgICAgIHZpc2libGU6IGJvb2xlYW59fVxuICAgICAqL1xuXG4gICAgX3RoaXMucmVuZGVyZWQgPSB7XG4gICAgICB0cmFuc2Zvcm1fOiAnJyxcbiAgICAgIHZpc2libGU6IHRydWVcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgKiBAdHlwZSB7P2ltcG9ydChcIi4vZXZlbnRzLmpzXCIpLkV2ZW50c0tleX1cbiAgICAgKi9cblxuICAgIF90aGlzLm1hcFBvc3RyZW5kZXJMaXN0ZW5lcktleSA9IG51bGw7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShQcm9wZXJ0eS5FTEVNRU5UKSwgX3RoaXMuaGFuZGxlRWxlbWVudENoYW5nZWQpO1xuXG4gICAgX3RoaXMuYWRkRXZlbnRMaXN0ZW5lcihnZXRDaGFuZ2VFdmVudFR5cGUoUHJvcGVydHkuTUFQKSwgX3RoaXMuaGFuZGxlTWFwQ2hhbmdlZCk7XG5cbiAgICBfdGhpcy5hZGRFdmVudExpc3RlbmVyKGdldENoYW5nZUV2ZW50VHlwZShQcm9wZXJ0eS5PRkZTRVQpLCBfdGhpcy5oYW5kbGVPZmZzZXRDaGFuZ2VkKTtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKFByb3BlcnR5LlBPU0lUSU9OKSwgX3RoaXMuaGFuZGxlUG9zaXRpb25DaGFuZ2VkKTtcblxuICAgIF90aGlzLmFkZEV2ZW50TGlzdGVuZXIoZ2V0Q2hhbmdlRXZlbnRUeXBlKFByb3BlcnR5LlBPU0lUSU9OSU5HKSwgX3RoaXMuaGFuZGxlUG9zaXRpb25pbmdDaGFuZ2VkKTtcblxuICAgIGlmIChvcHRpb25zLmVsZW1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgX3RoaXMuc2V0RWxlbWVudChvcHRpb25zLmVsZW1lbnQpO1xuICAgIH1cblxuICAgIF90aGlzLnNldE9mZnNldChvcHRpb25zLm9mZnNldCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5vZmZzZXQgOiBbMCwgMF0pO1xuXG4gICAgX3RoaXMuc2V0UG9zaXRpb25pbmcob3B0aW9ucy5wb3NpdGlvbmluZyAhPT0gdW5kZWZpbmVkID9cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vT3ZlcmxheVBvc2l0aW9uaW5nLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgb3B0aW9ucy5wb3NpdGlvbmluZyA6IE92ZXJsYXlQb3NpdGlvbmluZy5UT1BfTEVGVCk7XG5cbiAgICBpZiAob3B0aW9ucy5wb3NpdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBfdGhpcy5zZXRQb3NpdGlvbihvcHRpb25zLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgRE9NIGVsZW1lbnQgb2YgdGhpcyBvdmVybGF5LlxuICAgKiBAcmV0dXJuIHtIVE1MRWxlbWVudHx1bmRlZmluZWR9IFRoZSBFbGVtZW50IGNvbnRhaW5pbmcgdGhlIG92ZXJsYXkuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5nZXRFbGVtZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge0hUTUxFbGVtZW50fHVuZGVmaW5lZH0gKi9cbiAgICAgIHRoaXMuZ2V0KFByb3BlcnR5LkVMRU1FTlQpXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgb3ZlcmxheSBpZGVudGlmaWVyIHdoaWNoIGlzIHNldCBvbiBjb25zdHJ1Y3Rvci5cbiAgICogQHJldHVybiB7bnVtYmVyfHN0cmluZ3x1bmRlZmluZWR9IElkLlxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0SWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWQ7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hcCBhc3NvY2lhdGVkIHdpdGggdGhpcyBvdmVybGF5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL1BsdWdnYWJsZU1hcC5qc1wiKS5kZWZhdWx0fHVuZGVmaW5lZH0gVGhlIG1hcCB0aGF0IHRoZVxuICAgKiBvdmVybGF5IGlzIHBhcnQgb2YuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5nZXRNYXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9QbHVnZ2FibGVNYXAuanNcIikuZGVmYXVsdHx1bmRlZmluZWR9ICovXG4gICAgICB0aGlzLmdldChQcm9wZXJ0eS5NQVApXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgb2Zmc2V0IG9mIHRoaXMgb3ZlcmxheS5cbiAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gVGhlIG9mZnNldC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldE9mZnNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgLyoqIEB0eXBlIHtBcnJheTxudW1iZXI+fSAqL1xuICAgICAgdGhpcy5nZXQoUHJvcGVydHkuT0ZGU0VUKVxuICAgICk7XG4gIH07XG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhpcyBvdmVybGF5LlxuICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IFRoZSBzcGF0aWFsIHBvaW50IHRoYXQgdGhlIG92ZXJsYXkgaXNcbiAgICogICAgIGFuY2hvcmVkIGF0LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV8dW5kZWZpbmVkfSAqL1xuICAgICAgdGhpcy5nZXQoUHJvcGVydHkuUE9TSVRJT04pXG4gICAgKTtcbiAgfTtcbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVudCBwb3NpdGlvbmluZyBvZiB0aGlzIG92ZXJsYXkuXG4gICAqIEByZXR1cm4ge2ltcG9ydChcIi4vT3ZlcmxheVBvc2l0aW9uaW5nLmpzXCIpLmRlZmF1bHR9IEhvdyB0aGUgb3ZlcmxheSBpcyBwb3NpdGlvbmVkXG4gICAqICAgICByZWxhdGl2ZSB0byBpdHMgcG9pbnQgb24gdGhlIG1hcC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmdldFBvc2l0aW9uaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vT3ZlcmxheVBvc2l0aW9uaW5nLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgICB0aGlzLmdldChQcm9wZXJ0eS5QT1NJVElPTklORylcbiAgICApO1xuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmhhbmRsZUVsZW1lbnRDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHJlbW92ZUNoaWxkcmVuKHRoaXMuZWxlbWVudCk7XG4gICAgdmFyIGVsZW1lbnQgPSB0aGlzLmdldEVsZW1lbnQoKTtcblxuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICB0aGlzLmVsZW1lbnQuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmhhbmRsZU1hcENoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMubWFwUG9zdHJlbmRlckxpc3RlbmVyS2V5KSB7XG4gICAgICByZW1vdmVOb2RlKHRoaXMuZWxlbWVudCk7XG4gICAgICB1bmxpc3RlbkJ5S2V5KHRoaXMubWFwUG9zdHJlbmRlckxpc3RlbmVyS2V5KTtcbiAgICAgIHRoaXMubWFwUG9zdHJlbmRlckxpc3RlbmVyS2V5ID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgbWFwID0gdGhpcy5nZXRNYXAoKTtcblxuICAgIGlmIChtYXApIHtcbiAgICAgIHRoaXMubWFwUG9zdHJlbmRlckxpc3RlbmVyS2V5ID0gbGlzdGVuKG1hcCwgTWFwRXZlbnRUeXBlLlBPU1RSRU5ERVIsIHRoaXMucmVuZGVyLCB0aGlzKTtcbiAgICAgIHRoaXMudXBkYXRlUGl4ZWxQb3NpdGlvbigpO1xuICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuc3RvcEV2ZW50ID8gbWFwLmdldE92ZXJsYXlDb250YWluZXJTdG9wRXZlbnQoKSA6IG1hcC5nZXRPdmVybGF5Q29udGFpbmVyKCk7XG5cbiAgICAgIGlmICh0aGlzLmluc2VydEZpcnN0KSB7XG4gICAgICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUodGhpcy5lbGVtZW50LCBjb250YWluZXIuY2hpbGROb2Rlc1swXSB8fCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBlcmZvcm1BdXRvUGFuKCk7XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVwZGF0ZVBpeGVsUG9zaXRpb24oKTtcbiAgfTtcbiAgLyoqXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5oYW5kbGVPZmZzZXRDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudXBkYXRlUGl4ZWxQb3NpdGlvbigpO1xuICB9O1xuICAvKipcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLmhhbmRsZVBvc2l0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnVwZGF0ZVBpeGVsUG9zaXRpb24oKTtcbiAgICB0aGlzLnBlcmZvcm1BdXRvUGFuKCk7XG4gIH07XG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuaGFuZGxlUG9zaXRpb25pbmdDaGFuZ2VkID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudXBkYXRlUGl4ZWxQb3NpdGlvbigpO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBET00gZWxlbWVudCB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBvdmVybGF5LlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fHVuZGVmaW5lZH0gZWxlbWVudCBUaGUgRWxlbWVudCBjb250YWluaW5nIHRoZSBvdmVybGF5LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuc2V0RWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuRUxFTUVOVCwgZWxlbWVudCk7XG4gIH07XG4gIC8qKlxuICAgKiBTZXQgdGhlIG1hcCB0byBiZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBvdmVybGF5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vUGx1Z2dhYmxlTWFwLmpzXCIpLmRlZmF1bHR8dW5kZWZpbmVkfSBtYXAgVGhlIG1hcCB0aGF0IHRoZVxuICAgKiBvdmVybGF5IGlzIHBhcnQgb2YuXG4gICAqIEBvYnNlcnZhYmxlXG4gICAqIEBhcGlcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS5zZXRNYXAgPSBmdW5jdGlvbiAobWFwKSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuTUFQLCBtYXApO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBvZmZzZXQgZm9yIHRoaXMgb3ZlcmxheS5cbiAgICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBvZmZzZXQgT2Zmc2V0LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuc2V0T2Zmc2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICAgIHRoaXMuc2V0KFByb3BlcnR5Lk9GRlNFVCwgb2Zmc2V0KTtcbiAgfTtcbiAgLyoqXG4gICAqIFNldCB0aGUgcG9zaXRpb24gZm9yIHRoaXMgb3ZlcmxheS4gSWYgdGhlIHBvc2l0aW9uIGlzIGB1bmRlZmluZWRgIHRoZVxuICAgKiBvdmVybGF5IGlzIGhpZGRlbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZXx1bmRlZmluZWR9IHBvc2l0aW9uIFRoZSBzcGF0aWFsIHBvaW50IHRoYXQgdGhlIG92ZXJsYXlcbiAgICogICAgIGlzIGFuY2hvcmVkIGF0LlxuICAgKiBAb2JzZXJ2YWJsZVxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAocG9zaXRpb24pIHtcbiAgICB0aGlzLnNldChQcm9wZXJ0eS5QT1NJVElPTiwgcG9zaXRpb24pO1xuICB9O1xuICAvKipcbiAgICogUGFuIHRoZSBtYXAgc28gdGhhdCB0aGUgb3ZlcmxheSBpcyBlbnRpcmVseSB2aXNpc2JsZSBpbiB0aGUgY3VycmVudCB2aWV3cG9ydFxuICAgKiAoaWYgbmVjZXNzYXJ5KSB1c2luZyB0aGUgY29uZmlndXJlZCBhdXRvUGFuIHBhcmFtZXRlcnNcbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnBlcmZvcm1BdXRvUGFuID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmF1dG9QYW4pIHtcbiAgICAgIHRoaXMucGFuSW50b1ZpZXcodGhpcy5hdXRvUGFuKTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBQYW4gdGhlIG1hcCBzbyB0aGF0IHRoZSBvdmVybGF5IGlzIGVudGlyZWx5IHZpc2libGUgaW4gdGhlIGN1cnJlbnQgdmlld3BvcnRcbiAgICogKGlmIG5lY2Vzc2FyeSkuXG4gICAqIEBwYXJhbSB7UGFuSW50b1ZpZXdPcHRpb25zPX0gb3B0X3BhbkludG9WaWV3T3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcGFuIGFjdGlvblxuICAgKiBAYXBpXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUucGFuSW50b1ZpZXcgPSBmdW5jdGlvbiAob3B0X3BhbkludG9WaWV3T3B0aW9ucykge1xuICAgIHZhciBtYXAgPSB0aGlzLmdldE1hcCgpO1xuXG4gICAgaWYgKCFtYXAgfHwgIW1hcC5nZXRUYXJnZXRFbGVtZW50KCkgfHwgIXRoaXMuZ2V0KFByb3BlcnR5LlBPU0lUSU9OKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBtYXBSZWN0ID0gdGhpcy5nZXRSZWN0KG1hcC5nZXRUYXJnZXRFbGVtZW50KCksIG1hcC5nZXRTaXplKCkpO1xuICAgIHZhciBlbGVtZW50ID0gdGhpcy5nZXRFbGVtZW50KCk7XG4gICAgdmFyIG92ZXJsYXlSZWN0ID0gdGhpcy5nZXRSZWN0KGVsZW1lbnQsIFtvdXRlcldpZHRoKGVsZW1lbnQpLCBvdXRlckhlaWdodChlbGVtZW50KV0pO1xuICAgIHZhciBwYW5JbnRvVmlld09wdGlvbnMgPSBvcHRfcGFuSW50b1ZpZXdPcHRpb25zIHx8IHt9O1xuICAgIHZhciBteU1hcmdpbiA9IHBhbkludG9WaWV3T3B0aW9ucy5tYXJnaW4gPT09IHVuZGVmaW5lZCA/IDIwIDogcGFuSW50b1ZpZXdPcHRpb25zLm1hcmdpbjtcblxuICAgIGlmICghY29udGFpbnNFeHRlbnQobWFwUmVjdCwgb3ZlcmxheVJlY3QpKSB7XG4gICAgICAvLyB0aGUgb3ZlcmxheSBpcyBub3QgY29tcGxldGVseSBpbnNpZGUgdGhlIHZpZXdwb3J0LCBzbyBwYW4gdGhlIG1hcFxuICAgICAgdmFyIG9mZnNldExlZnQgPSBvdmVybGF5UmVjdFswXSAtIG1hcFJlY3RbMF07XG4gICAgICB2YXIgb2Zmc2V0UmlnaHQgPSBtYXBSZWN0WzJdIC0gb3ZlcmxheVJlY3RbMl07XG4gICAgICB2YXIgb2Zmc2V0VG9wID0gb3ZlcmxheVJlY3RbMV0gLSBtYXBSZWN0WzFdO1xuICAgICAgdmFyIG9mZnNldEJvdHRvbSA9IG1hcFJlY3RbM10gLSBvdmVybGF5UmVjdFszXTtcbiAgICAgIHZhciBkZWx0YSA9IFswLCAwXTtcblxuICAgICAgaWYgKG9mZnNldExlZnQgPCAwKSB7XG4gICAgICAgIC8vIG1vdmUgbWFwIHRvIHRoZSBsZWZ0XG4gICAgICAgIGRlbHRhWzBdID0gb2Zmc2V0TGVmdCAtIG15TWFyZ2luO1xuICAgICAgfSBlbHNlIGlmIChvZmZzZXRSaWdodCA8IDApIHtcbiAgICAgICAgLy8gbW92ZSBtYXAgdG8gdGhlIHJpZ2h0XG4gICAgICAgIGRlbHRhWzBdID0gTWF0aC5hYnMob2Zmc2V0UmlnaHQpICsgbXlNYXJnaW47XG4gICAgICB9XG5cbiAgICAgIGlmIChvZmZzZXRUb3AgPCAwKSB7XG4gICAgICAgIC8vIG1vdmUgbWFwIHVwXG4gICAgICAgIGRlbHRhWzFdID0gb2Zmc2V0VG9wIC0gbXlNYXJnaW47XG4gICAgICB9IGVsc2UgaWYgKG9mZnNldEJvdHRvbSA8IDApIHtcbiAgICAgICAgLy8gbW92ZSBtYXAgZG93blxuICAgICAgICBkZWx0YVsxXSA9IE1hdGguYWJzKG9mZnNldEJvdHRvbSkgKyBteU1hcmdpbjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRlbHRhWzBdICE9PSAwIHx8IGRlbHRhWzFdICE9PSAwKSB7XG4gICAgICAgIHZhciBjZW50ZXIgPVxuICAgICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSAqL1xuICAgICAgICBtYXAuZ2V0VmlldygpLmdldENlbnRlckludGVybmFsKCk7XG4gICAgICAgIHZhciBjZW50ZXJQeCA9IG1hcC5nZXRQaXhlbEZyb21Db29yZGluYXRlSW50ZXJuYWwoY2VudGVyKTtcblxuICAgICAgICBpZiAoIWNlbnRlclB4KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG5ld0NlbnRlclB4ID0gW2NlbnRlclB4WzBdICsgZGVsdGFbMF0sIGNlbnRlclB4WzFdICsgZGVsdGFbMV1dO1xuICAgICAgICB2YXIgcGFuT3B0aW9ucyA9IHBhbkludG9WaWV3T3B0aW9ucy5hbmltYXRpb24gfHwge307XG4gICAgICAgIG1hcC5nZXRWaWV3KCkuYW5pbWF0ZUludGVybmFsKHtcbiAgICAgICAgICBjZW50ZXI6IG1hcC5nZXRDb29yZGluYXRlRnJvbVBpeGVsSW50ZXJuYWwobmV3Q2VudGVyUHgpLFxuICAgICAgICAgIGR1cmF0aW9uOiBwYW5PcHRpb25zLmR1cmF0aW9uLFxuICAgICAgICAgIGVhc2luZzogcGFuT3B0aW9ucy5lYXNpbmdcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICAvKipcbiAgICogR2V0IHRoZSBleHRlbnQgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byB0aGUgZG9jdW1lbnRcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCBUaGUgZWxlbWVudC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZX0gc2l6ZSBUaGUgc2l6ZSBvZiB0aGUgZWxlbWVudC5cbiAgICogQHJldHVybiB7aW1wb3J0KFwiLi9leHRlbnQuanNcIikuRXh0ZW50fSBUaGUgZXh0ZW50LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0UmVjdCA9IGZ1bmN0aW9uIChlbGVtZW50LCBzaXplKSB7XG4gICAgdmFyIGJveCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIG9mZnNldFggPSBib3gubGVmdCArIHdpbmRvdy5wYWdlWE9mZnNldDtcbiAgICB2YXIgb2Zmc2V0WSA9IGJveC50b3AgKyB3aW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgcmV0dXJuIFtvZmZzZXRYLCBvZmZzZXRZLCBvZmZzZXRYICsgc2l6ZVswXSwgb2Zmc2V0WSArIHNpemVbMV1dO1xuICB9O1xuICAvKipcbiAgICogU2V0IHRoZSBwb3NpdGlvbmluZyBmb3IgdGhpcyBvdmVybGF5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vT3ZlcmxheVBvc2l0aW9uaW5nLmpzXCIpLmRlZmF1bHR9IHBvc2l0aW9uaW5nIGhvdyB0aGUgb3ZlcmxheSBpc1xuICAgKiAgICAgcG9zaXRpb25lZCByZWxhdGl2ZSB0byBpdHMgcG9pbnQgb24gdGhlIG1hcC5cbiAgICogQG9ic2VydmFibGVcbiAgICogQGFwaVxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnNldFBvc2l0aW9uaW5nID0gZnVuY3Rpb24gKHBvc2l0aW9uaW5nKSB7XG4gICAgdGhpcy5zZXQoUHJvcGVydHkuUE9TSVRJT05JTkcsIHBvc2l0aW9uaW5nKTtcbiAgfTtcbiAgLyoqXG4gICAqIE1vZGlmeSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgZWxlbWVudC5cbiAgICogQHBhcmFtIHtib29sZWFufSB2aXNpYmxlIEVsZW1lbnQgdmlzaWJpbGl0eS5cbiAgICogQHByb3RlY3RlZFxuICAgKi9cblxuXG4gIE92ZXJsYXkucHJvdG90eXBlLnNldFZpc2libGUgPSBmdW5jdGlvbiAodmlzaWJsZSkge1xuICAgIGlmICh0aGlzLnJlbmRlcmVkLnZpc2libGUgIT09IHZpc2libGUpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA/ICcnIDogJ25vbmUnO1xuICAgICAgdGhpcy5yZW5kZXJlZC52aXNpYmxlID0gdmlzaWJsZTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiBVcGRhdGUgcGl4ZWwgcG9zaXRpb24uXG4gICAqIEBwcm90ZWN0ZWRcbiAgICovXG5cblxuICBPdmVybGF5LnByb3RvdHlwZS51cGRhdGVQaXhlbFBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtYXAgPSB0aGlzLmdldE1hcCgpO1xuICAgIHZhciBwb3NpdGlvbiA9IHRoaXMuZ2V0UG9zaXRpb24oKTtcblxuICAgIGlmICghbWFwIHx8ICFtYXAuaXNSZW5kZXJlZCgpIHx8ICFwb3NpdGlvbikge1xuICAgICAgdGhpcy5zZXRWaXNpYmxlKGZhbHNlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcGl4ZWwgPSBtYXAuZ2V0UGl4ZWxGcm9tQ29vcmRpbmF0ZShwb3NpdGlvbik7XG4gICAgdmFyIG1hcFNpemUgPSBtYXAuZ2V0U2l6ZSgpO1xuICAgIHRoaXMudXBkYXRlUmVuZGVyZWRQb3NpdGlvbihwaXhlbCwgbWFwU2l6ZSk7XG4gIH07XG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcGl4ZWwuanNcIikuUGl4ZWx9IHBpeGVsIFRoZSBwaXhlbCBsb2NhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3NpemUuanNcIikuU2l6ZXx1bmRlZmluZWR9IG1hcFNpemUgVGhlIG1hcCBzaXplLlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUudXBkYXRlUmVuZGVyZWRQb3NpdGlvbiA9IGZ1bmN0aW9uIChwaXhlbCwgbWFwU2l6ZSkge1xuICAgIHZhciBzdHlsZSA9IHRoaXMuZWxlbWVudC5zdHlsZTtcbiAgICB2YXIgb2Zmc2V0ID0gdGhpcy5nZXRPZmZzZXQoKTtcbiAgICB2YXIgcG9zaXRpb25pbmcgPSB0aGlzLmdldFBvc2l0aW9uaW5nKCk7XG4gICAgdGhpcy5zZXRWaXNpYmxlKHRydWUpO1xuICAgIHZhciB4ID0gTWF0aC5yb3VuZChwaXhlbFswXSArIG9mZnNldFswXSkgKyAncHgnO1xuICAgIHZhciB5ID0gTWF0aC5yb3VuZChwaXhlbFsxXSArIG9mZnNldFsxXSkgKyAncHgnO1xuICAgIHZhciBwb3NYID0gJzAlJztcbiAgICB2YXIgcG9zWSA9ICcwJSc7XG5cbiAgICBpZiAocG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkJPVFRPTV9SSUdIVCB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQ0VOVEVSX1JJR0hUIHx8IHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5UT1BfUklHSFQpIHtcbiAgICAgIHBvc1ggPSAnLTEwMCUnO1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkJPVFRPTV9DRU5URVIgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLkNFTlRFUl9DRU5URVIgfHwgcG9zaXRpb25pbmcgPT0gT3ZlcmxheVBvc2l0aW9uaW5nLlRPUF9DRU5URVIpIHtcbiAgICAgIHBvc1ggPSAnLTUwJSc7XG4gICAgfVxuXG4gICAgaWYgKHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5CT1RUT01fTEVGVCB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQk9UVE9NX0NFTlRFUiB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQk9UVE9NX1JJR0hUKSB7XG4gICAgICBwb3NZID0gJy0xMDAlJztcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uaW5nID09IE92ZXJsYXlQb3NpdGlvbmluZy5DRU5URVJfTEVGVCB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQ0VOVEVSX0NFTlRFUiB8fCBwb3NpdGlvbmluZyA9PSBPdmVybGF5UG9zaXRpb25pbmcuQ0VOVEVSX1JJR0hUKSB7XG4gICAgICBwb3NZID0gJy01MCUnO1xuICAgIH1cblxuICAgIHZhciB0cmFuc2Zvcm0gPSBcInRyYW5zbGF0ZShcIiArIHBvc1ggKyBcIiwgXCIgKyBwb3NZICsgXCIpIHRyYW5zbGF0ZShcIiArIHggKyBcIiwgXCIgKyB5ICsgXCIpXCI7XG5cbiAgICBpZiAodGhpcy5yZW5kZXJlZC50cmFuc2Zvcm1fICE9IHRyYW5zZm9ybSkge1xuICAgICAgdGhpcy5yZW5kZXJlZC50cmFuc2Zvcm1fID0gdHJhbnNmb3JtO1xuICAgICAgc3R5bGUudHJhbnNmb3JtID0gdHJhbnNmb3JtOyAvLyBAdHMtaWdub3JlIElFOVxuXG4gICAgICBzdHlsZS5tc1RyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICB9XG4gIH07XG4gIC8qKlxuICAgKiByZXR1cm5zIHRoZSBvcHRpb25zIHRoaXMgT3ZlcmxheSBoYXMgYmVlbiBjcmVhdGVkIHdpdGhcbiAgICogQHJldHVybiB7T3B0aW9uc30gb3ZlcmxheSBvcHRpb25zXG4gICAqL1xuXG5cbiAgT3ZlcmxheS5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zO1xuICB9O1xuXG4gIHJldHVybiBPdmVybGF5O1xufShCYXNlT2JqZWN0KTtcblxuZXhwb3J0IGRlZmF1bHQgT3ZlcmxheTsiLCJpbXBvcnQgUmVhY3QsIHt1c2VSZWYsIHVzZUVmZmVjdCwgdXNlU3RhdGV9IGZyb20gJ3JlYWN0JztcbmltcG9ydCAqIGFzIHN0eWxlcyBmcm9tICcuL29wZW5sYXllcnNQb3B1cC5tb2R1bGUuc2Nzcyc7XG5pbXBvcnQgT3ZlcmxheSBmcm9tICdvbC9PdmVybGF5JztcbmltcG9ydCB7Q29vcmRpbmF0ZX0gZnJvbSAnb2wvQ29vcmRpbmF0ZSc7XG5pbXBvcnQgTWFwIGZyb20gJ29sL01hcCc7XG5pbXBvcnQge0ZlYXR1cmVMaWtlfSBmcm9tICdvbC9GZWF0dXJlJztcbmltcG9ydCBQb3B1cENvbnRlbnQgZnJvbSAnLi9wb3B1cENvbnRlbnQnO1xuXG5pbnRlcmZhY2UgSU9wZW5sYXllcnNQb3B1cFByb3BzIHtcbiAgICBtYXA6IE1hcCxcbiAgICBzZWxlY3RlZEZlYXR1cmU6IEZlYXR1cmVMaWtlO1xuICAgIHBvc2l0aW9uOiBDb29yZGluYXRlO1xufVxuXG5jb25zdCBPcGVubGF5ZXJzUG9wdXAgPSAoe21hcCwgc2VsZWN0ZWRGZWF0dXJlLCBwb3NpdGlvbn06IElPcGVubGF5ZXJzUG9wdXBQcm9wcykgPT4ge1xuICBjb25zdCBwb3B1cENvbnRhaW5lckVsZW1lbnQgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQ+KG51bGwpO1xuICBjb25zdCBwb3B1cENsb3NlckVsZW1lbnQgPSB1c2VSZWY8SFRNTEFuY2hvckVsZW1lbnQ+KG51bGwpO1xuICBjb25zdCBwb3B1cENvbnRlbnRFbGVtZW50ID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgW2N1cnJlbnRPdmVybGF5LCBzZXRDdXJyZW50T3ZlcmxheV0gPSB1c2VTdGF0ZTxPdmVybGF5PigpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcG9wdXBDbG9zZXJFbGVtZW50LmN1cnJlbnQhLm9uY2xpY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIG92ZXJsYXkuc2V0UG9zaXRpb24odW5kZWZpbmVkKTtcbiAgICAgIHBvcHVwQ2xvc2VyRWxlbWVudC5jdXJyZW50IS5ibHVyKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGNvbnN0IG92ZXJsYXkgPSBuZXcgT3ZlcmxheSh7XG4gICAgICBlbGVtZW50OiBwb3B1cENvbnRhaW5lckVsZW1lbnQuY3VycmVudCEsXG4gICAgICBhdXRvUGFuOiB0cnVlLFxuICAgICAgYXV0b1BhbkFuaW1hdGlvbjoge1xuICAgICAgICBkdXJhdGlvbjogMjUwLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBzZXRDdXJyZW50T3ZlcmxheShvdmVybGF5KTtcbiAgICBtYXAuYWRkT3ZlcmxheShvdmVybGF5KTtcbiAgfSwgW10pO1xuXG4gIHVzZUVmZmVjdCggKCkgPT4ge1xuICAgIGlmIChwb3NpdGlvbiAmJiBjdXJyZW50T3ZlcmxheSAmJiBzZWxlY3RlZEZlYXR1cmUpIHsgLy8gbWF5IGJlIGVtcHR5IG9uIGZpcnN0IHJlbmRlclxuICAgICAgY3VycmVudE92ZXJsYXkuc2V0UG9zaXRpb24ocG9zaXRpb24pO1xuICAgIH1cbiAgfSwgW3Bvc2l0aW9uXSk7XG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAgPGRpdiByZWY9e3BvcHVwQ29udGFpbmVyRWxlbWVudH1cbiAgICAgICAgY2xhc3NOYW1lPXtzdHlsZXMucG9wdXBDb250YWluZXJ9PlxuICAgICAgICA8YSBocmVmPVwiI1wiIHJlZj17cG9wdXBDbG9zZXJFbGVtZW50fSBjbGFzc05hbWU9e3N0eWxlcy5wb3B1cENsb3Nlcn0+PC9hPlxuICAgICAgICA8ZGl2IHJlZj17cG9wdXBDb250ZW50RWxlbWVudH0gY2xhc3NOYW1lPXtzdHlsZXMucG9wdXBDb250ZW50fT5cbiAgICAgICAgICA8UG9wdXBDb250ZW50IHByb3BlcnRpZXM9e3NlbGVjdGVkRmVhdHVyZT8uZ2V0UHJvcGVydGllcygpfSAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgT3BlbmxheWVyc1BvcHVwO1xuIiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovVW5pdHNcbiAqL1xuXG4vKipcbiAqIFByb2plY3Rpb24gdW5pdHM6IGAnZGVncmVlcydgLCBgJ2Z0J2AsIGAnbSdgLCBgJ3BpeGVscydgLCBgJ3RpbGUtcGl4ZWxzJ2Agb3JcbiAqIGAndXMtZnQnYC5cbiAqIEBlbnVtIHtzdHJpbmd9XG4gKi9cbnZhciBVbml0cyA9IHtcbiAgLyoqXG4gICAqIERlZ3JlZXNcbiAgICogQGFwaVxuICAgKi9cbiAgREVHUkVFUzogJ2RlZ3JlZXMnLFxuXG4gIC8qKlxuICAgKiBGZWV0XG4gICAqIEBhcGlcbiAgICovXG4gIEZFRVQ6ICdmdCcsXG5cbiAgLyoqXG4gICAqIE1ldGVyc1xuICAgKiBAYXBpXG4gICAqL1xuICBNRVRFUlM6ICdtJyxcblxuICAvKipcbiAgICogUGl4ZWxzXG4gICAqIEBhcGlcbiAgICovXG4gIFBJWEVMUzogJ3BpeGVscycsXG5cbiAgLyoqXG4gICAqIFRpbGUgUGl4ZWxzXG4gICAqIEBhcGlcbiAgICovXG4gIFRJTEVfUElYRUxTOiAndGlsZS1waXhlbHMnLFxuXG4gIC8qKlxuICAgKiBVUyBGZWV0XG4gICAqIEBhcGlcbiAgICovXG4gIFVTRkVFVDogJ3VzLWZ0J1xufTtcbi8qKlxuICogTWV0ZXJzIHBlciB1bml0IGxvb2t1cCB0YWJsZS5cbiAqIEBjb25zdFxuICogQHR5cGUge09iamVjdDxVbml0cywgbnVtYmVyPn1cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgdmFyIE1FVEVSU19QRVJfVU5JVCA9IHt9OyAvLyB1c2UgdGhlIHJhZGl1cyBvZiB0aGUgTm9ybWFsIHNwaGVyZVxuXG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuREVHUkVFU10gPSAyICogTWF0aC5QSSAqIDYzNzA5OTcgLyAzNjA7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuRkVFVF0gPSAwLjMwNDg7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuTUVURVJTXSA9IDE7XG5NRVRFUlNfUEVSX1VOSVRbVW5pdHMuVVNGRUVUXSA9IDEyMDAgLyAzOTM3O1xuZXhwb3J0IGRlZmF1bHQgVW5pdHM7IiwiaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiL2hvbWUvcnVubmVyL3dvcmsvanVzdGljZTQwLXRvb2wvanVzdGljZTQwLXRvb2wvY2xpZW50L25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiL2hvbWUvcnVubmVyL3dvcmsvanVzdGljZTQwLXRvb2wvanVzdGljZTQwLXRvb2wvY2xpZW50L25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuXG4vKipcbiAqIEBtb2R1bGUgb2wvcHJvai9Qcm9qZWN0aW9uXG4gKi9cbmltcG9ydCB7IE1FVEVSU19QRVJfVU5JVCB9IGZyb20gJy4vVW5pdHMuanMnO1xuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gY29kZSBUaGUgU1JTIGlkZW50aWZpZXIgY29kZSwgZS5nLiBgRVBTRzo0MzI2YC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9Vbml0cy5qc1wiKS5kZWZhdWx0fHN0cmluZ30gW3VuaXRzXSBVbml0cy4gUmVxdWlyZWQgdW5sZXNzIGFcbiAqIHByb2o0IHByb2plY3Rpb24gaXMgZGVmaW5lZCBmb3IgYGNvZGVgLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbZXh0ZW50XSBUaGUgdmFsaWRpdHkgZXh0ZW50IGZvciB0aGUgU1JTLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtheGlzT3JpZW50YXRpb249J2VudSddIFRoZSBheGlzIG9yaWVudGF0aW9uIGFzIHNwZWNpZmllZCBpbiBQcm9qNC5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2dsb2JhbD1mYWxzZV0gV2hldGhlciB0aGUgcHJvamVjdGlvbiBpcyB2YWxpZCBmb3IgdGhlIHdob2xlIGdsb2JlLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFttZXRlcnNQZXJVbml0XSBUaGUgbWV0ZXJzIHBlciB1bml0IGZvciB0aGUgU1JTLlxuICogSWYgbm90IHByb3ZpZGVkLCB0aGUgYHVuaXRzYCBhcmUgdXNlZCB0byBnZXQgdGhlIG1ldGVycyBwZXIgdW5pdCBmcm9tIHRoZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovVW5pdHN+TUVURVJTX1BFUl9VTklUfVxuICogbG9va3VwIHRhYmxlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSBbd29ybGRFeHRlbnRdIFRoZSB3b3JsZCBleHRlbnQgZm9yIHRoZSBTUlMuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlciwgaW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTpudW1iZXJ9IFtnZXRQb2ludFJlc29sdXRpb25dXG4gKiBGdW5jdGlvbiB0byBkZXRlcm1pbmUgcmVzb2x1dGlvbiBhdCBhIHBvaW50LiBUaGUgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggYVxuICogYHtudW1iZXJ9YCB2aWV3IHJlc29sdXRpb24gYW5kIGFuIGB7aW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfWAgYXMgYXJndW1lbnRzLCBhbmQgcmV0dXJuc1xuICogdGhlIGB7bnVtYmVyfWAgcmVzb2x1dGlvbiBpbiBwcm9qZWN0aW9uIHVuaXRzIGF0IHRoZSBwYXNzZWQgY29vcmRpbmF0ZS4gSWYgdGhpcyBpcyBgdW5kZWZpbmVkYCxcbiAqIHRoZSBkZWZhdWx0IHtAbGluayBtb2R1bGU6b2wvcHJvaiNnZXRQb2ludFJlc29sdXRpb259IGZ1bmN0aW9uIHdpbGwgYmUgdXNlZC5cbiAqL1xuXG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFByb2plY3Rpb24gZGVmaW5pdGlvbiBjbGFzcy4gT25lIG9mIHRoZXNlIGlzIGNyZWF0ZWQgZm9yIGVhY2ggcHJvamVjdGlvblxuICogc3VwcG9ydGVkIGluIHRoZSBhcHBsaWNhdGlvbiBhbmQgc3RvcmVkIGluIHRoZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p9IG5hbWVzcGFjZS5cbiAqIFlvdSBjYW4gdXNlIHRoZXNlIGluIGFwcGxpY2F0aW9ucywgYnV0IHRoaXMgaXMgbm90IHJlcXVpcmVkLCBhcyBBUEkgcGFyYW1zXG4gKiBhbmQgb3B0aW9ucyB1c2Uge0BsaW5rIG1vZHVsZTpvbC9wcm9qflByb2plY3Rpb25MaWtlfSB3aGljaCBtZWFucyB0aGUgc2ltcGxlIHN0cmluZ1xuICogY29kZSB3aWxsIHN1ZmZpY2UuXG4gKlxuICogWW91IGNhbiB1c2Uge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmdldH0gdG8gcmV0cmlldmUgdGhlIG9iamVjdCBmb3IgYSBwYXJ0aWN1bGFyXG4gKiBwcm9qZWN0aW9uLlxuICpcbiAqIFRoZSBsaWJyYXJ5IGluY2x1ZGVzIGRlZmluaXRpb25zIGZvciBgRVBTRzo0MzI2YCBhbmQgYEVQU0c6Mzg1N2AsIHRvZ2V0aGVyXG4gKiB3aXRoIHRoZSBmb2xsb3dpbmcgYWxpYXNlczpcbiAqICogYEVQU0c6NDMyNmA6IENSUzo4NCwgdXJuOm9nYzpkZWY6Y3JzOkVQU0c6Ni42OjQzMjYsXG4gKiAgICAgdXJuOm9nYzpkZWY6Y3JzOk9HQzoxLjM6Q1JTODQsIHVybjpvZ2M6ZGVmOmNyczpPR0M6Mjo4NCxcbiAqICAgICBodHRwOi8vd3d3Lm9wZW5naXMubmV0L2dtbC9zcnMvZXBzZy54bWwjNDMyNixcbiAqICAgICB1cm46eC1vZ2M6ZGVmOmNyczpFUFNHOjQzMjZcbiAqICogYEVQU0c6Mzg1N2A6IEVQU0c6MTAyMTAwLCBFUFNHOjEwMjExMywgRVBTRzo5MDA5MTMsXG4gKiAgICAgdXJuOm9nYzpkZWY6Y3JzOkVQU0c6Ni4xODozOjM4NTcsXG4gKiAgICAgaHR0cDovL3d3dy5vcGVuZ2lzLm5ldC9nbWwvc3JzL2Vwc2cueG1sIzM4NTdcbiAqXG4gKiBJZiB5b3UgdXNlIFtwcm9qNGpzXShodHRwczovL2dpdGh1Yi5jb20vcHJvajRqcy9wcm9qNGpzKSwgYWxpYXNlcyBjYW5cbiAqIGJlIGFkZGVkIHVzaW5nIGBwcm9qNC5kZWZzKClgLiBBZnRlciBhbGwgcmVxdWlyZWQgcHJvamVjdGlvbiBkZWZpbml0aW9ucyBhcmVcbiAqIGFkZGVkLCBjYWxsIHRoZSB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovcHJvajR+cmVnaXN0ZXJ9IGZ1bmN0aW9uLlxuICpcbiAqIEBhcGlcbiAqL1xuXG52YXIgUHJvamVjdGlvbiA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgUHJvamVjdGlvbiBvcHRpb25zLlxuICAgKi9cbiAgZnVuY3Rpb24gUHJvamVjdGlvbihvcHRpb25zKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFByb2plY3Rpb24pO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuICAgIHRoaXMuY29kZV8gPSBvcHRpb25zLmNvZGU7XG4gICAgLyoqXG4gICAgICogVW5pdHMgb2YgcHJvamVjdGVkIGNvb3JkaW5hdGVzLiBXaGVuIHNldCB0byBgVElMRV9QSVhFTFNgLCBhXG4gICAgICogYHRoaXMuZXh0ZW50X2AgYW5kIGB0aGlzLndvcmxkRXh0ZW50X2AgbXVzdCBiZSBjb25maWd1cmVkIHByb3Blcmx5IGZvciBlYWNoXG4gICAgICogdGlsZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL1VuaXRzLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICB0aGlzLnVuaXRzXyA9XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuL1VuaXRzLmpzXCIpLmRlZmF1bHR9ICovXG4gICAgb3B0aW9ucy51bml0cztcbiAgICAvKipcbiAgICAgKiBWYWxpZGl0eSBleHRlbnQgb2YgdGhlIHByb2plY3Rpb24gaW4gcHJvamVjdGVkIGNvb3JkaW5hdGVzLiBGb3IgcHJvamVjdGlvbnNcbiAgICAgKiB3aXRoIGBUSUxFX1BJWEVMU2AgdW5pdHMsIHRoaXMgaXMgdGhlIGV4dGVudCBvZiB0aGUgdGlsZSBpblxuICAgICAqIHRpbGUgcGl4ZWwgc3BhY2UuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIHRoaXMuZXh0ZW50XyA9IG9wdGlvbnMuZXh0ZW50ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmV4dGVudCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogRXh0ZW50IG9mIHRoZSB3b3JsZCBpbiBFUFNHOjQzMjYuIEZvciBwcm9qZWN0aW9ucyB3aXRoXG4gICAgICogYFRJTEVfUElYRUxTYCB1bml0cywgdGhpcyBpcyB0aGUgZXh0ZW50IG9mIHRoZSB0aWxlIGluXG4gICAgICogcHJvamVjdGVkIGNvb3JkaW5hdGUgc3BhY2UuXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH1cbiAgICAgKi9cblxuICAgIHRoaXMud29ybGRFeHRlbnRfID0gb3B0aW9ucy53b3JsZEV4dGVudCAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy53b3JsZEV4dGVudCA6IG51bGw7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgICAqL1xuXG4gICAgdGhpcy5heGlzT3JpZW50YXRpb25fID0gb3B0aW9ucy5heGlzT3JpZW50YXRpb24gIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuYXhpc09yaWVudGF0aW9uIDogJ2VudSc7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICAgKi9cblxuICAgIHRoaXMuZ2xvYmFsXyA9IG9wdGlvbnMuZ2xvYmFsICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmdsb2JhbCA6IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG5cbiAgICB0aGlzLmNhbldyYXBYXyA9ICEhKHRoaXMuZ2xvYmFsXyAmJiB0aGlzLmV4dGVudF8pO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2Z1bmN0aW9uKG51bWJlciwgaW1wb3J0KFwiLi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTpudW1iZXJ8dW5kZWZpbmVkfVxuICAgICAqL1xuXG4gICAgdGhpcy5nZXRQb2ludFJlc29sdXRpb25GdW5jXyA9IG9wdGlvbnMuZ2V0UG9pbnRSZXNvbHV0aW9uO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge2ltcG9ydChcIi4uL3RpbGVncmlkL1RpbGVHcmlkLmpzXCIpLmRlZmF1bHR9XG4gICAgICovXG5cbiAgICB0aGlzLmRlZmF1bHRUaWxlR3JpZF8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge251bWJlcnx1bmRlZmluZWR9XG4gICAgICovXG5cbiAgICB0aGlzLm1ldGVyc1BlclVuaXRfID0gb3B0aW9ucy5tZXRlcnNQZXJVbml0O1xuICB9XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUaGUgcHJvamVjdGlvbiBpcyBzdWl0YWJsZSBmb3Igd3JhcHBpbmcgdGhlIHgtYXhpc1xuICAgKi9cblxuXG4gIF9jcmVhdGVDbGFzcyhQcm9qZWN0aW9uLCBbe1xuICAgIGtleTogXCJjYW5XcmFwWFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBjYW5XcmFwWCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhbldyYXBYXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjb2RlIGZvciB0aGlzIHByb2plY3Rpb24sIGUuZy4gJ0VQU0c6NDMyNicuXG4gICAgICogQHJldHVybiB7c3RyaW5nfSBDb2RlLlxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldENvZGVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0Q29kZSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvZGVfO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbGlkaXR5IGV4dGVudCBmb3IgdGhpcyBwcm9qZWN0aW9uLlxuICAgICAqIEByZXR1cm4ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IEV4dGVudC5cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRFeHRlbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RXh0ZW50KCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXh0ZW50XztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB1bml0cyBvZiB0aGlzIHByb2plY3Rpb24uXG4gICAgICogQHJldHVybiB7aW1wb3J0KFwiLi9Vbml0cy5qc1wiKS5kZWZhdWx0fSBVbml0cy5cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRVbml0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRVbml0cygpIHtcbiAgICAgIHJldHVybiB0aGlzLnVuaXRzXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhbW91bnQgb2YgbWV0ZXJzIHBlciB1bml0IG9mIHRoaXMgcHJvamVjdGlvbi4gIElmIHRoZSBwcm9qZWN0aW9uIGlzXG4gICAgICogbm90IGNvbmZpZ3VyZWQgd2l0aCBgbWV0ZXJzUGVyVW5pdGAgb3IgYSB1bml0cyBpZGVudGlmaWVyLCB0aGUgcmV0dXJuIGlzXG4gICAgICogYHVuZGVmaW5lZGAuXG4gICAgICogQHJldHVybiB7bnVtYmVyfHVuZGVmaW5lZH0gTWV0ZXJzLlxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldE1ldGVyc1BlclVuaXRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0TWV0ZXJzUGVyVW5pdCgpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGVyc1BlclVuaXRfIHx8IE1FVEVSU19QRVJfVU5JVFt0aGlzLnVuaXRzX107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgd29ybGQgZXh0ZW50IGZvciB0aGlzIHByb2plY3Rpb24uXG4gICAgICogQHJldHVybiB7aW1wb3J0KFwiLi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gRXh0ZW50LlxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldFdvcmxkRXh0ZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFdvcmxkRXh0ZW50KCkge1xuICAgICAgcmV0dXJuIHRoaXMud29ybGRFeHRlbnRfO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGF4aXMgb3JpZW50YXRpb24gb2YgdGhpcyBwcm9qZWN0aW9uLlxuICAgICAqIEV4YW1wbGUgdmFsdWVzIGFyZTpcbiAgICAgKiBlbnUgLSB0aGUgZGVmYXVsdCBlYXN0aW5nLCBub3J0aGluZywgZWxldmF0aW9uLlxuICAgICAqIG5ldSAtIG5vcnRoaW5nLCBlYXN0aW5nLCB1cCAtIHVzZWZ1bCBmb3IgXCJsYXQvbG9uZ1wiIGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMsXG4gICAgICogICAgIG9yIHNvdXRoIG9yaWVudGF0ZWQgdHJhbnN2ZXJzZSBtZXJjYXRvci5cbiAgICAgKiB3bnUgLSB3ZXN0aW5nLCBub3J0aGluZywgdXAgLSBzb21lIHBsYW5ldGFyeSBjb29yZGluYXRlIHN5c3RlbXMgaGF2ZVxuICAgICAqICAgICBcIndlc3QgcG9zaXRpdmVcIiBjb29yZGluYXRlIHN5c3RlbXNcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IEF4aXMgb3JpZW50YXRpb24uXG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0QXhpc09yaWVudGF0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldEF4aXNPcmllbnRhdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmF4aXNPcmllbnRhdGlvbl87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElzIHRoaXMgcHJvamVjdGlvbiBhIGdsb2JhbCBwcm9qZWN0aW9uIHdoaWNoIHNwYW5zIHRoZSB3aG9sZSB3b3JsZD9cbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBXaGV0aGVyIHRoZSBwcm9qZWN0aW9uIGlzIGdsb2JhbC5cbiAgICAgKiBAYXBpXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJpc0dsb2JhbFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBpc0dsb2JhbCgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdsb2JhbF87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBpZiB0aGUgcHJvamVjdGlvbiBpcyBhIGdsb2JhbCBwcm9qZWN0aW9uIHdoaWNoIHNwYW5zIHRoZSB3aG9sZSB3b3JsZFxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZ2xvYmFsIFdoZXRoZXIgdGhlIHByb2plY3Rpb24gaXMgZ2xvYmFsLlxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldEdsb2JhbFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRHbG9iYWwoZ2xvYmFsKSB7XG4gICAgICB0aGlzLmdsb2JhbF8gPSBnbG9iYWw7XG4gICAgICB0aGlzLmNhbldyYXBYXyA9ICEhKGdsb2JhbCAmJiB0aGlzLmV4dGVudF8pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJuIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSBUaGUgZGVmYXVsdCB0aWxlIGdyaWQuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXREZWZhdWx0VGlsZUdyaWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0RGVmYXVsdFRpbGVHcmlkKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdFRpbGVHcmlkXztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi90aWxlZ3JpZC9UaWxlR3JpZC5qc1wiKS5kZWZhdWx0fSB0aWxlR3JpZCBUaGUgZGVmYXVsdCB0aWxlIGdyaWQuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXREZWZhdWx0VGlsZUdyaWRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0RGVmYXVsdFRpbGVHcmlkKHRpbGVHcmlkKSB7XG4gICAgICB0aGlzLmRlZmF1bHRUaWxlR3JpZF8gPSB0aWxlR3JpZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB2YWxpZGl0eSBleHRlbnQgZm9yIHRoaXMgcHJvamVjdGlvbi5cbiAgICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RXh0ZW50XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHNldEV4dGVudChleHRlbnQpIHtcbiAgICAgIHRoaXMuZXh0ZW50XyA9IGV4dGVudDtcbiAgICAgIHRoaXMuY2FuV3JhcFhfID0gISEodGhpcy5nbG9iYWxfICYmIGV4dGVudCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgd29ybGQgZXh0ZW50IGZvciB0aGlzIHByb2plY3Rpb24uXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fSB3b3JsZEV4dGVudCBXb3JsZCBleHRlbnRcbiAgICAgKiAgICAgW21pbmxvbiwgbWlubGF0LCBtYXhsb24sIG1heGxhdF0uXG4gICAgICogQGFwaVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0V29ybGRFeHRlbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gc2V0V29ybGRFeHRlbnQod29ybGRFeHRlbnQpIHtcbiAgICAgIHRoaXMud29ybGRFeHRlbnRfID0gd29ybGRFeHRlbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgZ2V0UG9pbnRSZXNvbHV0aW9uIGZ1bmN0aW9uIChzZWUge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmdldFBvaW50UmVzb2x1dGlvbn1cbiAgICAgKiBmb3IgdGhpcyBwcm9qZWN0aW9uLlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyLCBpbXBvcnQoXCIuLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOm51bWJlcn0gZnVuYyBGdW5jdGlvblxuICAgICAqIEBhcGlcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldEdldFBvaW50UmVzb2x1dGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRHZXRQb2ludFJlc29sdXRpb24oZnVuYykge1xuICAgICAgdGhpcy5nZXRQb2ludFJlc29sdXRpb25GdW5jXyA9IGZ1bmM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VzdG9tIHBvaW50IHJlc29sdXRpb24gZnVuY3Rpb24gZm9yIHRoaXMgcHJvamVjdGlvbiAoaWYgc2V0KS5cbiAgICAgKiBAcmV0dXJuIHtmdW5jdGlvbihudW1iZXIsIGltcG9ydChcIi4uL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6bnVtYmVyfHVuZGVmaW5lZH0gVGhlIGN1c3RvbSBwb2ludFxuICAgICAqIHJlc29sdXRpb24gZnVuY3Rpb24gKGlmIHNldCkuXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQb2ludFJlc29sdXRpb25GdW5jXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGdldFBvaW50UmVzb2x1dGlvbkZ1bmMoKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRQb2ludFJlc29sdXRpb25GdW5jXztcbiAgICB9XG4gIH1dKTtcblxuICByZXR1cm4gUHJvamVjdGlvbjtcbn0oKTtcblxuZXhwb3J0IGRlZmF1bHQgUHJvamVjdGlvbjsiLCIvKipcbiAqIEBtb2R1bGUgb2wvbWF0aFxuICovXG5cbi8qKlxuICogVGFrZXMgYSBudW1iZXIgYW5kIGNsYW1wcyBpdCB0byB3aXRoaW4gdGhlIHByb3ZpZGVkIGJvdW5kcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgaW5wdXQgbnVtYmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pbiBUaGUgbWluaW11bSB2YWx1ZSB0byByZXR1cm4uXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4IFRoZSBtYXhpbXVtIHZhbHVlIHRvIHJldHVybi5cbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIGlucHV0IG51bWJlciBpZiBpdCBpcyB3aXRoaW4gYm91bmRzLCBvciB0aGUgbmVhcmVzdFxuICogICAgIG51bWJlciB3aXRoaW4gdGhlIGJvdW5kcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYW1wKHZhbHVlLCBtaW4sIG1heCkge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsIG1pbiksIG1heCk7XG59XG4vKipcbiAqIFJldHVybiB0aGUgaHlwZXJib2xpYyBjb3NpbmUgb2YgYSBnaXZlbiBudW1iZXIuIFRoZSBtZXRob2Qgd2lsbCB1c2UgdGhlXG4gKiBuYXRpdmUgYE1hdGguY29zaGAgZnVuY3Rpb24gaWYgaXQgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgdGhlIGh5cGVyYm9saWNcbiAqIGNvc2luZSB3aWxsIGJlIGNhbGN1bGF0ZWQgdmlhIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gb2YgdGhlIE1vemlsbGFcbiAqIGRldmVsb3BlciBuZXR3b3JrLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEh5cGVyYm9saWMgY29zaW5lIG9mIHguXG4gKi9cblxuZXhwb3J0IHZhciBjb3NoID0gZnVuY3Rpb24gKCkge1xuICAvLyBXcmFwcGVkIGluIGEgaWlmZSwgdG8gc2F2ZSB0aGUgb3ZlcmhlYWQgb2YgY2hlY2tpbmcgZm9yIHRoZSBuYXRpdmVcbiAgLy8gaW1wbGVtZW50YXRpb24gb24gZXZlcnkgaW52b2NhdGlvbi5cbiAgdmFyIGNvc2g7XG5cbiAgaWYgKCdjb3NoJyBpbiBNYXRoKSB7XG4gICAgLy8gVGhlIGVudmlyb25tZW50IHN1cHBvcnRzIHRoZSBuYXRpdmUgTWF0aC5jb3NoIGZ1bmN0aW9uLCB1c2UgaXTigKZcbiAgICBjb3NoID0gTWF0aC5jb3NoO1xuICB9IGVsc2Uge1xuICAgIC8vIOKApiBlbHNlLCB1c2UgdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbiBvZiBNRE46XG4gICAgY29zaCA9IGZ1bmN0aW9uIGNvc2goeCkge1xuICAgICAgdmFyIHkgPVxuICAgICAgLyoqIEB0eXBlIHtNYXRofSAqL1xuICAgICAgTWF0aC5leHAoeCk7XG4gICAgICByZXR1cm4gKHkgKyAxIC8geSkgLyAyO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gY29zaDtcbn0oKTtcbi8qKlxuICogUmV0dXJuIHRoZSBiYXNlIDIgbG9nYXJpdGhtIG9mIGEgZ2l2ZW4gbnVtYmVyLiBUaGUgbWV0aG9kIHdpbGwgdXNlIHRoZVxuICogbmF0aXZlIGBNYXRoLmxvZzJgIGZ1bmN0aW9uIGlmIGl0IGlzIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIHRoZSBiYXNlIDJcbiAqIGxvZ2FyaXRobSB3aWxsIGJlIGNhbGN1bGF0ZWQgdmlhIHRoZSByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gKiBNb3ppbGxhIGRldmVsb3BlciBuZXR3b3JrLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEJhc2UgMiBsb2dhcml0aG0gb2YgeC5cbiAqL1xuXG5leHBvcnQgdmFyIGxvZzIgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFdyYXBwZWQgaW4gYSBpaWZlLCB0byBzYXZlIHRoZSBvdmVyaGVhZCBvZiBjaGVja2luZyBmb3IgdGhlIG5hdGl2ZVxuICAvLyBpbXBsZW1lbnRhdGlvbiBvbiBldmVyeSBpbnZvY2F0aW9uLlxuICB2YXIgbG9nMjtcblxuICBpZiAoJ2xvZzInIGluIE1hdGgpIHtcbiAgICAvLyBUaGUgZW52aXJvbm1lbnQgc3VwcG9ydHMgdGhlIG5hdGl2ZSBNYXRoLmxvZzIgZnVuY3Rpb24sIHVzZSBpdOKAplxuICAgIGxvZzIgPSBNYXRoLmxvZzI7XG4gIH0gZWxzZSB7XG4gICAgLy8g4oCmIGVsc2UsIHVzZSB0aGUgcmVmZXJlbmNlIGltcGxlbWVudGF0aW9uIG9mIE1ETjpcbiAgICBsb2cyID0gZnVuY3Rpb24gbG9nMih4KSB7XG4gICAgICByZXR1cm4gTWF0aC5sb2coeCkgKiBNYXRoLkxPRzJFO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gbG9nMjtcbn0oKTtcbi8qKlxuICogUmV0dXJucyB0aGUgc3F1YXJlIG9mIHRoZSBjbG9zZXN0IGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvaW50ICh4LCB5KSBhbmQgdGhlXG4gKiBsaW5lIHNlZ21lbnQgKHgxLCB5MSkgdG8gKHgyLCB5MikuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MSBYMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSBZMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiBYMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MiBZMi5cbiAqIEByZXR1cm4ge251bWJlcn0gU3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZFNlZ21lbnREaXN0YW5jZSh4LCB5LCB4MSwgeTEsIHgyLCB5Mikge1xuICB2YXIgZHggPSB4MiAtIHgxO1xuICB2YXIgZHkgPSB5MiAtIHkxO1xuXG4gIGlmIChkeCAhPT0gMCB8fCBkeSAhPT0gMCkge1xuICAgIHZhciB0ID0gKCh4IC0geDEpICogZHggKyAoeSAtIHkxKSAqIGR5KSAvIChkeCAqIGR4ICsgZHkgKiBkeSk7XG5cbiAgICBpZiAodCA+IDEpIHtcbiAgICAgIHgxID0geDI7XG4gICAgICB5MSA9IHkyO1xuICAgIH0gZWxzZSBpZiAodCA+IDApIHtcbiAgICAgIHgxICs9IGR4ICogdDtcbiAgICAgIHkxICs9IGR5ICogdDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3F1YXJlZERpc3RhbmNlKHgsIHksIHgxLCB5MSk7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIHNxdWFyZSBvZiB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnRzICh4MSwgeTEpIGFuZCAoeDIsIHkyKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MSBYMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MSBZMS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4MiBYMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB5MiBZMi5cbiAqIEByZXR1cm4ge251bWJlcn0gU3F1YXJlZCBkaXN0YW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc3F1YXJlZERpc3RhbmNlKHgxLCB5MSwgeDIsIHkyKSB7XG4gIHZhciBkeCA9IHgyIC0geDE7XG4gIHZhciBkeSA9IHkyIC0geTE7XG4gIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cbi8qKlxuICogU29sdmVzIHN5c3RlbSBvZiBsaW5lYXIgZXF1YXRpb25zIHVzaW5nIEdhdXNzaWFuIGVsaW1pbmF0aW9uIG1ldGhvZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBtYXQgQXVnbWVudGVkIG1hdHJpeCAobiB4IG4gKyAxIGNvbHVtbilcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIHJvdy1tYWpvciBvcmRlci5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IFRoZSByZXN1bHRpbmcgdmVjdG9yLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBzb2x2ZUxpbmVhclN5c3RlbShtYXQpIHtcbiAgdmFyIG4gPSBtYXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgLy8gRmluZCBtYXggaW4gdGhlIGktdGggY29sdW1uIChpZ25vcmluZyBpIC0gMSBmaXJzdCByb3dzKVxuICAgIHZhciBtYXhSb3cgPSBpO1xuICAgIHZhciBtYXhFbCA9IE1hdGguYWJzKG1hdFtpXVtpXSk7XG5cbiAgICBmb3IgKHZhciByID0gaSArIDE7IHIgPCBuOyByKyspIHtcbiAgICAgIHZhciBhYnNWYWx1ZSA9IE1hdGguYWJzKG1hdFtyXVtpXSk7XG5cbiAgICAgIGlmIChhYnNWYWx1ZSA+IG1heEVsKSB7XG4gICAgICAgIG1heEVsID0gYWJzVmFsdWU7XG4gICAgICAgIG1heFJvdyA9IHI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1heEVsID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDsgLy8gbWF0cml4IGlzIHNpbmd1bGFyXG4gICAgfSAvLyBTd2FwIG1heCByb3cgd2l0aCBpLXRoIChjdXJyZW50KSByb3dcblxuXG4gICAgdmFyIHRtcCA9IG1hdFttYXhSb3ddO1xuICAgIG1hdFttYXhSb3ddID0gbWF0W2ldO1xuICAgIG1hdFtpXSA9IHRtcDsgLy8gU3VidHJhY3QgdGhlIGktdGggcm93IHRvIG1ha2UgYWxsIHRoZSByZW1haW5pbmcgcm93cyAwIGluIHRoZSBpLXRoIGNvbHVtblxuXG4gICAgZm9yICh2YXIgaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7XG4gICAgICB2YXIgY29lZiA9IC1tYXRbal1baV0gLyBtYXRbaV1baV07XG5cbiAgICAgIGZvciAodmFyIGsgPSBpOyBrIDwgbiArIDE7IGsrKykge1xuICAgICAgICBpZiAoaSA9PSBrKSB7XG4gICAgICAgICAgbWF0W2pdW2tdID0gMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXRbal1ba10gKz0gY29lZiAqIG1hdFtpXVtrXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSAvLyBTb2x2ZSBBeD1iIGZvciB1cHBlciB0cmlhbmd1bGFyIG1hdHJpeCBBIChtYXQpXG5cblxuICB2YXIgeCA9IG5ldyBBcnJheShuKTtcblxuICBmb3IgKHZhciBsID0gbiAtIDE7IGwgPj0gMDsgbC0tKSB7XG4gICAgeFtsXSA9IG1hdFtsXVtuXSAvIG1hdFtsXVtsXTtcblxuICAgIGZvciAodmFyIG0gPSBsIC0gMTsgbSA+PSAwOyBtLS0pIHtcbiAgICAgIG1hdFttXVtuXSAtPSBtYXRbbV1bbF0gKiB4W2xdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB4O1xufVxuLyoqXG4gKiBDb252ZXJ0cyByYWRpYW5zIHRvIHRvIGRlZ3JlZXMuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlSW5SYWRpYW5zIEFuZ2xlIGluIHJhZGlhbnMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIGluIGRlZ3JlZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRGVncmVlcyhhbmdsZUluUmFkaWFucykge1xuICByZXR1cm4gYW5nbGVJblJhZGlhbnMgKiAxODAgLyBNYXRoLlBJO1xufVxuLyoqXG4gKiBDb252ZXJ0cyBkZWdyZWVzIHRvIHJhZGlhbnMuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlSW5EZWdyZWVzIEFuZ2xlIGluIGRlZ3JlZXMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuZ2xlIGluIHJhZGlhbnMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvUmFkaWFucyhhbmdsZUluRGVncmVlcykge1xuICByZXR1cm4gYW5nbGVJbkRlZ3JlZXMgKiBNYXRoLlBJIC8gMTgwO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtb2R1bG8gb2YgYSAvIGIsIGRlcGVuZGluZyBvbiB0aGUgc2lnbiBvZiBiLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBhIERpdmlkZW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IGIgRGl2aXNvci5cbiAqIEByZXR1cm4ge251bWJlcn0gTW9kdWxvLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBtb2R1bG8oYSwgYikge1xuICB2YXIgciA9IGEgJSBiO1xuICByZXR1cm4gciAqIGIgPCAwID8gciArIGIgOiByO1xufVxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBsaW5lYXJseSBpbnRlcnBvbGF0ZWQgdmFsdWUgb2YgeCBiZXR3ZWVuIGEgYW5kIGIuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGEgTnVtYmVyXG4gKiBAcGFyYW0ge251bWJlcn0gYiBOdW1iZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFZhbHVlIHRvIGJlIGludGVycG9sYXRlZC5cbiAqIEByZXR1cm4ge251bWJlcn0gSW50ZXJwb2xhdGVkIHZhbHVlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBsZXJwKGEsIGIsIHgpIHtcbiAgcmV0dXJuIGEgKyB4ICogKGIgLSBhKTtcbn0iLCJpbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCIvaG9tZS9ydW5uZXIvd29yay9qdXN0aWNlNDAtdG9vbC9qdXN0aWNlNDAtdG9vbC9jbGllbnQvbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCIvaG9tZS9ydW5uZXIvd29yay9qdXN0aWNlNDAtdG9vbC9qdXN0aWNlNDAtdG9vbC9jbGllbnQvbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIi9ob21lL3J1bm5lci93b3JrL2p1c3RpY2U0MC10b29sL2p1c3RpY2U0MC10b29sL2NsaWVudC9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiO1xuaW1wb3J0IF9nZXRQcm90b3R5cGVPZiBmcm9tIFwiL2hvbWUvcnVubmVyL3dvcmsvanVzdGljZTQwLXRvb2wvanVzdGljZTQwLXRvb2wvY2xpZW50L25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9nZXRQcm90b3R5cGVPZlwiO1xuXG5mdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkgeyB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTsgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkgeyB2YXIgU3VwZXIgPSBfZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksIHJlc3VsdDsgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHsgdmFyIE5ld1RhcmdldCA9IF9nZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjsgcmVzdWx0ID0gUmVmbGVjdC5jb25zdHJ1Y3QoU3VwZXIsIGFyZ3VtZW50cywgTmV3VGFyZ2V0KTsgfSBlbHNlIHsgcmVzdWx0ID0gU3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfSByZXR1cm4gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgcmVzdWx0KTsgfTsgfVxuXG5mdW5jdGlvbiBfaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KCkgeyBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwidW5kZWZpbmVkXCIgfHwgIVJlZmxlY3QuY29uc3RydWN0KSByZXR1cm4gZmFsc2U7IGlmIChSZWZsZWN0LmNvbnN0cnVjdC5zaGFtKSByZXR1cm4gZmFsc2U7IGlmICh0eXBlb2YgUHJveHkgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIHRydWU7IHRyeSB7IEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTsgcmV0dXJuIHRydWU7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIGZhbHNlOyB9IH1cblxuLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2ovZXBzZzM4NTdcbiAqL1xuaW1wb3J0IFByb2plY3Rpb24gZnJvbSAnLi9Qcm9qZWN0aW9uLmpzJztcbmltcG9ydCBVbml0cyBmcm9tICcuL1VuaXRzLmpzJztcbmltcG9ydCB7IGNvc2ggfSBmcm9tICcuLi9tYXRoLmpzJztcbi8qKlxuICogUmFkaXVzIG9mIFdHUzg0IHNwaGVyZVxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIFJBRElVUyA9IDYzNzgxMzc7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIEhBTEZfU0laRSA9IE1hdGguUEkgKiBSQURJVVM7XG4vKipcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gKi9cblxuZXhwb3J0IHZhciBFWFRFTlQgPSBbLUhBTEZfU0laRSwgLUhBTEZfU0laRSwgSEFMRl9TSVpFLCBIQUxGX1NJWkVdO1xuLyoqXG4gKiBAY29uc3RcbiAqIEB0eXBlIHtpbXBvcnQoXCIuLi9leHRlbnQuanNcIikuRXh0ZW50fVxuICovXG5cbmV4cG9ydCB2YXIgV09STERfRVhURU5UID0gWy0xODAsIC04NSwgMTgwLCA4NV07XG4vKipcbiAqIE1heGltdW0gc2FmZSB2YWx1ZSBpbiB5IGRpcmVjdGlvblxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgTUFYX1NBRkVfWSA9IFJBRElVUyAqIE1hdGgubG9nKE1hdGgudGFuKE1hdGguUEkgLyAyKSk7XG4vKipcbiAqIEBjbGFzc2Rlc2NcbiAqIFByb2plY3Rpb24gb2JqZWN0IGZvciB3ZWIvc3BoZXJpY2FsIE1lcmNhdG9yIChFUFNHOjM4NTcpLlxuICovXG5cbnZhciBFUFNHMzg1N1Byb2plY3Rpb24gPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9Qcm9qZWN0aW9uKSB7XG4gIF9pbmhlcml0cyhFUFNHMzg1N1Byb2plY3Rpb24sIF9Qcm9qZWN0aW9uKTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKEVQU0czODU3UHJvamVjdGlvbik7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIENvZGUuXG4gICAqL1xuICBmdW5jdGlvbiBFUFNHMzg1N1Byb2plY3Rpb24oY29kZSkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFUFNHMzg1N1Byb2plY3Rpb24pO1xuXG4gICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIHtcbiAgICAgIGNvZGU6IGNvZGUsXG4gICAgICB1bml0czogVW5pdHMuTUVURVJTLFxuICAgICAgZXh0ZW50OiBFWFRFTlQsXG4gICAgICBnbG9iYWw6IHRydWUsXG4gICAgICB3b3JsZEV4dGVudDogV09STERfRVhURU5ULFxuICAgICAgZ2V0UG9pbnRSZXNvbHV0aW9uOiBmdW5jdGlvbiBnZXRQb2ludFJlc29sdXRpb24ocmVzb2x1dGlvbiwgcG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdXRpb24gLyBjb3NoKHBvaW50WzFdIC8gUkFESVVTKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBFUFNHMzg1N1Byb2plY3Rpb247XG59KFByb2plY3Rpb24pO1xuLyoqXG4gKiBQcm9qZWN0aW9ucyBlcXVhbCB0byBFUFNHOjM4NTcuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICovXG5cblxuZXhwb3J0IHZhciBQUk9KRUNUSU9OUyA9IFtuZXcgRVBTRzM4NTdQcm9qZWN0aW9uKCdFUFNHOjM4NTcnKSwgbmV3IEVQU0czODU3UHJvamVjdGlvbignRVBTRzoxMDIxMDAnKSwgbmV3IEVQU0czODU3UHJvamVjdGlvbignRVBTRzoxMDIxMTMnKSwgbmV3IEVQU0czODU3UHJvamVjdGlvbignRVBTRzo5MDA5MTMnKSwgbmV3IEVQU0czODU3UHJvamVjdGlvbignaHR0cDovL3d3dy5vcGVuZ2lzLm5ldC9nbWwvc3JzL2Vwc2cueG1sIzM4NTcnKV07XG4vKipcbiAqIFRyYW5zZm9ybWF0aW9uIGZyb20gRVBTRzo0MzI2IHRvIEVQU0c6Mzg1Ny5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X291dHB1dCBPdXRwdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9kaW1lbnNpb24gRGltZW5zaW9uIChkZWZhdWx0IGlzIGAyYCkuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPdXRwdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21FUFNHNDMyNihpbnB1dCwgb3B0X291dHB1dCwgb3B0X2RpbWVuc2lvbikge1xuICB2YXIgbGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICB2YXIgZGltZW5zaW9uID0gb3B0X2RpbWVuc2lvbiA+IDEgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgdmFyIG91dHB1dCA9IG9wdF9vdXRwdXQ7XG5cbiAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGRpbWVuc2lvbiA+IDIpIHtcbiAgICAgIC8vIHByZXNlcnZlIHZhbHVlcyBiZXlvbmQgc2Vjb25kIGRpbWVuc2lvblxuICAgICAgb3V0cHV0ID0gaW5wdXQuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0ID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gZGltZW5zaW9uKSB7XG4gICAgb3V0cHV0W2ldID0gSEFMRl9TSVpFICogaW5wdXRbaV0gLyAxODA7XG4gICAgdmFyIHkgPSBSQURJVVMgKiBNYXRoLmxvZyhNYXRoLnRhbihNYXRoLlBJICogKCtpbnB1dFtpICsgMV0gKyA5MCkgLyAzNjApKTtcblxuICAgIGlmICh5ID4gTUFYX1NBRkVfWSkge1xuICAgICAgeSA9IE1BWF9TQUZFX1k7XG4gICAgfSBlbHNlIGlmICh5IDwgLU1BWF9TQUZFX1kpIHtcbiAgICAgIHkgPSAtTUFYX1NBRkVfWTtcbiAgICB9XG5cbiAgICBvdXRwdXRbaSArIDFdID0geTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG4vKipcbiAqIFRyYW5zZm9ybWF0aW9uIGZyb20gRVBTRzozODU3IHRvIEVQU0c6NDMyNi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+PX0gb3B0X291dHB1dCBPdXRwdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9kaW1lbnNpb24gRGltZW5zaW9uIChkZWZhdWx0IGlzIGAyYCkuXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBPdXRwdXQgYXJyYXkgb2YgY29vcmRpbmF0ZSB2YWx1ZXMuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvRVBTRzQzMjYoaW5wdXQsIG9wdF9vdXRwdXQsIG9wdF9kaW1lbnNpb24pIHtcbiAgdmFyIGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgdmFyIGRpbWVuc2lvbiA9IG9wdF9kaW1lbnNpb24gPiAxID8gb3B0X2RpbWVuc2lvbiA6IDI7XG4gIHZhciBvdXRwdXQgPSBvcHRfb3V0cHV0O1xuXG4gIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkaW1lbnNpb24gPiAyKSB7XG4gICAgICAvLyBwcmVzZXJ2ZSB2YWx1ZXMgYmV5b25kIHNlY29uZCBkaW1lbnNpb25cbiAgICAgIG91dHB1dCA9IGlucHV0LnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dCA9IG5ldyBBcnJheShsZW5ndGgpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGRpbWVuc2lvbikge1xuICAgIG91dHB1dFtpXSA9IDE4MCAqIGlucHV0W2ldIC8gSEFMRl9TSVpFO1xuICAgIG91dHB1dFtpICsgMV0gPSAzNjAgKiBNYXRoLmF0YW4oTWF0aC5leHAoaW5wdXRbaSArIDFdIC8gUkFESVVTKSkgLyBNYXRoLlBJIC0gOTA7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufSIsImltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIi9ob21lL3J1bm5lci93b3JrL2p1c3RpY2U0MC10b29sL2p1c3RpY2U0MC10b29sL2NsaWVudC9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIi9ob21lL3J1bm5lci93b3JrL2p1c3RpY2U0MC10b29sL2p1c3RpY2U0MC10b29sL2NsaWVudC9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiL2hvbWUvcnVubmVyL3dvcmsvanVzdGljZTQwLXRvb2wvanVzdGljZTQwLXRvb2wvY2xpZW50L25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCI7XG5pbXBvcnQgX2dldFByb3RvdHlwZU9mIGZyb20gXCIvaG9tZS9ydW5uZXIvd29yay9qdXN0aWNlNDAtdG9vbC9qdXN0aWNlNDAtdG9vbC9jbGllbnQvbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mXCI7XG5cbmZ1bmN0aW9uIF9jcmVhdGVTdXBlcihEZXJpdmVkKSB7IHZhciBoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0ID0gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpOyByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7IHZhciBTdXBlciA9IF9nZXRQcm90b3R5cGVPZihEZXJpdmVkKSwgcmVzdWx0OyBpZiAoaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCkgeyB2YXIgTmV3VGFyZ2V0ID0gX2dldFByb3RvdHlwZU9mKHRoaXMpLmNvbnN0cnVjdG9yOyByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpOyB9IGVsc2UgeyByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9IHJldHVybiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCByZXN1bHQpOyB9OyB9XG5cbmZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7IGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTsgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTsgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTsgdHJ5IHsgQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZi5jYWxsKFJlZmxlY3QuY29uc3RydWN0KEJvb2xlYW4sIFtdLCBmdW5jdGlvbiAoKSB7fSkpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfVxuXG4vKipcbiAqIEBtb2R1bGUgb2wvcHJvai9lcHNnNDMyNlxuICovXG5pbXBvcnQgUHJvamVjdGlvbiBmcm9tICcuL1Byb2plY3Rpb24uanMnO1xuaW1wb3J0IFVuaXRzIGZyb20gJy4vVW5pdHMuanMnO1xuLyoqXG4gKiBTZW1pLW1ham9yIHJhZGl1cyBvZiB0aGUgV0dTODQgZWxsaXBzb2lkLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge251bWJlcn1cbiAqL1xuXG5leHBvcnQgdmFyIFJBRElVUyA9IDYzNzgxMzc7XG4vKipcbiAqIEV4dGVudCBvZiB0aGUgRVBTRzo0MzI2IHByb2plY3Rpb24gd2hpY2ggaXMgdGhlIHdob2xlIHdvcmxkLlxuICpcbiAqIEBjb25zdFxuICogQHR5cGUge2ltcG9ydChcIi4uL2V4dGVudC5qc1wiKS5FeHRlbnR9XG4gKi9cblxuZXhwb3J0IHZhciBFWFRFTlQgPSBbLTE4MCwgLTkwLCAxODAsIDkwXTtcbi8qKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5cbmV4cG9ydCB2YXIgTUVURVJTX1BFUl9VTklUID0gTWF0aC5QSSAqIFJBRElVUyAvIDE4MDtcbi8qKlxuICogQGNsYXNzZGVzY1xuICogUHJvamVjdGlvbiBvYmplY3QgZm9yIFdHUzg0IGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMgKEVQU0c6NDMyNikuXG4gKlxuICogTm90ZSB0aGF0IE9wZW5MYXllcnMgZG9lcyBub3Qgc3RyaWN0bHkgY29tcGx5IHdpdGggdGhlIEVQU0cgZGVmaW5pdGlvbi5cbiAqIFRoZSBFUFNHIHJlZ2lzdHJ5IGRlZmluZXMgNDMyNiBhcyBhIENSUyBmb3IgTGF0aXR1ZGUsTG9uZ2l0dWRlICh5LHgpLlxuICogT3BlbkxheWVycyB0cmVhdHMgRVBTRzo0MzI2IGFzIGEgcHNldWRvLXByb2plY3Rpb24sIHdpdGggeCx5IGNvb3JkaW5hdGVzLlxuICovXG5cbnZhciBFUFNHNDMyNlByb2plY3Rpb24gPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9Qcm9qZWN0aW9uKSB7XG4gIF9pbmhlcml0cyhFUFNHNDMyNlByb2plY3Rpb24sIF9Qcm9qZWN0aW9uKTtcblxuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKEVQU0c0MzI2UHJvamVjdGlvbik7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIENvZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X2F4aXNPcmllbnRhdGlvbiBBeGlzIG9yaWVudGF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gRVBTRzQzMjZQcm9qZWN0aW9uKGNvZGUsIG9wdF9heGlzT3JpZW50YXRpb24pIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRVBTRzQzMjZQcm9qZWN0aW9uKTtcblxuICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCB7XG4gICAgICBjb2RlOiBjb2RlLFxuICAgICAgdW5pdHM6IFVuaXRzLkRFR1JFRVMsXG4gICAgICBleHRlbnQ6IEVYVEVOVCxcbiAgICAgIGF4aXNPcmllbnRhdGlvbjogb3B0X2F4aXNPcmllbnRhdGlvbixcbiAgICAgIGdsb2JhbDogdHJ1ZSxcbiAgICAgIG1ldGVyc1BlclVuaXQ6IE1FVEVSU19QRVJfVU5JVCxcbiAgICAgIHdvcmxkRXh0ZW50OiBFWFRFTlRcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBFUFNHNDMyNlByb2plY3Rpb247XG59KFByb2plY3Rpb24pO1xuLyoqXG4gKiBQcm9qZWN0aW9ucyBlcXVhbCB0byBFUFNHOjQzMjYuXG4gKlxuICogQGNvbnN0XG4gKiBAdHlwZSB7QXJyYXk8aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICovXG5cblxuZXhwb3J0IHZhciBQUk9KRUNUSU9OUyA9IFtuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCdDUlM6ODQnKSwgbmV3IEVQU0c0MzI2UHJvamVjdGlvbignRVBTRzo0MzI2JywgJ25ldScpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCd1cm46b2djOmRlZjpjcnM6T0dDOjEuMzpDUlM4NCcpLCBuZXcgRVBTRzQzMjZQcm9qZWN0aW9uKCd1cm46b2djOmRlZjpjcnM6T0dDOjI6ODQnKSwgbmV3IEVQU0c0MzI2UHJvamVjdGlvbignaHR0cDovL3d3dy5vcGVuZ2lzLm5ldC9nbWwvc3JzL2Vwc2cueG1sIzQzMjYnLCAnbmV1JyldOyIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL3Byb2plY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgaW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHQ+fVxuICovXG52YXIgY2FjaGUgPSB7fTtcbi8qKlxuICogQ2xlYXIgdGhlIHByb2plY3Rpb25zIGNhY2hlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhcigpIHtcbiAgY2FjaGUgPSB7fTtcbn1cbi8qKlxuICogR2V0IGEgY2FjaGVkIHByb2plY3Rpb24gYnkgY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIFRoZSBjb2RlIGZvciB0aGUgcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBUaGUgcHJvamVjdGlvbiAoaWYgY2FjaGVkKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0KGNvZGUpIHtcbiAgcmV0dXJuIGNhY2hlW2NvZGVdIHx8IGNhY2hlW2NvZGUucmVwbGFjZSgvdXJuOih4LSk/b2djOmRlZjpjcnM6RVBTRzooLio6KT8oXFx3KykkLywgJ0VQU0c6JDMnKV0gfHwgbnVsbDtcbn1cbi8qKlxuICogQWRkIGEgcHJvamVjdGlvbiB0byB0aGUgY2FjaGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gY29kZSBUaGUgcHJvamVjdGlvbiBjb2RlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBUaGUgcHJvamVjdGlvbiB0byBjYWNoZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkKGNvZGUsIHByb2plY3Rpb24pIHtcbiAgY2FjaGVbY29kZV0gPSBwcm9qZWN0aW9uO1xufSIsIi8qKlxuICogQG1vZHVsZSBvbC9wcm9qL3RyYW5zZm9ybXNcbiAqL1xuaW1wb3J0IHsgaXNFbXB0eSB9IGZyb20gJy4uL29iai5qcyc7XG4vKipcbiAqIEBwcml2YXRlXG4gKiBAdHlwZSB7IU9iamVjdDxzdHJpbmcsIE9iamVjdDxzdHJpbmcsIGltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb24+Pn1cbiAqL1xuXG52YXIgdHJhbnNmb3JtcyA9IHt9O1xuLyoqXG4gKiBDbGVhciB0aGUgdHJhbnNmb3JtIGNhY2hlLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhcigpIHtcbiAgdHJhbnNmb3JtcyA9IHt9O1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgYSBjb252ZXJzaW9uIGZ1bmN0aW9uIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgZnJvbSB0aGUgc291cmNlXG4gKiBwcm9qZWN0aW9uIHRvIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9Qcm9qZWN0aW9uLmpzXCIpLmRlZmF1bHR9IHNvdXJjZSBTb3VyY2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVHJhbnNmb3JtLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGQoc291cmNlLCBkZXN0aW5hdGlvbiwgdHJhbnNmb3JtRm4pIHtcbiAgdmFyIHNvdXJjZUNvZGUgPSBzb3VyY2UuZ2V0Q29kZSgpO1xuICB2YXIgZGVzdGluYXRpb25Db2RlID0gZGVzdGluYXRpb24uZ2V0Q29kZSgpO1xuXG4gIGlmICghKHNvdXJjZUNvZGUgaW4gdHJhbnNmb3JtcykpIHtcbiAgICB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdID0ge307XG4gIH1cblxuICB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdW2Rlc3RpbmF0aW9uQ29kZV0gPSB0cmFuc2Zvcm1Gbjtcbn1cbi8qKlxuICogVW5yZWdpc3RlcnMgdGhlIGNvbnZlcnNpb24gZnVuY3Rpb24gdG8gY29udmVydCBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2VcbiAqIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24uICBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGNsZWFuIHVwXG4gKiBjYWNoZWQgdHJhbnNmb3JtcyBkdXJpbmcgdGVzdGluZy5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2UgU291cmNlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vUHJvamVjdGlvbi5qc1wiKS5kZWZhdWx0fSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi4vcHJvai5qc1wiKS5UcmFuc2Zvcm1GdW5jdGlvbn0gdHJhbnNmb3JtRm4gVGhlIHVucmVnaXN0ZXJlZCB0cmFuc2Zvcm0uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZShzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciBzb3VyY2VDb2RlID0gc291cmNlLmdldENvZGUoKTtcbiAgdmFyIGRlc3RpbmF0aW9uQ29kZSA9IGRlc3RpbmF0aW9uLmdldENvZGUoKTtcbiAgdmFyIHRyYW5zZm9ybSA9IHRyYW5zZm9ybXNbc291cmNlQ29kZV1bZGVzdGluYXRpb25Db2RlXTtcbiAgZGVsZXRlIHRyYW5zZm9ybXNbc291cmNlQ29kZV1bZGVzdGluYXRpb25Db2RlXTtcblxuICBpZiAoaXNFbXB0eSh0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdKSkge1xuICAgIGRlbGV0ZSB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybTtcbn1cbi8qKlxuICogR2V0IGEgdHJhbnNmb3JtIGdpdmVuIGEgc291cmNlIGNvZGUgYW5kIGEgZGVzdGluYXRpb24gY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VDb2RlIFRoZSBjb2RlIGZvciB0aGUgc291cmNlIHByb2plY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZGVzdGluYXRpb25Db2RlIFRoZSBjb2RlIGZvciB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4uL3Byb2ouanNcIikuVHJhbnNmb3JtRnVuY3Rpb258dW5kZWZpbmVkfSBUaGUgdHJhbnNmb3JtIGZ1bmN0aW9uIChpZiBmb3VuZCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldChzb3VyY2VDb2RlLCBkZXN0aW5hdGlvbkNvZGUpIHtcbiAgdmFyIHRyYW5zZm9ybTtcblxuICBpZiAoc291cmNlQ29kZSBpbiB0cmFuc2Zvcm1zICYmIGRlc3RpbmF0aW9uQ29kZSBpbiB0cmFuc2Zvcm1zW3NvdXJjZUNvZGVdKSB7XG4gICAgdHJhbnNmb3JtID0gdHJhbnNmb3Jtc1tzb3VyY2VDb2RlXVtkZXN0aW5hdGlvbkNvZGVdO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybTtcbn0iLCIvKipcbiAqIEBtb2R1bGUgb2wvZXh0ZW50XG4gKi9cbmltcG9ydCBDb3JuZXIgZnJvbSAnLi9leHRlbnQvQ29ybmVyLmpzJztcbmltcG9ydCBSZWxhdGlvbnNoaXAgZnJvbSAnLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzJztcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gJy4vYXNzZXJ0cy5qcyc7XG4vKipcbiAqIEFuIGFycmF5IG9mIG51bWJlcnMgcmVwcmVzZW50aW5nIGFuIGV4dGVudDogYFttaW54LCBtaW55LCBtYXh4LCBtYXh5XWAuXG4gKiBAdHlwZWRlZiB7QXJyYXk8bnVtYmVyPn0gRXh0ZW50XG4gKiBAYXBpXG4gKi9cblxuLyoqXG4gKiBCdWlsZCBhbiBleHRlbnQgdGhhdCBpbmNsdWRlcyBhbGwgZ2l2ZW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICogQHJldHVybiB7RXh0ZW50fSBCb3VuZGluZyBleHRlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGJvdW5kaW5nRXh0ZW50KGNvb3JkaW5hdGVzKSB7XG4gIHZhciBleHRlbnQgPSBjcmVhdGVFbXB0eSgpO1xuXG4gIGZvciAodmFyIGkgPSAwLCBpaSA9IGNvb3JkaW5hdGVzLmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICBleHRlbmRDb29yZGluYXRlKGV4dGVudCwgY29vcmRpbmF0ZXNbaV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSB4cyBYcy5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0geXMgWXMuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHByaXZhdGVcbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmZ1bmN0aW9uIF9ib3VuZGluZ0V4dGVudFhZcyh4cywgeXMsIG9wdF9leHRlbnQpIHtcbiAgdmFyIG1pblggPSBNYXRoLm1pbi5hcHBseShudWxsLCB4cyk7XG4gIHZhciBtaW5ZID0gTWF0aC5taW4uYXBwbHkobnVsbCwgeXMpO1xuICB2YXIgbWF4WCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIHhzKTtcbiAgdmFyIG1heFkgPSBNYXRoLm1heC5hcHBseShudWxsLCB5cyk7XG4gIHJldHVybiBjcmVhdGVPclVwZGF0ZShtaW5YLCBtaW5ZLCBtYXhYLCBtYXhZLCBvcHRfZXh0ZW50KTtcbn1cbi8qKlxuICogUmV0dXJuIGV4dGVudCBpbmNyZWFzZWQgYnkgdGhlIHByb3ZpZGVkIHZhbHVlLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIGFtb3VudCBieSB3aGljaCB0aGUgZXh0ZW50IHNob3VsZCBiZSBidWZmZXJlZC5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBidWZmZXIoZXh0ZW50LCB2YWx1ZSwgb3B0X2V4dGVudCkge1xuICBpZiAob3B0X2V4dGVudCkge1xuICAgIG9wdF9leHRlbnRbMF0gPSBleHRlbnRbMF0gLSB2YWx1ZTtcbiAgICBvcHRfZXh0ZW50WzFdID0gZXh0ZW50WzFdIC0gdmFsdWU7XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXSArIHZhbHVlO1xuICAgIG9wdF9leHRlbnRbM10gPSBleHRlbnRbM10gKyB2YWx1ZTtcbiAgICByZXR1cm4gb3B0X2V4dGVudDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW2V4dGVudFswXSAtIHZhbHVlLCBleHRlbnRbMV0gLSB2YWx1ZSwgZXh0ZW50WzJdICsgdmFsdWUsIGV4dGVudFszXSArIHZhbHVlXTtcbiAgfVxufVxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYW4gZXh0ZW50LlxuICpcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50IHRvIGNsb25lLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gVGhlIGNsb25lLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShleHRlbnQsIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gZXh0ZW50WzBdO1xuICAgIG9wdF9leHRlbnRbMV0gPSBleHRlbnRbMV07XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXTtcbiAgICBvcHRfZXh0ZW50WzNdID0gZXh0ZW50WzNdO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleHRlbnQuc2xpY2UoKTtcbiAgfVxufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4IFguXG4gKiBAcGFyYW0ge251bWJlcn0geSBZLlxuICogQHJldHVybiB7bnVtYmVyfSBDbG9zZXN0IHNxdWFyZWQgZGlzdGFuY2UuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb3Nlc3RTcXVhcmVkRGlzdGFuY2VYWShleHRlbnQsIHgsIHkpIHtcbiAgdmFyIGR4LCBkeTtcblxuICBpZiAoeCA8IGV4dGVudFswXSkge1xuICAgIGR4ID0gZXh0ZW50WzBdIC0geDtcbiAgfSBlbHNlIGlmIChleHRlbnRbMl0gPCB4KSB7XG4gICAgZHggPSB4IC0gZXh0ZW50WzJdO1xuICB9IGVsc2Uge1xuICAgIGR4ID0gMDtcbiAgfVxuXG4gIGlmICh5IDwgZXh0ZW50WzFdKSB7XG4gICAgZHkgPSBleHRlbnRbMV0gLSB5O1xuICB9IGVsc2UgaWYgKGV4dGVudFszXSA8IHkpIHtcbiAgICBkeSA9IHkgLSBleHRlbnRbM107XG4gIH0gZWxzZSB7XG4gICAgZHkgPSAwO1xuICB9XG5cbiAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5O1xufVxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgaXMgY29udGFpbmVkIG9yIG9uIHRoZSBlZGdlIG9mIHRoZSBleHRlbnQuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIENvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgY29vcmRpbmF0ZSBpcyBjb250YWluZWQgaW4gdGhlIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNDb29yZGluYXRlKGV4dGVudCwgY29vcmRpbmF0ZSkge1xuICByZXR1cm4gY29udGFpbnNYWShleHRlbnQsIGNvb3JkaW5hdGVbMF0sIGNvb3JkaW5hdGVbMV0pO1xufVxuLyoqXG4gKiBDaGVjayBpZiBvbmUgZXh0ZW50IGNvbnRhaW5zIGFub3RoZXIuXG4gKlxuICogQW4gZXh0ZW50IGlzIGRlZW1lZCBjb250YWluZWQgaWYgaXQgbGllcyBjb21wbGV0ZWx5IHdpdGhpbiB0aGUgb3RoZXIgZXh0ZW50LFxuICogaW5jbHVkaW5nIGlmIHRoZXkgc2hhcmUgb25lIG9yIG1vcmUgZWRnZXMuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQgMi5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSBzZWNvbmQgZXh0ZW50IGlzIGNvbnRhaW5lZCBieSBvciBvbiB0aGUgZWRnZSBvZiB0aGVcbiAqICAgICBmaXJzdC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY29udGFpbnNFeHRlbnQoZXh0ZW50MSwgZXh0ZW50Mikge1xuICByZXR1cm4gZXh0ZW50MVswXSA8PSBleHRlbnQyWzBdICYmIGV4dGVudDJbMl0gPD0gZXh0ZW50MVsyXSAmJiBleHRlbnQxWzFdIDw9IGV4dGVudDJbMV0gJiYgZXh0ZW50MlszXSA8PSBleHRlbnQxWzNdO1xufVxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcGFzc2VkIGNvb3JkaW5hdGUgaXMgY29udGFpbmVkIG9yIG9uIHRoZSBlZGdlIG9mIHRoZSBleHRlbnQuXG4gKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYIGNvb3JkaW5hdGUuXG4gKiBAcGFyYW0ge251bWJlcn0geSBZIGNvb3JkaW5hdGUuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgeCwgeSB2YWx1ZXMgYXJlIGNvbnRhaW5lZCBpbiB0aGUgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluc1hZKGV4dGVudCwgeCwgeSkge1xuICByZXR1cm4gZXh0ZW50WzBdIDw9IHggJiYgeCA8PSBleHRlbnRbMl0gJiYgZXh0ZW50WzFdIDw9IHkgJiYgeSA8PSBleHRlbnRbM107XG59XG4vKipcbiAqIEdldCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYSBjb29yZGluYXRlIGFuZCBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIFRoZSBjb29yZGluYXRlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzXCIpLmRlZmF1bHR9IFRoZSByZWxhdGlvbnNoaXAgKGJpdHdpc2UgY29tcGFyZSB3aXRoXG4gKiAgICAgaW1wb3J0KFwiLi9leHRlbnQvUmVsYXRpb25zaGlwLmpzXCIpLlJlbGF0aW9uc2hpcCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBjb29yZGluYXRlKSB7XG4gIHZhciBtaW5YID0gZXh0ZW50WzBdO1xuICB2YXIgbWluWSA9IGV4dGVudFsxXTtcbiAgdmFyIG1heFggPSBleHRlbnRbMl07XG4gIHZhciBtYXhZID0gZXh0ZW50WzNdO1xuICB2YXIgeCA9IGNvb3JkaW5hdGVbMF07XG4gIHZhciB5ID0gY29vcmRpbmF0ZVsxXTtcbiAgdmFyIHJlbGF0aW9uc2hpcCA9IFJlbGF0aW9uc2hpcC5VTktOT1dOO1xuXG4gIGlmICh4IDwgbWluWCkge1xuICAgIHJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcCB8IFJlbGF0aW9uc2hpcC5MRUZUO1xuICB9IGVsc2UgaWYgKHggPiBtYXhYKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLlJJR0hUO1xuICB9XG5cbiAgaWYgKHkgPCBtaW5ZKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLkJFTE9XO1xuICB9IGVsc2UgaWYgKHkgPiBtYXhZKSB7XG4gICAgcmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwIHwgUmVsYXRpb25zaGlwLkFCT1ZFO1xuICB9XG5cbiAgaWYgKHJlbGF0aW9uc2hpcCA9PT0gUmVsYXRpb25zaGlwLlVOS05PV04pIHtcbiAgICByZWxhdGlvbnNoaXAgPSBSZWxhdGlvbnNoaXAuSU5URVJTRUNUSU5HO1xuICB9XG5cbiAgcmV0dXJuIHJlbGF0aW9uc2hpcDtcbn1cbi8qKlxuICogQ3JlYXRlIGFuIGVtcHR5IGV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRW1wdHkgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFbXB0eSgpIHtcbiAgcmV0dXJuIFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGV4dGVudCBvciB1cGRhdGUgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5YIE1pbmltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtaW5ZIE1pbmltdW0gWS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhYIE1heGltdW0gWC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhZIE1heGltdW0gWS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBEZXN0aW5hdGlvbiBleHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGUobWluWCwgbWluWSwgbWF4WCwgbWF4WSwgb3B0X2V4dGVudCkge1xuICBpZiAob3B0X2V4dGVudCkge1xuICAgIG9wdF9leHRlbnRbMF0gPSBtaW5YO1xuICAgIG9wdF9leHRlbnRbMV0gPSBtaW5ZO1xuICAgIG9wdF9leHRlbnRbMl0gPSBtYXhYO1xuICAgIG9wdF9leHRlbnRbM10gPSBtYXhZO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbbWluWCwgbWluWSwgbWF4WCwgbWF4WV07XG4gIH1cbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGVtcHR5IGV4dGVudCBvciBtYWtlIHRoZSBwcm92aWRlZCBvbmUgZW1wdHkuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRW1wdHkob3B0X2V4dGVudCkge1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUoSW5maW5pdHksIEluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eSwgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZShjb29yZGluYXRlLCBvcHRfZXh0ZW50KSB7XG4gIHZhciB4ID0gY29vcmRpbmF0ZVswXTtcbiAgdmFyIHkgPSBjb29yZGluYXRlWzFdO1xuICByZXR1cm4gY3JlYXRlT3JVcGRhdGUoeCwgeSwgeCwgeSwgb3B0X2V4dGVudCk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+fSBjb29yZGluYXRlcyBDb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tQ29vcmRpbmF0ZXMoY29vcmRpbmF0ZXMsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGV4dGVudCA9IGNyZWF0ZU9yVXBkYXRlRW1wdHkob3B0X2V4dGVudCk7XG4gIHJldHVybiBleHRlbmRDb29yZGluYXRlcyhleHRlbnQsIGNvb3JkaW5hdGVzKTtcbn1cbi8qKlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBmbGF0Q29vcmRpbmF0ZXMgRmxhdCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgT2Zmc2V0LlxuICogQHBhcmFtIHtudW1iZXJ9IGVuZCBFbmQuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RyaWRlIFN0cmlkZS5cbiAqIEBwYXJhbSB7RXh0ZW50PX0gb3B0X2V4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JVcGRhdGVGcm9tRmxhdENvb3JkaW5hdGVzKGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSwgb3B0X2V4dGVudCkge1xuICB2YXIgZXh0ZW50ID0gY3JlYXRlT3JVcGRhdGVFbXB0eShvcHRfZXh0ZW50KTtcbiAgcmV0dXJuIGV4dGVuZEZsYXRDb29yZGluYXRlcyhleHRlbnQsIGZsYXRDb29yZGluYXRlcywgb2Zmc2V0LCBlbmQsIHN0cmlkZSk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGU+Pn0gcmluZ3MgUmluZ3MuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9yVXBkYXRlRnJvbVJpbmdzKHJpbmdzLCBvcHRfZXh0ZW50KSB7XG4gIHZhciBleHRlbnQgPSBjcmVhdGVPclVwZGF0ZUVtcHR5KG9wdF9leHRlbnQpO1xuICByZXR1cm4gZXh0ZW5kUmluZ3MoZXh0ZW50LCByaW5ncyk7XG59XG4vKipcbiAqIERldGVybWluZSBpZiB0d28gZXh0ZW50cyBhcmUgZXF1aXZhbGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtib29sZWFufSBUaGUgdHdvIGV4dGVudHMgYXJlIGVxdWl2YWxlbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGVxdWFscyhleHRlbnQxLCBleHRlbnQyKSB7XG4gIHJldHVybiBleHRlbnQxWzBdID09IGV4dGVudDJbMF0gJiYgZXh0ZW50MVsyXSA9PSBleHRlbnQyWzJdICYmIGV4dGVudDFbMV0gPT0gZXh0ZW50MlsxXSAmJiBleHRlbnQxWzNdID09IGV4dGVudDJbM107XG59XG4vKipcbiAqIERldGVybWluZSBpZiB0d28gZXh0ZW50cyBhcmUgYXBwcm94aW1hdGVseSBlcXVpdmFsZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgRXh0ZW50IDEuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MiBFeHRlbnQgMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0b2xlcmFuY2UgVG9sZXJhbmNlIGluIGV4dGVudCBjb29yZGluYXRlIHVuaXRzLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHR3byBleHRlbnRzIGRpZmZlciBieSBsZXNzIHRoYW4gdGhlIHRvbGVyYW5jZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwcm94aW1hdGVseUVxdWFscyhleHRlbnQxLCBleHRlbnQyLCB0b2xlcmFuY2UpIHtcbiAgcmV0dXJuIE1hdGguYWJzKGV4dGVudDFbMF0gLSBleHRlbnQyWzBdKSA8IHRvbGVyYW5jZSAmJiBNYXRoLmFicyhleHRlbnQxWzJdIC0gZXh0ZW50MlsyXSkgPCB0b2xlcmFuY2UgJiYgTWF0aC5hYnMoZXh0ZW50MVsxXSAtIGV4dGVudDJbMV0pIDwgdG9sZXJhbmNlICYmIE1hdGguYWJzKGV4dGVudDFbM10gLSBleHRlbnQyWzNdKSA8IHRvbGVyYW5jZTtcbn1cbi8qKlxuICogTW9kaWZ5IGFuIGV4dGVudCB0byBpbmNsdWRlIGFub3RoZXIgZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDEgVGhlIGV4dGVudCB0byBiZSBtb2RpZmllZC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIFRoZSBleHRlbnQgdGhhdCB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBmaXJzdC5cbiAqIEByZXR1cm4ge0V4dGVudH0gQSByZWZlcmVuY2UgdG8gdGhlIGZpcnN0IChleHRlbmRlZCkgZXh0ZW50LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBleHRlbmQoZXh0ZW50MSwgZXh0ZW50Mikge1xuICBpZiAoZXh0ZW50MlswXSA8IGV4dGVudDFbMF0pIHtcbiAgICBleHRlbnQxWzBdID0gZXh0ZW50MlswXTtcbiAgfVxuXG4gIGlmIChleHRlbnQyWzJdID4gZXh0ZW50MVsyXSkge1xuICAgIGV4dGVudDFbMl0gPSBleHRlbnQyWzJdO1xuICB9XG5cbiAgaWYgKGV4dGVudDJbMV0gPCBleHRlbnQxWzFdKSB7XG4gICAgZXh0ZW50MVsxXSA9IGV4dGVudDJbMV07XG4gIH1cblxuICBpZiAoZXh0ZW50MlszXSA+IGV4dGVudDFbM10pIHtcbiAgICBleHRlbnQxWzNdID0gZXh0ZW50MlszXTtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQxO1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kQ29vcmRpbmF0ZShleHRlbnQsIGNvb3JkaW5hdGUpIHtcbiAgaWYgKGNvb3JkaW5hdGVbMF0gPCBleHRlbnRbMF0pIHtcbiAgICBleHRlbnRbMF0gPSBjb29yZGluYXRlWzBdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMF0gPiBleHRlbnRbMl0pIHtcbiAgICBleHRlbnRbMl0gPSBjb29yZGluYXRlWzBdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMV0gPCBleHRlbnRbMV0pIHtcbiAgICBleHRlbnRbMV0gPSBjb29yZGluYXRlWzFdO1xuICB9XG5cbiAgaWYgKGNvb3JkaW5hdGVbMV0gPiBleHRlbnRbM10pIHtcbiAgICBleHRlbnRbM10gPSBjb29yZGluYXRlWzFdO1xuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtBcnJheTxpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZT59IGNvb3JkaW5hdGVzIENvb3JkaW5hdGVzLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZENvb3JkaW5hdGVzKGV4dGVudCwgY29vcmRpbmF0ZXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGV4dGVuZENvb3JkaW5hdGUoZXh0ZW50LCBjb29yZGluYXRlc1tpXSk7XG4gIH1cblxuICByZXR1cm4gZXh0ZW50O1xufVxuLyoqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gZmxhdENvb3JkaW5hdGVzIEZsYXQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IE9mZnNldC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0cmlkZSBTdHJpZGUuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kRmxhdENvb3JkaW5hdGVzKGV4dGVudCwgZmxhdENvb3JkaW5hdGVzLCBvZmZzZXQsIGVuZCwgc3RyaWRlKSB7XG4gIGZvciAoOyBvZmZzZXQgPCBlbmQ7IG9mZnNldCArPSBzdHJpZGUpIHtcbiAgICBleHRlbmRYWShleHRlbnQsIGZsYXRDb29yZGluYXRlc1tvZmZzZXRdLCBmbGF0Q29vcmRpbmF0ZXNbb2Zmc2V0ICsgMV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlPj59IHJpbmdzIFJpbmdzLlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZFJpbmdzKGV4dGVudCwgcmluZ3MpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gcmluZ3MubGVuZ3RoOyBpIDwgaWk7ICsraSkge1xuICAgIGV4dGVuZENvb3JkaW5hdGVzKGV4dGVudCwgcmluZ3NbaV0pO1xuICB9XG5cbiAgcmV0dXJuIGV4dGVudDtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0geCBYLlxuICogQHBhcmFtIHtudW1iZXJ9IHkgWS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXh0ZW5kWFkoZXh0ZW50LCB4LCB5KSB7XG4gIGV4dGVudFswXSA9IE1hdGgubWluKGV4dGVudFswXSwgeCk7XG4gIGV4dGVudFsxXSA9IE1hdGgubWluKGV4dGVudFsxXSwgeSk7XG4gIGV4dGVudFsyXSA9IE1hdGgubWF4KGV4dGVudFsyXSwgeCk7XG4gIGV4dGVudFszXSA9IE1hdGgubWF4KGV4dGVudFszXSwgeSk7XG59XG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gY2FsbHMgYGNhbGxiYWNrYCBmb3IgZWFjaCBjb3JuZXIgb2YgdGhlIGV4dGVudC4gSWYgdGhlXG4gKiBjYWxsYmFjayByZXR1cm5zIGEgdHJ1dGh5IHZhbHVlIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRoYXQgdmFsdWVcbiAqIGltbWVkaWF0ZWx5LiBPdGhlcndpc2UgdGhlIGZ1bmN0aW9uIHJldHVybnMgYGZhbHNlYC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IFN9IGNhbGxiYWNrIENhbGxiYWNrLlxuICogQHJldHVybiB7U3xib29sZWFufSBWYWx1ZS5cbiAqIEB0ZW1wbGF0ZSBTXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2hDb3JuZXIoZXh0ZW50LCBjYWxsYmFjaykge1xuICB2YXIgdmFsO1xuICB2YWwgPSBjYWxsYmFjayhnZXRCb3R0b21MZWZ0KGV4dGVudCkpO1xuXG4gIGlmICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgdmFsID0gY2FsbGJhY2soZ2V0Qm90dG9tUmlnaHQoZXh0ZW50KSk7XG5cbiAgaWYgKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICB2YWwgPSBjYWxsYmFjayhnZXRUb3BSaWdodChleHRlbnQpKTtcblxuICBpZiAodmFsKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIHZhbCA9IGNhbGxiYWNrKGdldFRvcExlZnQoZXh0ZW50KSk7XG5cbiAgaWYgKHZhbCkge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG4vKipcbiAqIEdldCB0aGUgc2l6ZSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gQXJlYS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXJlYShleHRlbnQpIHtcbiAgdmFyIGFyZWEgPSAwO1xuXG4gIGlmICghaXNFbXB0eShleHRlbnQpKSB7XG4gICAgYXJlYSA9IGdldFdpZHRoKGV4dGVudCkgKiBnZXRIZWlnaHQoZXh0ZW50KTtcbiAgfVxuXG4gIHJldHVybiBhcmVhO1xufVxuLyoqXG4gKiBHZXQgdGhlIGJvdHRvbSBsZWZ0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQm90dG9tIGxlZnQgY29vcmRpbmF0ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Qm90dG9tTGVmdChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMF0sIGV4dGVudFsxXV07XG59XG4vKipcbiAqIEdldCB0aGUgYm90dG9tIHJpZ2h0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gQm90dG9tIHJpZ2h0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJvdHRvbVJpZ2h0KGV4dGVudCkge1xuICByZXR1cm4gW2V4dGVudFsyXSwgZXh0ZW50WzFdXTtcbn1cbi8qKlxuICogR2V0IHRoZSBjZW50ZXIgY29vcmRpbmF0ZSBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDZW50ZXIuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENlbnRlcihleHRlbnQpIHtcbiAgcmV0dXJuIFsoZXh0ZW50WzBdICsgZXh0ZW50WzJdKSAvIDIsIChleHRlbnRbMV0gKyBleHRlbnRbM10pIC8gMl07XG59XG4vKipcbiAqIEdldCBhIGNvcm5lciBjb29yZGluYXRlIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC9Db3JuZXIuanNcIikuZGVmYXVsdH0gY29ybmVyIENvcm5lci5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb3JuZXIgY29vcmRpbmF0ZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29ybmVyKGV4dGVudCwgY29ybmVyKSB7XG4gIHZhciBjb29yZGluYXRlO1xuXG4gIGlmIChjb3JuZXIgPT09IENvcm5lci5CT1RUT01fTEVGVCkge1xuICAgIGNvb3JkaW5hdGUgPSBnZXRCb3R0b21MZWZ0KGV4dGVudCk7XG4gIH0gZWxzZSBpZiAoY29ybmVyID09PSBDb3JuZXIuQk9UVE9NX1JJR0hUKSB7XG4gICAgY29vcmRpbmF0ZSA9IGdldEJvdHRvbVJpZ2h0KGV4dGVudCk7XG4gIH0gZWxzZSBpZiAoY29ybmVyID09PSBDb3JuZXIuVE9QX0xFRlQpIHtcbiAgICBjb29yZGluYXRlID0gZ2V0VG9wTGVmdChleHRlbnQpO1xuICB9IGVsc2UgaWYgKGNvcm5lciA9PT0gQ29ybmVyLlRPUF9SSUdIVCkge1xuICAgIGNvb3JkaW5hdGUgPSBnZXRUb3BSaWdodChleHRlbnQpO1xuICB9IGVsc2Uge1xuICAgIGFzc2VydChmYWxzZSwgMTMpOyAvLyBJbnZhbGlkIGNvcm5lclxuICB9XG5cbiAgcmV0dXJuIGNvb3JkaW5hdGU7XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEVubGFyZ2VkIGFyZWEuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEVubGFyZ2VkQXJlYShleHRlbnQxLCBleHRlbnQyKSB7XG4gIHZhciBtaW5YID0gTWF0aC5taW4oZXh0ZW50MVswXSwgZXh0ZW50MlswXSk7XG4gIHZhciBtaW5ZID0gTWF0aC5taW4oZXh0ZW50MVsxXSwgZXh0ZW50MlsxXSk7XG4gIHZhciBtYXhYID0gTWF0aC5tYXgoZXh0ZW50MVsyXSwgZXh0ZW50MlsyXSk7XG4gIHZhciBtYXhZID0gTWF0aC5tYXgoZXh0ZW50MVszXSwgZXh0ZW50MlszXSk7XG4gIHJldHVybiAobWF4WCAtIG1pblgpICogKG1heFkgLSBtaW5ZKTtcbn1cbi8qKlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY2VudGVyIENlbnRlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIFJlc29sdXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gcm90YXRpb24gUm90YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBzaXplIFNpemUuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHJldHVybiB7RXh0ZW50fSBFeHRlbnQuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvclZpZXdBbmRTaXplKGNlbnRlciwgcmVzb2x1dGlvbiwgcm90YXRpb24sIHNpemUsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGR4ID0gcmVzb2x1dGlvbiAqIHNpemVbMF0gLyAyO1xuICB2YXIgZHkgPSByZXNvbHV0aW9uICogc2l6ZVsxXSAvIDI7XG4gIHZhciBjb3NSb3RhdGlvbiA9IE1hdGguY29zKHJvdGF0aW9uKTtcbiAgdmFyIHNpblJvdGF0aW9uID0gTWF0aC5zaW4ocm90YXRpb24pO1xuICB2YXIgeENvcyA9IGR4ICogY29zUm90YXRpb247XG4gIHZhciB4U2luID0gZHggKiBzaW5Sb3RhdGlvbjtcbiAgdmFyIHlDb3MgPSBkeSAqIGNvc1JvdGF0aW9uO1xuICB2YXIgeVNpbiA9IGR5ICogc2luUm90YXRpb247XG4gIHZhciB4ID0gY2VudGVyWzBdO1xuICB2YXIgeSA9IGNlbnRlclsxXTtcbiAgdmFyIHgwID0geCAtIHhDb3MgKyB5U2luO1xuICB2YXIgeDEgPSB4IC0geENvcyAtIHlTaW47XG4gIHZhciB4MiA9IHggKyB4Q29zIC0geVNpbjtcbiAgdmFyIHgzID0geCArIHhDb3MgKyB5U2luO1xuICB2YXIgeTAgPSB5IC0geFNpbiAtIHlDb3M7XG4gIHZhciB5MSA9IHkgLSB4U2luICsgeUNvcztcbiAgdmFyIHkyID0geSArIHhTaW4gKyB5Q29zO1xuICB2YXIgeTMgPSB5ICsgeFNpbiAtIHlDb3M7XG4gIHJldHVybiBjcmVhdGVPclVwZGF0ZShNYXRoLm1pbih4MCwgeDEsIHgyLCB4MyksIE1hdGgubWluKHkwLCB5MSwgeTIsIHkzKSwgTWF0aC5tYXgoeDAsIHgxLCB4MiwgeDMpLCBNYXRoLm1heCh5MCwgeTEsIHkyLCB5MyksIG9wdF9leHRlbnQpO1xufVxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gSGVpZ2h0LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIZWlnaHQoZXh0ZW50KSB7XG4gIHJldHVybiBleHRlbnRbM10gLSBleHRlbnRbMV07XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQxIEV4dGVudCAxLlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudDIgRXh0ZW50IDIuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEludGVyc2VjdGlvbiBhcmVhLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbnRlcnNlY3Rpb25BcmVhKGV4dGVudDEsIGV4dGVudDIpIHtcbiAgdmFyIGludGVyc2VjdGlvbiA9IGdldEludGVyc2VjdGlvbihleHRlbnQxLCBleHRlbnQyKTtcbiAgcmV0dXJuIGdldEFyZWEoaW50ZXJzZWN0aW9uKTtcbn1cbi8qKlxuICogR2V0IHRoZSBpbnRlcnNlY3Rpb24gb2YgdHdvIGV4dGVudHMuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudCAyLlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IE9wdGlvbmFsIGV4dGVudCB0byBwb3B1bGF0ZSB3aXRoIGludGVyc2VjdGlvbi5cbiAqIEByZXR1cm4ge0V4dGVudH0gSW50ZXJzZWN0aW5nIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9uKGV4dGVudDEsIGV4dGVudDIsIG9wdF9leHRlbnQpIHtcbiAgdmFyIGludGVyc2VjdGlvbiA9IG9wdF9leHRlbnQgPyBvcHRfZXh0ZW50IDogY3JlYXRlRW1wdHkoKTtcblxuICBpZiAoaW50ZXJzZWN0cyhleHRlbnQxLCBleHRlbnQyKSkge1xuICAgIGlmIChleHRlbnQxWzBdID4gZXh0ZW50MlswXSkge1xuICAgICAgaW50ZXJzZWN0aW9uWzBdID0gZXh0ZW50MVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJzZWN0aW9uWzBdID0gZXh0ZW50MlswXTtcbiAgICB9XG5cbiAgICBpZiAoZXh0ZW50MVsxXSA+IGV4dGVudDJbMV0pIHtcbiAgICAgIGludGVyc2VjdGlvblsxXSA9IGV4dGVudDFbMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGludGVyc2VjdGlvblsxXSA9IGV4dGVudDJbMV07XG4gICAgfVxuXG4gICAgaWYgKGV4dGVudDFbMl0gPCBleHRlbnQyWzJdKSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMl0gPSBleHRlbnQxWzJdO1xuICAgIH0gZWxzZSB7XG4gICAgICBpbnRlcnNlY3Rpb25bMl0gPSBleHRlbnQyWzJdO1xuICAgIH1cblxuICAgIGlmIChleHRlbnQxWzNdIDwgZXh0ZW50MlszXSkge1xuICAgICAgaW50ZXJzZWN0aW9uWzNdID0gZXh0ZW50MVszXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW50ZXJzZWN0aW9uWzNdID0gZXh0ZW50MlszXTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY3JlYXRlT3JVcGRhdGVFbXB0eShpbnRlcnNlY3Rpb24pO1xuICB9XG5cbiAgcmV0dXJuIGludGVyc2VjdGlvbjtcbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IE1hcmdpbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFyZ2luKGV4dGVudCkge1xuICByZXR1cm4gZ2V0V2lkdGgoZXh0ZW50KSArIGdldEhlaWdodChleHRlbnQpO1xufVxuLyoqXG4gKiBHZXQgdGhlIHNpemUgKHdpZHRoLCBoZWlnaHQpIG9mIGFuIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgVGhlIGV4dGVudC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vc2l6ZS5qc1wiKS5TaXplfSBUaGUgZXh0ZW50IHNpemUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNpemUoZXh0ZW50KSB7XG4gIHJldHVybiBbZXh0ZW50WzJdIC0gZXh0ZW50WzBdLCBleHRlbnRbM10gLSBleHRlbnRbMV1dO1xufVxuLyoqXG4gKiBHZXQgdGhlIHRvcCBsZWZ0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVG9wIGxlZnQgY29vcmRpbmF0ZS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VG9wTGVmdChleHRlbnQpIHtcbiAgcmV0dXJuIFtleHRlbnRbMF0sIGV4dGVudFszXV07XG59XG4vKipcbiAqIEdldCB0aGUgdG9wIHJpZ2h0IGNvb3JkaW5hdGUgb2YgYW4gZXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gVG9wIHJpZ2h0IGNvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRvcFJpZ2h0KGV4dGVudCkge1xuICByZXR1cm4gW2V4dGVudFsyXSwgZXh0ZW50WzNdXTtcbn1cbi8qKlxuICogR2V0IHRoZSB3aWR0aCBvZiBhbiBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge251bWJlcn0gV2lkdGguXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdpZHRoKGV4dGVudCkge1xuICByZXR1cm4gZXh0ZW50WzJdIC0gZXh0ZW50WzBdO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgb25lIGV4dGVudCBpbnRlcnNlY3RzIGFub3RoZXIuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50MSBFeHRlbnQgMS5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQyIEV4dGVudC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRoZSB0d28gZXh0ZW50cyBpbnRlcnNlY3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGludGVyc2VjdHMoZXh0ZW50MSwgZXh0ZW50Mikge1xuICByZXR1cm4gZXh0ZW50MVswXSA8PSBleHRlbnQyWzJdICYmIGV4dGVudDFbMl0gPj0gZXh0ZW50MlswXSAmJiBleHRlbnQxWzFdIDw9IGV4dGVudDJbM10gJiYgZXh0ZW50MVszXSA+PSBleHRlbnQyWzFdO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gZXh0ZW50IGlzIGVtcHR5LlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBJcyBlbXB0eS5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShleHRlbnQpIHtcbiAgcmV0dXJuIGV4dGVudFsyXSA8IGV4dGVudFswXSB8fCBleHRlbnRbM10gPCBleHRlbnRbMV07XG59XG4vKipcbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgRXh0ZW50LlxuICogQHBhcmFtIHtFeHRlbnQ9fSBvcHRfZXh0ZW50IEV4dGVudC5cbiAqIEByZXR1cm4ge0V4dGVudH0gRXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiByZXR1cm5PclVwZGF0ZShleHRlbnQsIG9wdF9leHRlbnQpIHtcbiAgaWYgKG9wdF9leHRlbnQpIHtcbiAgICBvcHRfZXh0ZW50WzBdID0gZXh0ZW50WzBdO1xuICAgIG9wdF9leHRlbnRbMV0gPSBleHRlbnRbMV07XG4gICAgb3B0X2V4dGVudFsyXSA9IGV4dGVudFsyXTtcbiAgICBvcHRfZXh0ZW50WzNdID0gZXh0ZW50WzNdO1xuICAgIHJldHVybiBvcHRfZXh0ZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBleHRlbnQ7XG4gIH1cbn1cbi8qKlxuICogQHBhcmFtIHtFeHRlbnR9IGV4dGVudCBFeHRlbnQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHNjYWxlRnJvbUNlbnRlcihleHRlbnQsIHZhbHVlKSB7XG4gIHZhciBkZWx0YVggPSAoZXh0ZW50WzJdIC0gZXh0ZW50WzBdKSAvIDIgKiAodmFsdWUgLSAxKTtcbiAgdmFyIGRlbHRhWSA9IChleHRlbnRbM10gLSBleHRlbnRbMV0pIC8gMiAqICh2YWx1ZSAtIDEpO1xuICBleHRlbnRbMF0gLT0gZGVsdGFYO1xuICBleHRlbnRbMl0gKz0gZGVsdGFYO1xuICBleHRlbnRbMV0gLT0gZGVsdGFZO1xuICBleHRlbnRbM10gKz0gZGVsdGFZO1xufVxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgdGhlIHNlZ21lbnQgYmV0d2VlbiB0d28gY29vcmRpbmF0ZXMgaW50ZXJzZWN0cyAoY3Jvc3NlcyxcbiAqIHRvdWNoZXMsIG9yIGlzIGNvbnRhaW5lZCBieSkgdGhlIHByb3ZpZGVkIGV4dGVudC5cbiAqIEBwYXJhbSB7RXh0ZW50fSBleHRlbnQgVGhlIGV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHN0YXJ0IFNlZ21lbnQgc3RhcnQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGVuZCBTZWdtZW50IGVuZCBjb29yZGluYXRlLlxuICogQHJldHVybiB7Ym9vbGVhbn0gVGhlIHNlZ21lbnQgaW50ZXJzZWN0cyB0aGUgZXh0ZW50LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RzU2VnbWVudChleHRlbnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGludGVyc2VjdHMgPSBmYWxzZTtcbiAgdmFyIHN0YXJ0UmVsID0gY29vcmRpbmF0ZVJlbGF0aW9uc2hpcChleHRlbnQsIHN0YXJ0KTtcbiAgdmFyIGVuZFJlbCA9IGNvb3JkaW5hdGVSZWxhdGlvbnNoaXAoZXh0ZW50LCBlbmQpO1xuXG4gIGlmIChzdGFydFJlbCA9PT0gUmVsYXRpb25zaGlwLklOVEVSU0VDVElORyB8fCBlbmRSZWwgPT09IFJlbGF0aW9uc2hpcC5JTlRFUlNFQ1RJTkcpIHtcbiAgICBpbnRlcnNlY3RzID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbWluWCA9IGV4dGVudFswXTtcbiAgICB2YXIgbWluWSA9IGV4dGVudFsxXTtcbiAgICB2YXIgbWF4WCA9IGV4dGVudFsyXTtcbiAgICB2YXIgbWF4WSA9IGV4dGVudFszXTtcbiAgICB2YXIgc3RhcnRYID0gc3RhcnRbMF07XG4gICAgdmFyIHN0YXJ0WSA9IHN0YXJ0WzFdO1xuICAgIHZhciBlbmRYID0gZW5kWzBdO1xuICAgIHZhciBlbmRZID0gZW5kWzFdO1xuICAgIHZhciBzbG9wZSA9IChlbmRZIC0gc3RhcnRZKSAvIChlbmRYIC0gc3RhcnRYKTtcbiAgICB2YXIgeCwgeTtcblxuICAgIGlmICghIShlbmRSZWwgJiBSZWxhdGlvbnNoaXAuQUJPVkUpICYmICEoc3RhcnRSZWwgJiBSZWxhdGlvbnNoaXAuQUJPVkUpKSB7XG4gICAgICAvLyBwb3RlbnRpYWxseSBpbnRlcnNlY3RzIHRvcFxuICAgICAgeCA9IGVuZFggLSAoZW5kWSAtIG1heFkpIC8gc2xvcGU7XG4gICAgICBpbnRlcnNlY3RzID0geCA+PSBtaW5YICYmIHggPD0gbWF4WDtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHMgJiYgISEoZW5kUmVsICYgUmVsYXRpb25zaGlwLlJJR0hUKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLlJJR0hUKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyByaWdodFxuICAgICAgeSA9IGVuZFkgLSAoZW5kWCAtIG1heFgpICogc2xvcGU7XG4gICAgICBpbnRlcnNlY3RzID0geSA+PSBtaW5ZICYmIHkgPD0gbWF4WTtcbiAgICB9XG5cbiAgICBpZiAoIWludGVyc2VjdHMgJiYgISEoZW5kUmVsICYgUmVsYXRpb25zaGlwLkJFTE9XKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLkJFTE9XKSkge1xuICAgICAgLy8gcG90ZW50aWFsbHkgaW50ZXJzZWN0cyBib3R0b21cbiAgICAgIHggPSBlbmRYIC0gKGVuZFkgLSBtaW5ZKSAvIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHggPj0gbWluWCAmJiB4IDw9IG1heFg7XG4gICAgfVxuXG4gICAgaWYgKCFpbnRlcnNlY3RzICYmICEhKGVuZFJlbCAmIFJlbGF0aW9uc2hpcC5MRUZUKSAmJiAhKHN0YXJ0UmVsICYgUmVsYXRpb25zaGlwLkxFRlQpKSB7XG4gICAgICAvLyBwb3RlbnRpYWxseSBpbnRlcnNlY3RzIGxlZnRcbiAgICAgIHkgPSBlbmRZIC0gKGVuZFggLSBtaW5YKSAqIHNsb3BlO1xuICAgICAgaW50ZXJzZWN0cyA9IHkgPj0gbWluWSAmJiB5IDw9IG1heFk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGludGVyc2VjdHM7XG59XG4vKipcbiAqIEFwcGx5IGEgdHJhbnNmb3JtIGZ1bmN0aW9uIHRvIHRoZSBleHRlbnQuXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qLmpzXCIpLlRyYW5zZm9ybUZ1bmN0aW9ufSB0cmFuc2Zvcm1GbiBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBDYWxsZWQgd2l0aCBgW21pblgsIG1pblksIG1heFgsIG1heFldYCBleHRlbnQgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0ge0V4dGVudD19IG9wdF9leHRlbnQgRGVzdGluYXRpb24gZXh0ZW50LlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfc3RvcHMgTnVtYmVyIG9mIHN0b3BzIHBlciBzaWRlIHVzZWQgZm9yIHRoZSB0cmFuc2Zvcm0uXG4gKiBCeSBkZWZhdWx0IG9ubHkgdGhlIGNvcm5lcnMgYXJlIHVzZWQuXG4gKiBAcmV0dXJuIHtFeHRlbnR9IEV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlUcmFuc2Zvcm0oZXh0ZW50LCB0cmFuc2Zvcm1Gbiwgb3B0X2V4dGVudCwgb3B0X3N0b3BzKSB7XG4gIHZhciBjb29yZGluYXRlcyA9IFtdO1xuXG4gIGlmIChvcHRfc3RvcHMgPiAxKSB7XG4gICAgdmFyIHdpZHRoID0gZXh0ZW50WzJdIC0gZXh0ZW50WzBdO1xuICAgIHZhciBoZWlnaHQgPSBleHRlbnRbM10gLSBleHRlbnRbMV07XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdF9zdG9wczsgKytpKSB7XG4gICAgICBjb29yZGluYXRlcy5wdXNoKGV4dGVudFswXSArIHdpZHRoICogaSAvIG9wdF9zdG9wcywgZXh0ZW50WzFdLCBleHRlbnRbMl0sIGV4dGVudFsxXSArIGhlaWdodCAqIGkgLyBvcHRfc3RvcHMsIGV4dGVudFsyXSAtIHdpZHRoICogaSAvIG9wdF9zdG9wcywgZXh0ZW50WzNdLCBleHRlbnRbMF0sIGV4dGVudFszXSAtIGhlaWdodCAqIGkgLyBvcHRfc3RvcHMpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjb29yZGluYXRlcyA9IFtleHRlbnRbMF0sIGV4dGVudFsxXSwgZXh0ZW50WzJdLCBleHRlbnRbMV0sIGV4dGVudFsyXSwgZXh0ZW50WzNdLCBleHRlbnRbMF0sIGV4dGVudFszXV07XG4gIH1cblxuICB0cmFuc2Zvcm1Gbihjb29yZGluYXRlcywgY29vcmRpbmF0ZXMsIDIpO1xuICB2YXIgeHMgPSBbXTtcbiAgdmFyIHlzID0gW107XG5cbiAgZm9yICh2YXIgX2kgPSAwLCBsID0gY29vcmRpbmF0ZXMubGVuZ3RoOyBfaSA8IGw7IF9pICs9IDIpIHtcbiAgICB4cy5wdXNoKGNvb3JkaW5hdGVzW19pXSk7XG4gICAgeXMucHVzaChjb29yZGluYXRlc1tfaSArIDFdKTtcbiAgfVxuXG4gIHJldHVybiBfYm91bmRpbmdFeHRlbnRYWXMoeHMsIHlzLCBvcHRfZXh0ZW50KTtcbn1cbi8qKlxuICogTW9kaWZpZXMgdGhlIHByb3ZpZGVkIGV4dGVudCBpbi1wbGFjZSB0byBiZSB3aXRoaW4gdGhlIHJlYWwgd29ybGRcbiAqIGV4dGVudC5cbiAqXG4gKiBAcGFyYW0ge0V4dGVudH0gZXh0ZW50IEV4dGVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9wcm9qL1Byb2plY3Rpb24uanNcIikuZGVmYXVsdH0gcHJvamVjdGlvbiBQcm9qZWN0aW9uXG4gKiBAcmV0dXJuIHtFeHRlbnR9IFRoZSBleHRlbnQgd2l0aGluIHRoZSByZWFsIHdvcmxkIGV4dGVudC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gd3JhcFgoZXh0ZW50LCBwcm9qZWN0aW9uKSB7XG4gIHZhciBwcm9qZWN0aW9uRXh0ZW50ID0gcHJvamVjdGlvbi5nZXRFeHRlbnQoKTtcbiAgdmFyIGNlbnRlciA9IGdldENlbnRlcihleHRlbnQpO1xuXG4gIGlmIChwcm9qZWN0aW9uLmNhbldyYXBYKCkgJiYgKGNlbnRlclswXSA8IHByb2plY3Rpb25FeHRlbnRbMF0gfHwgY2VudGVyWzBdID49IHByb2plY3Rpb25FeHRlbnRbMl0pKSB7XG4gICAgdmFyIHdvcmxkV2lkdGggPSBnZXRXaWR0aChwcm9qZWN0aW9uRXh0ZW50KTtcbiAgICB2YXIgd29ybGRzQXdheSA9IE1hdGguZmxvb3IoKGNlbnRlclswXSAtIHByb2plY3Rpb25FeHRlbnRbMF0pIC8gd29ybGRXaWR0aCk7XG4gICAgdmFyIG9mZnNldCA9IHdvcmxkc0F3YXkgKiB3b3JsZFdpZHRoO1xuICAgIGV4dGVudFswXSAtPSBvZmZzZXQ7XG4gICAgZXh0ZW50WzJdIC09IG9mZnNldDtcbiAgfVxuXG4gIHJldHVybiBleHRlbnQ7XG59IiwiLyoqXG4gKiBAbW9kdWxlIG9sL3Byb2pcbiAqL1xuXG4vKipcbiAqIFRoZSBvbC9wcm9qIG1vZHVsZSBzdG9yZXM6XG4gKiAqIGEgbGlzdCBvZiB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn1cbiAqIG9iamVjdHMsIG9uZSBmb3IgZWFjaCBwcm9qZWN0aW9uIHN1cHBvcnRlZCBieSB0aGUgYXBwbGljYXRpb25cbiAqICogYSBsaXN0IG9mIHRyYW5zZm9ybSBmdW5jdGlvbnMgbmVlZGVkIHRvIGNvbnZlcnQgY29vcmRpbmF0ZXMgaW4gb25lIHByb2plY3Rpb25cbiAqIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgc3RhdGljIGZ1bmN0aW9ucyBhcmUgdGhlIG1ldGhvZHMgdXNlZCB0byBtYWludGFpbiB0aGVzZS5cbiAqIEVhY2ggdHJhbnNmb3JtIGZ1bmN0aW9uIGNhbiBoYW5kbGUgbm90IG9ubHkgc2ltcGxlIGNvb3JkaW5hdGUgcGFpcnMsIGJ1dCBhbHNvXG4gKiBsYXJnZSBhcnJheXMgb2YgY29vcmRpbmF0ZXMgc3VjaCBhcyB2ZWN0b3IgZ2VvbWV0cmllcy5cbiAqXG4gKiBXaGVuIGxvYWRlZCwgdGhlIGxpYnJhcnkgYWRkcyBwcm9qZWN0aW9uIG9iamVjdHMgZm9yIEVQU0c6NDMyNiAoV0dTODRcbiAqIGdlb2dyYXBoaWMgY29vcmRpbmF0ZXMpIGFuZCBFUFNHOjM4NTcgKFdlYiBvciBTcGhlcmljYWwgTWVyY2F0b3IsIGFzIHVzZWRcbiAqIGZvciBleGFtcGxlIGJ5IEJpbmcgTWFwcyBvciBPcGVuU3RyZWV0TWFwKSwgdG9nZXRoZXIgd2l0aCB0aGUgcmVsZXZhbnRcbiAqIHRyYW5zZm9ybSBmdW5jdGlvbnMuXG4gKlxuICogQWRkaXRpb25hbCB0cmFuc2Zvcm1zIG1heSBiZSBhZGRlZCBieSB1c2luZyB0aGUgaHR0cDovL3Byb2o0anMub3JnL1xuICogbGlicmFyeSAodmVyc2lvbiAyLjIgb3IgbGF0ZXIpLiBZb3UgY2FuIHVzZSB0aGUgZnVsbCBidWlsZCBzdXBwbGllZCBieVxuICogUHJvajRqcywgb3IgY3JlYXRlIGEgY3VzdG9tIGJ1aWxkIHRvIHN1cHBvcnQgdGhvc2UgcHJvamVjdGlvbnMgeW91IG5lZWQ7IHNlZVxuICogdGhlIFByb2o0anMgd2Vic2l0ZSBmb3IgaG93IHRvIGRvIHRoaXMuIFlvdSBhbHNvIG5lZWQgdGhlIFByb2o0anMgZGVmaW5pdGlvbnNcbiAqIGZvciB0aGUgcmVxdWlyZWQgcHJvamVjdGlvbnMuIFRoZXNlIGRlZmluaXRpb25zIGNhbiBiZSBvYnRhaW5lZCBmcm9tXG4gKiBodHRwczovL2Vwc2cuaW8vLCBhbmQgYXJlIGEgSlMgZnVuY3Rpb24sIHNvIGNhbiBiZSBsb2FkZWQgaW4gYSBzY3JpcHRcbiAqIHRhZyAoYXMgaW4gdGhlIGV4YW1wbGVzKSBvciBwYXN0ZWQgaW50byB5b3VyIGFwcGxpY2F0aW9uLlxuICpcbiAqIEFmdGVyIGFsbCByZXF1aXJlZCBwcm9qZWN0aW9uIGRlZmluaXRpb25zIGFyZSBhZGRlZCB0byBwcm9qNCdzIHJlZ2lzdHJ5IChieVxuICogdXNpbmcgYHByb2o0LmRlZnMoKWApLCBzaW1wbHkgY2FsbCBgcmVnaXN0ZXIocHJvajQpYCBmcm9tIHRoZSBgb2wvcHJvai9wcm9qNGBcbiAqIHBhY2thZ2UuIEV4aXN0aW5nIHRyYW5zZm9ybXMgYXJlIG5vdCBjaGFuZ2VkIGJ5IHRoaXMgZnVuY3Rpb24uIFNlZVxuICogZXhhbXBsZXMvd21zLWltYWdlLWN1c3RvbS1wcm9qIGZvciBhbiBleGFtcGxlIG9mIHRoaXMuXG4gKlxuICogQWRkaXRpb25hbCBwcm9qZWN0aW9uIGRlZmluaXRpb25zIGNhbiBiZSByZWdpc3RlcmVkIHdpdGggYHByb2o0LmRlZnMoKWAgYW55XG4gKiB0aW1lLiBKdXN0IG1ha2Ugc3VyZSB0byBjYWxsIGByZWdpc3Rlcihwcm9qNClgIGFnYWluOyBmb3IgZXhhbXBsZSwgd2l0aCB1c2VyLXN1cHBsaWVkIGRhdGEgd2hlcmUgeW91IGRvbid0XG4gKiBrbm93IGluIGFkdmFuY2Ugd2hhdCBwcm9qZWN0aW9ucyBhcmUgbmVlZGVkLCB5b3UgY2FuIGluaXRpYWxseSBsb2FkIG1pbmltYWxcbiAqIHN1cHBvcnQgYW5kIHRoZW4gbG9hZCB3aGljaGV2ZXIgYXJlIHJlcXVlc3RlZC5cbiAqXG4gKiBOb3RlIHRoYXQgUHJvajRqcyBkb2VzIG5vdCBzdXBwb3J0IHByb2plY3Rpb24gZXh0ZW50cy4gSWYgeW91IHdhbnQgdG8gYWRkXG4gKiBvbmUgZm9yIGNyZWF0aW5nIGRlZmF1bHQgdGlsZSBncmlkcywgeW91IGNhbiBhZGQgaXQgYWZ0ZXIgdGhlIFByb2plY3Rpb25cbiAqIG9iamVjdCBoYXMgYmVlbiBjcmVhdGVkIHdpdGggYHNldEV4dGVudGAsIGZvciBleGFtcGxlLFxuICogYGdldCgnRVBTRzoxMjM0Jykuc2V0RXh0ZW50KGV4dGVudClgLlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIFByb2o0anMgc3VwcG9ydCwgYW55IHRyYW5zZm9ybSBmdW5jdGlvbnMgY2FuIGJlIGFkZGVkIHdpdGhcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvan5hZGRDb29yZGluYXRlVHJhbnNmb3Jtc30uIFRvIHVzZSB0aGlzLCB5b3UgbXVzdCBmaXJzdCBjcmVhdGVcbiAqIGEge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb259IG9iamVjdCBmb3IgdGhlIG5ldyBwcm9qZWN0aW9uIGFuZCBhZGQgaXQgd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmFkZFByb2plY3Rpb259LiBZb3UgY2FuIHRoZW4gYWRkIHRoZSBmb3J3YXJkIGFuZCBpbnZlcnNlXG4gKiBmdW5jdGlvbnMgd2l0aCB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+YWRkQ29vcmRpbmF0ZVRyYW5zZm9ybXN9LiBTZWVcbiAqIGV4YW1wbGVzL3dtcy1jdXN0b20tcHJvaiBmb3IgYW4gZXhhbXBsZSBvZiB0aGlzLlxuICpcbiAqIE5vdGUgdGhhdCBpZiBubyB0cmFuc2Zvcm1zIGFyZSBuZWVkZWQgYW5kIHlvdSBvbmx5IG5lZWQgdG8gZGVmaW5lIHRoZVxuICogcHJvamVjdGlvbiwganVzdCBhZGQgYSB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0gd2l0aFxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qfmFkZFByb2plY3Rpb259LiBTZWUgZXhhbXBsZXMvd21zLW5vLXByb2ogZm9yIGFuIGV4YW1wbGUgb2ZcbiAqIHRoaXMuXG4gKi9cbmltcG9ydCBQcm9qZWN0aW9uIGZyb20gJy4vcHJvai9Qcm9qZWN0aW9uLmpzJztcbmltcG9ydCBVbml0cywgeyBNRVRFUlNfUEVSX1VOSVQgfSBmcm9tICcuL3Byb2ovVW5pdHMuanMnO1xuaW1wb3J0IHsgUFJPSkVDVElPTlMgYXMgRVBTRzM4NTdfUFJPSkVDVElPTlMsIGZyb21FUFNHNDMyNiwgdG9FUFNHNDMyNiB9IGZyb20gJy4vcHJvai9lcHNnMzg1Ny5qcyc7XG5pbXBvcnQgeyBQUk9KRUNUSU9OUyBhcyBFUFNHNDMyNl9QUk9KRUNUSU9OUyB9IGZyb20gJy4vcHJvai9lcHNnNDMyNi5qcyc7XG5pbXBvcnQgeyBhZGQgYXMgYWRkUHJvaiwgY2xlYXIgYXMgY2xlYXJQcm9qLCBnZXQgYXMgZ2V0UHJvaiB9IGZyb20gJy4vcHJvai9wcm9qZWN0aW9ucy5qcyc7XG5pbXBvcnQgeyBhZGQgYXMgYWRkVHJhbnNmb3JtRnVuYywgY2xlYXIgYXMgY2xlYXJUcmFuc2Zvcm1GdW5jcywgZ2V0IGFzIGdldFRyYW5zZm9ybUZ1bmMgfSBmcm9tICcuL3Byb2ovdHJhbnNmb3Jtcy5qcyc7XG5pbXBvcnQgeyBhcHBseVRyYW5zZm9ybSwgZ2V0V2lkdGggfSBmcm9tICcuL2V4dGVudC5qcyc7XG5pbXBvcnQgeyBjbGFtcCwgbW9kdWxvIH0gZnJvbSAnLi9tYXRoLmpzJztcbmltcG9ydCB7IGdldERpc3RhbmNlIH0gZnJvbSAnLi9zcGhlcmUuanMnO1xuaW1wb3J0IHsgZ2V0V29ybGRzQXdheSB9IGZyb20gJy4vY29vcmRpbmF0ZS5qcyc7XG4vKipcbiAqIEEgcHJvamVjdGlvbiBhcyB7QGxpbmsgbW9kdWxlOm9sL3Byb2ovUHJvamVjdGlvbn0sIFNSUyBpZGVudGlmaWVyXG4gKiBzdHJpbmcgb3IgdW5kZWZpbmVkLlxuICogQHR5cGVkZWYge1Byb2plY3Rpb258c3RyaW5nfHVuZGVmaW5lZH0gUHJvamVjdGlvbkxpa2VcbiAqIEBhcGlcbiAqL1xuXG4vKipcbiAqIEEgdHJhbnNmb3JtIGZ1bmN0aW9uIGFjY2VwdHMgYW4gYXJyYXkgb2YgaW5wdXQgY29vcmRpbmF0ZSB2YWx1ZXMsIGFuIG9wdGlvbmFsXG4gKiBvdXRwdXQgYXJyYXksIGFuZCBhbiBvcHRpb25hbCBkaW1lbnNpb24gKGRlZmF1bHQgc2hvdWxkIGJlIDIpLiAgVGhlIGZ1bmN0aW9uXG4gKiB0cmFuc2Zvcm1zIHRoZSBpbnB1dCBjb29yZGluYXRlIHZhbHVlcywgcG9wdWxhdGVzIHRoZSBvdXRwdXQgYXJyYXksIGFuZFxuICogcmV0dXJucyB0aGUgb3V0cHV0IGFycmF5LlxuICpcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbihBcnJheTxudW1iZXI+LCBBcnJheTxudW1iZXI+PSwgbnVtYmVyPSk6IEFycmF5PG51bWJlcj59IFRyYW5zZm9ybUZ1bmN0aW9uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IHsgTUVURVJTX1BFUl9VTklUIH07XG5leHBvcnQgeyBQcm9qZWN0aW9uIH07XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gaW5wdXQgSW5wdXQgY29vcmRpbmF0ZSBhcnJheS5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0IGFycmF5IG9mIGNvb3JkaW5hdGUgdmFsdWVzLlxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfZGltZW5zaW9uIERpbWVuc2lvbi5cbiAqIEByZXR1cm4ge0FycmF5PG51bWJlcj59IE91dHB1dCBjb29yZGluYXRlIGFycmF5IChuZXcgYXJyYXksIHNhbWUgY29vcmRpbmF0ZVxuICogICAgIHZhbHVlcykuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGNsb25lVHJhbnNmb3JtKGlucHV0LCBvcHRfb3V0cHV0LCBvcHRfZGltZW5zaW9uKSB7XG4gIHZhciBvdXRwdXQ7XG5cbiAgaWYgKG9wdF9vdXRwdXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIG9wdF9vdXRwdXRbaV0gPSBpbnB1dFtpXTtcbiAgICB9XG5cbiAgICBvdXRwdXQgPSBvcHRfb3V0cHV0O1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGlucHV0LnNsaWNlKCk7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0IGNvb3JkaW5hdGUgYXJyYXkuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj49fSBvcHRfb3V0cHV0IE91dHB1dCBhcnJheSBvZiBjb29yZGluYXRlIHZhbHVlcy5cbiAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24uXG4gKiBAcmV0dXJuIHtBcnJheTxudW1iZXI+fSBJbnB1dCBjb29yZGluYXRlIGFycmF5IChzYW1lIGFycmF5IGFzIGlucHV0KS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaWRlbnRpdHlUcmFuc2Zvcm0oaW5wdXQsIG9wdF9vdXRwdXQsIG9wdF9kaW1lbnNpb24pIHtcbiAgaWYgKG9wdF9vdXRwdXQgIT09IHVuZGVmaW5lZCAmJiBpbnB1dCAhPT0gb3B0X291dHB1dCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IGlucHV0Lmxlbmd0aDsgaSA8IGlpOyArK2kpIHtcbiAgICAgIG9wdF9vdXRwdXRbaV0gPSBpbnB1dFtpXTtcbiAgICB9XG5cbiAgICBpbnB1dCA9IG9wdF9vdXRwdXQ7XG4gIH1cblxuICByZXR1cm4gaW5wdXQ7XG59XG4vKipcbiAqIEFkZCBhIFByb2plY3Rpb24gb2JqZWN0IHRvIHRoZSBsaXN0IG9mIHN1cHBvcnRlZCBwcm9qZWN0aW9ucyB0aGF0IGNhbiBiZVxuICogbG9va2VkIHVwIGJ5IHRoZWlyIGNvZGUuXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBwcm9qZWN0aW9uIFByb2plY3Rpb24gaW5zdGFuY2UuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICBhZGRQcm9qKHByb2plY3Rpb24uZ2V0Q29kZSgpLCBwcm9qZWN0aW9uKTtcbiAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uLCBwcm9qZWN0aW9uLCBjbG9uZVRyYW5zZm9ybSk7XG59XG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8UHJvamVjdGlvbj59IHByb2plY3Rpb25zIFByb2plY3Rpb25zLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucykge1xuICBwcm9qZWN0aW9ucy5mb3JFYWNoKGFkZFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBGZXRjaGVzIGEgUHJvamVjdGlvbiBvYmplY3QgZm9yIHRoZSBjb2RlIHNwZWNpZmllZC5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBwcm9qZWN0aW9uTGlrZSBFaXRoZXIgYSBjb2RlIHN0cmluZyB3aGljaCBpc1xuICogICAgIGEgY29tYmluYXRpb24gb2YgYXV0aG9yaXR5IGFuZCBpZGVudGlmaWVyIHN1Y2ggYXMgXCJFUFNHOjQzMjZcIiwgb3IgYW5cbiAqICAgICBleGlzdGluZyBwcm9qZWN0aW9uIG9iamVjdCwgb3IgdW5kZWZpbmVkLlxuICogQHJldHVybiB7UHJvamVjdGlvbn0gUHJvamVjdGlvbiBvYmplY3QsIG9yIG51bGwgaWYgbm90IGluIGxpc3QuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldChwcm9qZWN0aW9uTGlrZSkge1xuICByZXR1cm4gdHlwZW9mIHByb2plY3Rpb25MaWtlID09PSAnc3RyaW5nJyA/IGdldFByb2ooXG4gIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICBwcm9qZWN0aW9uTGlrZSkgOlxuICAvKiogQHR5cGUge1Byb2plY3Rpb259ICovXG4gIHByb2plY3Rpb25MaWtlIHx8IG51bGw7XG59XG4vKipcbiAqIEdldCB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgcG9pbnQgaW4gZGVncmVlcyBvciBkaXN0YW5jZSB1bml0cy5cbiAqIEZvciBwcm9qZWN0aW9ucyB3aXRoIGRlZ3JlZXMgYXMgdGhlIHVuaXQgdGhpcyB3aWxsIHNpbXBseSByZXR1cm4gdGhlXG4gKiBwcm92aWRlZCByZXNvbHV0aW9uLiBGb3Igb3RoZXIgcHJvamVjdGlvbnMgdGhlIHBvaW50IHJlc29sdXRpb24gaXNcbiAqIGJ5IGRlZmF1bHQgZXN0aW1hdGVkIGJ5IHRyYW5zZm9ybWluZyB0aGUgJ3BvaW50JyBwaXhlbCB0byBFUFNHOjQzMjYsXG4gKiBtZWFzdXJpbmcgaXRzIHdpZHRoIGFuZCBoZWlnaHQgb24gdGhlIG5vcm1hbCBzcGhlcmUsXG4gKiBhbmQgdGFraW5nIHRoZSBhdmVyYWdlIG9mIHRoZSB3aWR0aCBhbmQgaGVpZ2h0LlxuICogQSBjdXN0b20gZnVuY3Rpb24gY2FuIGJlIHByb3ZpZGVkIGZvciBhIHNwZWNpZmljIHByb2plY3Rpb24sIGVpdGhlclxuICogYnkgc2V0dGluZyB0aGUgYGdldFBvaW50UmVzb2x1dGlvbmAgb3B0aW9uIGluIHRoZVxuICoge0BsaW5rIG1vZHVsZTpvbC9wcm9qL1Byb2plY3Rpb25+UHJvamVjdGlvbn0gY29uc3RydWN0b3Igb3IgYnkgdXNpbmdcbiAqIHtAbGluayBtb2R1bGU6b2wvcHJvai9Qcm9qZWN0aW9uflByb2plY3Rpb24jc2V0R2V0UG9pbnRSZXNvbHV0aW9ufSB0byBjaGFuZ2UgYW4gZXhpc3RpbmdcbiAqIHByb2plY3Rpb24gb2JqZWN0LlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gcHJvamVjdGlvbiBUaGUgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSByZXNvbHV0aW9uIE5vbWluYWwgcmVzb2x1dGlvbiBpbiBwcm9qZWN0aW9uIHVuaXRzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gcG9pbnQgUG9pbnQgdG8gZmluZCBhZGp1c3RlZCByZXNvbHV0aW9uIGF0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Byb2ovVW5pdHMuanNcIikuZGVmYXVsdD19IG9wdF91bml0cyBVbml0cyB0byBnZXQgdGhlIHBvaW50IHJlc29sdXRpb24gaW4uXG4gKiBEZWZhdWx0IGlzIHRoZSBwcm9qZWN0aW9uJ3MgdW5pdHMuXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFBvaW50IHJlc29sdXRpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFBvaW50UmVzb2x1dGlvbihwcm9qZWN0aW9uLCByZXNvbHV0aW9uLCBwb2ludCwgb3B0X3VuaXRzKSB7XG4gIHByb2plY3Rpb24gPSBnZXQocHJvamVjdGlvbik7XG4gIHZhciBwb2ludFJlc29sdXRpb247XG4gIHZhciBnZXR0ZXIgPSBwcm9qZWN0aW9uLmdldFBvaW50UmVzb2x1dGlvbkZ1bmMoKTtcblxuICBpZiAoZ2V0dGVyKSB7XG4gICAgcG9pbnRSZXNvbHV0aW9uID0gZ2V0dGVyKHJlc29sdXRpb24sIHBvaW50KTtcblxuICAgIGlmIChvcHRfdW5pdHMgJiYgb3B0X3VuaXRzICE9PSBwcm9qZWN0aW9uLmdldFVuaXRzKCkpIHtcbiAgICAgIHZhciBtZXRlcnNQZXJVbml0ID0gcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG5cbiAgICAgIGlmIChtZXRlcnNQZXJVbml0KSB7XG4gICAgICAgIHBvaW50UmVzb2x1dGlvbiA9IHBvaW50UmVzb2x1dGlvbiAqIG1ldGVyc1BlclVuaXQgLyBNRVRFUlNfUEVSX1VOSVRbb3B0X3VuaXRzXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIHVuaXRzID0gcHJvamVjdGlvbi5nZXRVbml0cygpO1xuXG4gICAgaWYgKHVuaXRzID09IFVuaXRzLkRFR1JFRVMgJiYgIW9wdF91bml0cyB8fCBvcHRfdW5pdHMgPT0gVW5pdHMuREVHUkVFUykge1xuICAgICAgcG9pbnRSZXNvbHV0aW9uID0gcmVzb2x1dGlvbjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRXN0aW1hdGUgcG9pbnQgcmVzb2x1dGlvbiBieSB0cmFuc2Zvcm1pbmcgdGhlIGNlbnRlciBwaXhlbCB0byBFUFNHOjQzMjYsXG4gICAgICAvLyBtZWFzdXJpbmcgaXRzIHdpZHRoIGFuZCBoZWlnaHQgb24gdGhlIG5vcm1hbCBzcGhlcmUsIGFuZCB0YWtpbmcgdGhlXG4gICAgICAvLyBhdmVyYWdlIG9mIHRoZSB3aWR0aCBhbmQgaGVpZ2h0LlxuICAgICAgdmFyIF90b0VQU0cgPSBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMocHJvamVjdGlvbiwgZ2V0KCdFUFNHOjQzMjYnKSk7XG5cbiAgICAgIGlmIChfdG9FUFNHID09PSBpZGVudGl0eVRyYW5zZm9ybSAmJiB1bml0cyAhPT0gVW5pdHMuREVHUkVFUykge1xuICAgICAgICAvLyBubyB0cmFuc2Zvcm0gaXMgYXZhaWxhYmxlXG4gICAgICAgIHBvaW50UmVzb2x1dGlvbiA9IHJlc29sdXRpb24gKiBwcm9qZWN0aW9uLmdldE1ldGVyc1BlclVuaXQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB2ZXJ0aWNlcyA9IFtwb2ludFswXSAtIHJlc29sdXRpb24gLyAyLCBwb2ludFsxXSwgcG9pbnRbMF0gKyByZXNvbHV0aW9uIC8gMiwgcG9pbnRbMV0sIHBvaW50WzBdLCBwb2ludFsxXSAtIHJlc29sdXRpb24gLyAyLCBwb2ludFswXSwgcG9pbnRbMV0gKyByZXNvbHV0aW9uIC8gMl07XG4gICAgICAgIHZlcnRpY2VzID0gX3RvRVBTRyh2ZXJ0aWNlcywgdmVydGljZXMsIDIpO1xuICAgICAgICB2YXIgd2lkdGggPSBnZXREaXN0YW5jZSh2ZXJ0aWNlcy5zbGljZSgwLCAyKSwgdmVydGljZXMuc2xpY2UoMiwgNCkpO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gZ2V0RGlzdGFuY2UodmVydGljZXMuc2xpY2UoNCwgNiksIHZlcnRpY2VzLnNsaWNlKDYsIDgpKTtcbiAgICAgICAgcG9pbnRSZXNvbHV0aW9uID0gKHdpZHRoICsgaGVpZ2h0KSAvIDI7XG4gICAgICB9XG5cbiAgICAgIHZhciBfbWV0ZXJzUGVyVW5pdCA9IG9wdF91bml0cyA/IE1FVEVSU19QRVJfVU5JVFtvcHRfdW5pdHNdIDogcHJvamVjdGlvbi5nZXRNZXRlcnNQZXJVbml0KCk7XG5cbiAgICAgIGlmIChfbWV0ZXJzUGVyVW5pdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBvaW50UmVzb2x1dGlvbiAvPSBfbWV0ZXJzUGVyVW5pdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcG9pbnRSZXNvbHV0aW9uO1xufVxuLyoqXG4gKiBSZWdpc3RlcnMgdHJhbnNmb3JtYXRpb24gZnVuY3Rpb25zIHRoYXQgZG9uJ3QgYWx0ZXIgY29vcmRpbmF0ZXMuIFRob3NlIGFsbG93XG4gKiB0byB0cmFuc2Zvcm0gYmV0d2VlbiBwcm9qZWN0aW9ucyB3aXRoIGVxdWFsIG1lYW5pbmcuXG4gKlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMgUHJvamVjdGlvbnMuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEVxdWl2YWxlbnRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucykge1xuICBhZGRQcm9qZWN0aW9ucyhwcm9qZWN0aW9ucyk7XG4gIHByb2plY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZSkge1xuICAgIHByb2plY3Rpb25zLmZvckVhY2goZnVuY3Rpb24gKGRlc3RpbmF0aW9uKSB7XG4gICAgICBpZiAoc291cmNlICE9PSBkZXN0aW5hdGlvbikge1xuICAgICAgICBhZGRUcmFuc2Zvcm1GdW5jKHNvdXJjZSwgZGVzdGluYXRpb24sIGNsb25lVHJhbnNmb3JtKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG4vKipcbiAqIFJlZ2lzdGVycyB0cmFuc2Zvcm1hdGlvbiBmdW5jdGlvbnMgdG8gY29udmVydCBjb29yZGluYXRlcyBpbiBhbnkgcHJvamVjdGlvblxuICogaW4gcHJvamVjdGlvbjEgdG8gYW55IHByb2plY3Rpb24gaW4gcHJvamVjdGlvbjIuXG4gKlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMxIFByb2plY3Rpb25zIHdpdGggZXF1YWxcbiAqICAgICBtZWFuaW5nLlxuICogQHBhcmFtIHtBcnJheTxQcm9qZWN0aW9uPn0gcHJvamVjdGlvbnMyIFByb2plY3Rpb25zIHdpdGggZXF1YWxcbiAqICAgICBtZWFuaW5nLlxuICogQHBhcmFtIHtUcmFuc2Zvcm1GdW5jdGlvbn0gZm9yd2FyZFRyYW5zZm9ybSBUcmFuc2Zvcm1hdGlvbiBmcm9tIGFueVxuICogICBwcm9qZWN0aW9uIGluIHByb2plY3Rpb24xIHRvIGFueSBwcm9qZWN0aW9uIGluIHByb2plY3Rpb24yLlxuICogQHBhcmFtIHtUcmFuc2Zvcm1GdW5jdGlvbn0gaW52ZXJzZVRyYW5zZm9ybSBUcmFuc2Zvcm0gZnJvbSBhbnkgcHJvamVjdGlvblxuICogICBpbiBwcm9qZWN0aW9uMiB0byBhbnkgcHJvamVjdGlvbiBpbiBwcm9qZWN0aW9uMS4uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEVxdWl2YWxlbnRUcmFuc2Zvcm1zKHByb2plY3Rpb25zMSwgcHJvamVjdGlvbnMyLCBmb3J3YXJkVHJhbnNmb3JtLCBpbnZlcnNlVHJhbnNmb3JtKSB7XG4gIHByb2plY3Rpb25zMS5mb3JFYWNoKGZ1bmN0aW9uIChwcm9qZWN0aW9uMSkge1xuICAgIHByb2plY3Rpb25zMi5mb3JFYWNoKGZ1bmN0aW9uIChwcm9qZWN0aW9uMikge1xuICAgICAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uMSwgcHJvamVjdGlvbjIsIGZvcndhcmRUcmFuc2Zvcm0pO1xuICAgICAgYWRkVHJhbnNmb3JtRnVuYyhwcm9qZWN0aW9uMiwgcHJvamVjdGlvbjEsIGludmVyc2VUcmFuc2Zvcm0pO1xuICAgIH0pO1xuICB9KTtcbn1cbi8qKlxuICogQ2xlYXIgYWxsIGNhY2hlZCBwcm9qZWN0aW9ucyBhbmQgdHJhbnNmb3Jtcy5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJBbGxQcm9qZWN0aW9ucygpIHtcbiAgY2xlYXJQcm9qKCk7XG4gIGNsZWFyVHJhbnNmb3JtRnVuY3MoKTtcbn1cbi8qKlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufHN0cmluZ3x1bmRlZmluZWR9IHByb2plY3Rpb24gUHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkZWZhdWx0Q29kZSBEZWZhdWx0IGNvZGUuXG4gKiBAcmV0dXJuIHtQcm9qZWN0aW9ufSBQcm9qZWN0aW9uLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm9qZWN0aW9uKHByb2plY3Rpb24sIGRlZmF1bHRDb2RlKSB7XG4gIGlmICghcHJvamVjdGlvbikge1xuICAgIHJldHVybiBnZXQoZGVmYXVsdENvZGUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9qZWN0aW9uID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBnZXQocHJvamVjdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChcbiAgICAgIC8qKiBAdHlwZSB7UHJvamVjdGlvbn0gKi9cbiAgICAgIHByb2plY3Rpb25cbiAgICApO1xuICB9XG59XG4vKipcbiAqIENyZWF0ZXMgYSB7QGxpbmsgbW9kdWxlOm9sL3Byb2p+VHJhbnNmb3JtRnVuY3Rpb259IGZyb20gYSBzaW1wbGUgMkQgY29vcmRpbmF0ZSB0cmFuc2Zvcm1cbiAqIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZSk6IGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZFRyYW5zZm9ybSBDb29yZGluYXRlXG4gKiAgICAgdHJhbnNmb3JtLlxuICogQHJldHVybiB7VHJhbnNmb3JtRnVuY3Rpb259IFRyYW5zZm9ybSBmdW5jdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHJhbnNmb3JtRnJvbUNvb3JkaW5hdGVUcmFuc2Zvcm0oY29vcmRUcmFuc2Zvcm0pIHtcbiAgcmV0dXJuIChcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGlucHV0IElucHV0LlxuICAgICAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPj19IG9wdF9vdXRwdXQgT3V0cHV0LlxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gb3B0X2RpbWVuc2lvbiBEaW1lbnNpb24uXG4gICAgICogQHJldHVybiB7QXJyYXk8bnVtYmVyPn0gT3V0cHV0LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIChpbnB1dCwgb3B0X291dHB1dCwgb3B0X2RpbWVuc2lvbikge1xuICAgICAgdmFyIGxlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgICAgIHZhciBkaW1lbnNpb24gPSBvcHRfZGltZW5zaW9uICE9PSB1bmRlZmluZWQgPyBvcHRfZGltZW5zaW9uIDogMjtcbiAgICAgIHZhciBvdXRwdXQgPSBvcHRfb3V0cHV0ICE9PSB1bmRlZmluZWQgPyBvcHRfb3V0cHV0IDogbmV3IEFycmF5KGxlbmd0aCk7XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGRpbWVuc2lvbikge1xuICAgICAgICB2YXIgcG9pbnQgPSBjb29yZFRyYW5zZm9ybShbaW5wdXRbaV0sIGlucHV0W2kgKyAxXV0pO1xuICAgICAgICBvdXRwdXRbaV0gPSBwb2ludFswXTtcbiAgICAgICAgb3V0cHV0W2kgKyAxXSA9IHBvaW50WzFdO1xuXG4gICAgICAgIGZvciAodmFyIGogPSBkaW1lbnNpb24gLSAxOyBqID49IDI7IC0taikge1xuICAgICAgICAgIG91dHB1dFtpICsgal0gPSBpbnB1dFtpICsgal07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9XG4gICk7XG59XG4vKipcbiAqIFJlZ2lzdGVycyBjb29yZGluYXRlIHRyYW5zZm9ybSBmdW5jdGlvbnMgdG8gY29udmVydCBjb29yZGluYXRlcyBiZXR3ZWVuIHRoZVxuICogc291cmNlIHByb2plY3Rpb24gYW5kIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogVGhlIGZvcndhcmQgYW5kIGludmVyc2UgZnVuY3Rpb25zIGNvbnZlcnQgY29vcmRpbmF0ZSBwYWlyczsgdGhpcyBmdW5jdGlvblxuICogY29udmVydHMgdGhlc2UgaW50byB0aGUgZnVuY3Rpb25zIHVzZWQgaW50ZXJuYWxseSB3aGljaCBhbHNvIGhhbmRsZVxuICogZXh0ZW50cyBhbmQgY29vcmRpbmF0ZSBhcnJheXMuXG4gKlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gZm9yd2FyZCBUaGUgZm9yd2FyZCB0cmFuc2Zvcm1cbiAqICAgICBmdW5jdGlvbiAodGhhdCBpcywgZnJvbSB0aGUgc291cmNlIHByb2plY3Rpb24gdG8gdGhlIGRlc3RpbmF0aW9uXG4gKiAgICAgcHJvamVjdGlvbikgdGhhdCB0YWtlcyBhIHtAbGluayBtb2R1bGU6b2wvY29vcmRpbmF0ZX5Db29yZGluYXRlfSBhcyBhcmd1bWVudCBhbmQgcmV0dXJuc1xuICogICAgIHRoZSB0cmFuc2Zvcm1lZCB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlKTogaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGludmVyc2UgVGhlIGludmVyc2UgdHJhbnNmb3JtXG4gKiAgICAgZnVuY3Rpb24gKHRoYXQgaXMsIGZyb20gdGhlIGRlc3RpbmF0aW9uIHByb2plY3Rpb24gdG8gdGhlIHNvdXJjZVxuICogICAgIHByb2plY3Rpb24pIHRoYXQgdGFrZXMgYSB7QGxpbmsgbW9kdWxlOm9sL2Nvb3JkaW5hdGV+Q29vcmRpbmF0ZX0gYXMgYXJndW1lbnQgYW5kIHJldHVybnNcbiAqICAgICB0aGUgdHJhbnNmb3JtZWQge0BsaW5rIG1vZHVsZTpvbC9jb29yZGluYXRlfkNvb3JkaW5hdGV9LlxuICogQGFwaVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb29yZGluYXRlVHJhbnNmb3Jtcyhzb3VyY2UsIGRlc3RpbmF0aW9uLCBmb3J3YXJkLCBpbnZlcnNlKSB7XG4gIHZhciBzb3VyY2VQcm9qID0gZ2V0KHNvdXJjZSk7XG4gIHZhciBkZXN0UHJvaiA9IGdldChkZXN0aW5hdGlvbik7XG4gIGFkZFRyYW5zZm9ybUZ1bmMoc291cmNlUHJvaiwgZGVzdFByb2osIGNyZWF0ZVRyYW5zZm9ybUZyb21Db29yZGluYXRlVHJhbnNmb3JtKGZvcndhcmQpKTtcbiAgYWRkVHJhbnNmb3JtRnVuYyhkZXN0UHJvaiwgc291cmNlUHJvaiwgY3JlYXRlVHJhbnNmb3JtRnJvbUNvb3JkaW5hdGVUcmFuc2Zvcm0oaW52ZXJzZSkpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgY29vcmRpbmF0ZSBmcm9tIGxvbmdpdHVkZS9sYXRpdHVkZSB0byBhIGRpZmZlcmVudCBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gY29vcmRpbmF0ZSBDb29yZGluYXRlIGFzIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUsIGkuZS5cbiAqICAgICBhbiBhcnJheSB3aXRoIGxvbmdpdHVkZSBhcyAxc3QgYW5kIGxhdGl0dWRlIGFzIDJuZCBlbGVtZW50LlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZT19IG9wdF9wcm9qZWN0aW9uIFRhcmdldCBwcm9qZWN0aW9uLiBUaGVcbiAqICAgICBkZWZhdWx0IGlzIFdlYiBNZXJjYXRvciwgaS5lLiAnRVBTRzozODU3Jy5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBDb29yZGluYXRlIHByb2plY3RlZCB0byB0aGUgdGFyZ2V0IHByb2plY3Rpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGZyb21Mb25MYXQoY29vcmRpbmF0ZSwgb3B0X3Byb2plY3Rpb24pIHtcbiAgcmV0dXJuIHRyYW5zZm9ybShjb29yZGluYXRlLCAnRVBTRzo0MzI2Jywgb3B0X3Byb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9wcm9qZWN0aW9uIDogJ0VQU0c6Mzg1NycpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgY29vcmRpbmF0ZSB0byBsb25naXR1ZGUvbGF0aXR1ZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBjb29yZGluYXRlIFByb2plY3RlZCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZT19IG9wdF9wcm9qZWN0aW9uIFByb2plY3Rpb24gb2YgdGhlIGNvb3JkaW5hdGUuXG4gKiAgICAgVGhlIGRlZmF1bHQgaXMgV2ViIE1lcmNhdG9yLCBpLmUuICdFUFNHOjM4NTcnLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUgYXMgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSwgaS5lLiBhbiBhcnJheVxuICogICAgIHdpdGggbG9uZ2l0dWRlIGFzIDFzdCBhbmQgbGF0aXR1ZGUgYXMgMm5kIGVsZW1lbnQuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvTG9uTGF0KGNvb3JkaW5hdGUsIG9wdF9wcm9qZWN0aW9uKSB7XG4gIHZhciBsb25MYXQgPSB0cmFuc2Zvcm0oY29vcmRpbmF0ZSwgb3B0X3Byb2plY3Rpb24gIT09IHVuZGVmaW5lZCA/IG9wdF9wcm9qZWN0aW9uIDogJ0VQU0c6Mzg1NycsICdFUFNHOjQzMjYnKTtcbiAgdmFyIGxvbiA9IGxvbkxhdFswXTtcblxuICBpZiAobG9uIDwgLTE4MCB8fCBsb24gPiAxODApIHtcbiAgICBsb25MYXRbMF0gPSBtb2R1bG8obG9uICsgMTgwLCAzNjApIC0gMTgwO1xuICB9XG5cbiAgcmV0dXJuIGxvbkxhdDtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIHR3byBwcm9qZWN0aW9ucyBhcmUgdGhlIHNhbWUsIHRoYXQgaXMgZXZlcnkgY29vcmRpbmF0ZSBpbiBvbmVcbiAqIHByb2plY3Rpb24gZG9lcyByZXByZXNlbnQgdGhlIHNhbWUgZ2VvZ3JhcGhpYyBwb2ludCBhcyB0aGUgc2FtZSBjb29yZGluYXRlIGluXG4gKiB0aGUgb3RoZXIgcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHByb2plY3Rpb24xIFByb2plY3Rpb24gMS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gcHJvamVjdGlvbjIgUHJvamVjdGlvbiAyLlxuICogQHJldHVybiB7Ym9vbGVhbn0gRXF1aXZhbGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZXF1aXZhbGVudChwcm9qZWN0aW9uMSwgcHJvamVjdGlvbjIpIHtcbiAgaWYgKHByb2plY3Rpb24xID09PSBwcm9qZWN0aW9uMikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIGVxdWFsVW5pdHMgPSBwcm9qZWN0aW9uMS5nZXRVbml0cygpID09PSBwcm9qZWN0aW9uMi5nZXRVbml0cygpO1xuXG4gIGlmIChwcm9qZWN0aW9uMS5nZXRDb2RlKCkgPT09IHByb2plY3Rpb24yLmdldENvZGUoKSkge1xuICAgIHJldHVybiBlcXVhbFVuaXRzO1xuICB9IGVsc2Uge1xuICAgIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHByb2plY3Rpb24xLCBwcm9qZWN0aW9uMik7XG4gICAgcmV0dXJuIHRyYW5zZm9ybUZ1bmMgPT09IGNsb25lVHJhbnNmb3JtICYmIGVxdWFsVW5pdHM7XG4gIH1cbn1cbi8qKlxuICogU2VhcmNoZXMgaW4gdGhlIGxpc3Qgb2YgdHJhbnNmb3JtIGZ1bmN0aW9ucyBmb3IgdGhlIGZ1bmN0aW9uIGZvciBjb252ZXJ0aW5nXG4gKiBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2UgcHJvamVjdGlvbiB0byB0aGUgZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1Byb2plY3Rpb259IHNvdXJjZVByb2plY3Rpb24gU291cmNlIFByb2plY3Rpb24gb2JqZWN0LlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBkZXN0aW5hdGlvblByb2plY3Rpb24gRGVzdGluYXRpb24gUHJvamVjdGlvblxuICogICAgIG9iamVjdC5cbiAqIEByZXR1cm4ge1RyYW5zZm9ybUZ1bmN0aW9ufSBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zZm9ybUZyb21Qcm9qZWN0aW9ucyhzb3VyY2VQcm9qZWN0aW9uLCBkZXN0aW5hdGlvblByb2plY3Rpb24pIHtcbiAgdmFyIHNvdXJjZUNvZGUgPSBzb3VyY2VQcm9qZWN0aW9uLmdldENvZGUoKTtcbiAgdmFyIGRlc3RpbmF0aW9uQ29kZSA9IGRlc3RpbmF0aW9uUHJvamVjdGlvbi5nZXRDb2RlKCk7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtRnVuYyhzb3VyY2VDb2RlLCBkZXN0aW5hdGlvbkNvZGUpO1xuXG4gIGlmICghdHJhbnNmb3JtRnVuYykge1xuICAgIHRyYW5zZm9ybUZ1bmMgPSBpZGVudGl0eVRyYW5zZm9ybTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1GdW5jO1xufVxuLyoqXG4gKiBHaXZlbiB0aGUgcHJvamVjdGlvbi1saWtlIG9iamVjdHMsIHNlYXJjaGVzIGZvciBhIHRyYW5zZm9ybWF0aW9uXG4gKiBmdW5jdGlvbiB0byBjb252ZXJ0IGEgY29vcmRpbmF0ZXMgYXJyYXkgZnJvbSB0aGUgc291cmNlIHByb2plY3Rpb24gdG8gdGhlXG4gKiBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbi5cbiAqIEByZXR1cm4ge1RyYW5zZm9ybUZ1bmN0aW9ufSBUcmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zZm9ybShzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciBzb3VyY2VQcm9qZWN0aW9uID0gZ2V0KHNvdXJjZSk7XG4gIHZhciBkZXN0aW5hdGlvblByb2plY3Rpb24gPSBnZXQoZGVzdGluYXRpb24pO1xuICByZXR1cm4gZ2V0VHJhbnNmb3JtRnJvbVByb2plY3Rpb25zKHNvdXJjZVByb2plY3Rpb24sIGRlc3RpbmF0aW9uUHJvamVjdGlvbik7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgYSBjb29yZGluYXRlIGZyb20gc291cmNlIHByb2plY3Rpb24gdG8gZGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIFRoaXMgcmV0dXJucyBhIG5ldyBjb29yZGluYXRlIChhbmQgZG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCkuXG4gKlxuICogU2VlIHtAbGluayBtb2R1bGU6b2wvcHJvan50cmFuc2Zvcm1FeHRlbnR9IGZvciBleHRlbnQgdHJhbnNmb3JtYXRpb24uXG4gKiBTZWUgdGhlIHRyYW5zZm9ybSBtZXRob2Qgb2Yge0BsaW5rIG1vZHVsZTpvbC9nZW9tL0dlb21ldHJ5fkdlb21ldHJ5fSBhbmQgaXRzXG4gKiBzdWJjbGFzc2VzIGZvciBnZW9tZXRyeSB0cmFuc2Zvcm1zLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IGNvb3JkaW5hdGUgQ29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHNvdXJjZSBTb3VyY2UgcHJvamVjdGlvbi1saWtlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gZGVzdGluYXRpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi1saWtlLlxuICogQHJldHVybiB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IENvb3JkaW5hdGUuXG4gKiBAYXBpXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShjb29yZGluYXRlLCBzb3VyY2UsIGRlc3RpbmF0aW9uKSB7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtKHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICByZXR1cm4gdHJhbnNmb3JtRnVuYyhjb29yZGluYXRlLCB1bmRlZmluZWQsIGNvb3JkaW5hdGUubGVuZ3RoKTtcbn1cbi8qKlxuICogVHJhbnNmb3JtcyBhbiBleHRlbnQgZnJvbSBzb3VyY2UgcHJvamVjdGlvbiB0byBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLiAgVGhpc1xuICogcmV0dXJucyBhIG5ldyBleHRlbnQgKGFuZCBkb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsKS5cbiAqXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IFRoZSBleHRlbnQgdG8gdHJhbnNmb3JtLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlIFNvdXJjZSBwcm9qZWN0aW9uLWxpa2UuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBkZXN0aW5hdGlvbiBEZXN0aW5hdGlvbiBwcm9qZWN0aW9uLWxpa2UuXG4gKiBAcGFyYW0ge251bWJlcj19IG9wdF9zdG9wcyBOdW1iZXIgb2Ygc3RvcHMgcGVyIHNpZGUgdXNlZCBmb3IgdGhlIHRyYW5zZm9ybS5cbiAqIEJ5IGRlZmF1bHQgb25seSB0aGUgY29ybmVycyBhcmUgdXNlZC5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIHRyYW5zZm9ybWVkIGV4dGVudC5cbiAqIEBhcGlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgc291cmNlLCBkZXN0aW5hdGlvbiwgb3B0X3N0b3BzKSB7XG4gIHZhciB0cmFuc2Zvcm1GdW5jID0gZ2V0VHJhbnNmb3JtKHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICByZXR1cm4gYXBwbHlUcmFuc2Zvcm0oZXh0ZW50LCB0cmFuc2Zvcm1GdW5jLCB1bmRlZmluZWQsIG9wdF9zdG9wcyk7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgdGhlIGdpdmVuIHBvaW50IHRvIHRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGV9IHBvaW50IFBvaW50LlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBzb3VyY2VQcm9qZWN0aW9uIFNvdXJjZSBwcm9qZWN0aW9uLlxuICogQHBhcmFtIHtQcm9qZWN0aW9ufSBkZXN0aW5hdGlvblByb2plY3Rpb24gRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEByZXR1cm4ge2ltcG9ydChcIi4vY29vcmRpbmF0ZS5qc1wiKS5Db29yZGluYXRlfSBQb2ludC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtV2l0aFByb2plY3Rpb25zKHBvaW50LCBzb3VyY2VQcm9qZWN0aW9uLCBkZXN0aW5hdGlvblByb2plY3Rpb24pIHtcbiAgdmFyIHRyYW5zZm9ybUZ1bmMgPSBnZXRUcmFuc2Zvcm1Gcm9tUHJvamVjdGlvbnMoc291cmNlUHJvamVjdGlvbiwgZGVzdGluYXRpb25Qcm9qZWN0aW9uKTtcbiAgcmV0dXJuIHRyYW5zZm9ybUZ1bmMocG9pbnQpO1xufVxuLyoqXG4gKiBAdHlwZSB7P1Byb2plY3Rpb259XG4gKi9cblxudmFyIHVzZXJQcm9qZWN0aW9uID0gbnVsbDtcbi8qKlxuICogU2V0IHRoZSBwcm9qZWN0aW9uIGZvciBjb29yZGluYXRlcyBzdXBwbGllZCBmcm9tIGFuZCByZXR1cm5lZCBieSBBUEkgbWV0aG9kcy5cbiAqIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBpcyBub3QgeWV0IGEgcGFydCBvZiB0aGUgc3RhYmxlIEFQSS4gIFN1cHBvcnQgZm9yIHVzZXJcbiAqIHByb2plY3Rpb25zIGlzIG5vdCB5ZXQgY29tcGxldGUgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IHByb2plY3Rpb24gVGhlIHVzZXIgcHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0VXNlclByb2plY3Rpb24ocHJvamVjdGlvbikge1xuICB1c2VyUHJvamVjdGlvbiA9IGdldChwcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogQ2xlYXIgdGhlIHVzZXIgcHJvamVjdGlvbiBpZiBzZXQuICBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2ZcbiAqIHRoZSBzdGFibGUgQVBJLiAgU3VwcG9ydCBmb3IgdXNlciBwcm9qZWN0aW9ucyBpcyBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGRcbiAqIGJlIGNvbnNpZGVyZWQgZXhwZXJpbWVudGFsLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhclVzZXJQcm9qZWN0aW9uKCkge1xuICB1c2VyUHJvamVjdGlvbiA9IG51bGw7XG59XG4vKipcbiAqIEdldCB0aGUgcHJvamVjdGlvbiBmb3IgY29vcmRpbmF0ZXMgc3VwcGxpZWQgZnJvbSBhbmQgcmV0dXJuZWQgYnkgQVBJIG1ldGhvZHMuXG4gKiBOb3RlIHRoYXQgdGhpcyBtZXRob2QgaXMgbm90IHlldCBhIHBhcnQgb2YgdGhlIHN0YWJsZSBBUEkuICBTdXBwb3J0IGZvciB1c2VyXG4gKiBwcm9qZWN0aW9ucyBpcyBub3QgeWV0IGNvbXBsZXRlIGFuZCBzaG91bGQgYmUgY29uc2lkZXJlZCBleHBlcmltZW50YWwuXG4gKiBAcmV0dXJucyB7P1Byb2plY3Rpb259IFRoZSB1c2VyIHByb2plY3Rpb24gKG9yIG51bGwgaWYgbm90IHNldCkuXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJQcm9qZWN0aW9uKCkge1xuICByZXR1cm4gdXNlclByb2plY3Rpb247XG59XG4vKipcbiAqIFVzZSBnZW9ncmFwaGljIGNvb3JkaW5hdGVzIChXR1MtODQgZGF0dW0pIGluIEFQSSBtZXRob2RzLiAgTm90ZSB0aGF0IHRoaXNcbiAqIG1ldGhvZCBpcyBub3QgeWV0IGEgcGFydCBvZiB0aGUgc3RhYmxlIEFQSS4gIFN1cHBvcnQgZm9yIHVzZXIgcHJvamVjdGlvbnMgaXNcbiAqIG5vdCB5ZXQgY29tcGxldGUgYW5kIHNob3VsZCBiZSBjb25zaWRlcmVkIGV4cGVyaW1lbnRhbC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlR2VvZ3JhcGhpYygpIHtcbiAgc2V0VXNlclByb2plY3Rpb24oJ0VQU0c6NDMyNicpO1xufVxuLyoqXG4gKiBSZXR1cm4gYSBjb29yZGluYXRlIHRyYW5zZm9ybWVkIGludG8gdGhlIHVzZXIgcHJvamVjdGlvbi4gIElmIG5vIHVzZXIgcHJvamVjdGlvblxuICogaXMgc2V0LCB0aGUgb3JpZ2luYWwgY29vcmRpbmF0ZSBpcyByZXR1cm5lZC5cbiAqIEBwYXJhbSB7QXJyYXk8bnVtYmVyPn0gY29vcmRpbmF0ZSBJbnB1dCBjb29yZGluYXRlLlxuICogQHBhcmFtIHtQcm9qZWN0aW9uTGlrZX0gc291cmNlUHJvamVjdGlvbiBUaGUgaW5wdXQgY29vcmRpbmF0ZSBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IFRoZSBpbnB1dCBjb29yZGluYXRlIGluIHRoZSB1c2VyIHByb2plY3Rpb24uXG4gKi9cblxuZXhwb3J0IGZ1bmN0aW9uIHRvVXNlckNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgc291cmNlUHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvb3JkaW5hdGU7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtKGNvb3JkaW5hdGUsIHNvdXJjZVByb2plY3Rpb24sIHVzZXJQcm9qZWN0aW9uKTtcbn1cbi8qKlxuICogUmV0dXJuIGEgY29vcmRpbmF0ZSB0cmFuc2Zvcm1lZCBmcm9tIHRoZSB1c2VyIHByb2plY3Rpb24uICBJZiBubyB1c2VyIHByb2plY3Rpb25cbiAqIGlzIHNldCwgdGhlIG9yaWdpbmFsIGNvb3JkaW5hdGUgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNvb3JkaW5hdGUgSW5wdXQgY29vcmRpbmF0ZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RQcm9qZWN0aW9uIFRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge0FycmF5PG51bWJlcj59IFRoZSBpbnB1dCBjb29yZGluYXRlIHRyYW5zZm9ybWVkLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBmcm9tVXNlckNvb3JkaW5hdGUoY29vcmRpbmF0ZSwgZGVzdFByb2plY3Rpb24pIHtcbiAgaWYgKCF1c2VyUHJvamVjdGlvbikge1xuICAgIHJldHVybiBjb29yZGluYXRlO1xuICB9XG5cbiAgcmV0dXJuIHRyYW5zZm9ybShjb29yZGluYXRlLCB1c2VyUHJvamVjdGlvbiwgZGVzdFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBSZXR1cm4gYW4gZXh0ZW50IHRyYW5zZm9ybWVkIGludG8gdGhlIHVzZXIgcHJvamVjdGlvbi4gIElmIG5vIHVzZXIgcHJvamVjdGlvblxuICogaXMgc2V0LCB0aGUgb3JpZ2luYWwgZXh0ZW50IGlzIHJldHVybmVkLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IGV4dGVudCBJbnB1dCBleHRlbnQuXG4gKiBAcGFyYW0ge1Byb2plY3Rpb25MaWtlfSBzb3VyY2VQcm9qZWN0aW9uIFRoZSBpbnB1dCBleHRlbnQgcHJvamVjdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2V4dGVudC5qc1wiKS5FeHRlbnR9IFRoZSBpbnB1dCBleHRlbnQgaW4gdGhlIHVzZXIgcHJvamVjdGlvbi5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gdG9Vc2VyRXh0ZW50KGV4dGVudCwgc291cmNlUHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1FeHRlbnQoZXh0ZW50LCBzb3VyY2VQcm9qZWN0aW9uLCB1c2VyUHJvamVjdGlvbik7XG59XG4vKipcbiAqIFJldHVybiBhbiBleHRlbnQgdHJhbnNmb3JtZWQgZnJvbSB0aGUgdXNlciBwcm9qZWN0aW9uLiAgSWYgbm8gdXNlciBwcm9qZWN0aW9uXG4gKiBpcyBzZXQsIHRoZSBvcmlnaW5hbCBleHRlbnQgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gZXh0ZW50IElucHV0IGV4dGVudC5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbkxpa2V9IGRlc3RQcm9qZWN0aW9uIFRoZSBkZXN0aW5hdGlvbiBwcm9qZWN0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vZXh0ZW50LmpzXCIpLkV4dGVudH0gVGhlIGlucHV0IGV4dGVudCB0cmFuc2Zvcm1lZC5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gZnJvbVVzZXJFeHRlbnQoZXh0ZW50LCBkZXN0UHJvamVjdGlvbikge1xuICBpZiAoIXVzZXJQcm9qZWN0aW9uKSB7XG4gICAgcmV0dXJuIGV4dGVudDtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm1FeHRlbnQoZXh0ZW50LCB1c2VyUHJvamVjdGlvbiwgZGVzdFByb2plY3Rpb24pO1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgc2FmZSBjb29yZGluYXRlIHRyYW5zZm9ybSBmdW5jdGlvbiBmcm9tIGEgY29vcmRpbmF0ZSB0cmFuc2Zvcm0gZnVuY3Rpb24uXG4gKiBcIlNhZmVcIiBtZWFucyB0aGF0IGl0IGNhbiBoYW5kbGUgd3JhcHBpbmcgb2YgeC1jb29yZGluYXRlcyBmb3IgZ2xvYmFsIHByb2plY3Rpb25zLFxuICogYW5kIHRoYXQgY29vcmRpbmF0ZXMgZXhjZWVkaW5nIHRoZSBzb3VyY2UgcHJvamVjdGlvbiB2YWxpZGl0eSBleHRlbnQncyByYW5nZSB3aWxsIGJlXG4gKiBjbGFtcGVkIHRvIHRoZSB2YWxpZGl0eSByYW5nZS5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gc291cmNlUHJvaiBTb3VyY2UgcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7UHJvamVjdGlvbn0gZGVzdFByb2ogRGVzdGluYXRpb24gcHJvamVjdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gdHJhbnNmb3JtIFRyYW5zZm9ybSBmdW5jdGlvbiAoc291cmNlIHRvIGRlc3RpYXRpb24pLlxuICogQHJldHVybiB7ZnVuY3Rpb24oaW1wb3J0KFwiLi9jb29yZGluYXRlLmpzXCIpLkNvb3JkaW5hdGUpOiBpbXBvcnQoXCIuL2Nvb3JkaW5hdGUuanNcIikuQ29vcmRpbmF0ZX0gU2FmZSB0cmFuc2Zvcm0gZnVuY3Rpb24gKHNvdXJjZSB0byBkZXN0aWF0aW9uKS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2FmZUNvb3JkaW5hdGVUcmFuc2Zvcm0oc291cmNlUHJvaiwgZGVzdFByb2osIHRyYW5zZm9ybSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGNvb3JkKSB7XG4gICAgdmFyIHNvdXJjZVggPSBjb29yZFswXTtcbiAgICB2YXIgc291cmNlWSA9IGNvb3JkWzFdO1xuICAgIHZhciB0cmFuc2Zvcm1lZCwgd29ybGRzQXdheTtcblxuICAgIGlmIChzb3VyY2VQcm9qLmNhbldyYXBYKCkpIHtcbiAgICAgIHZhciBzb3VyY2VFeHRlbnQgPSBzb3VyY2VQcm9qLmdldEV4dGVudCgpO1xuICAgICAgdmFyIHNvdXJjZUV4dGVudFdpZHRoID0gZ2V0V2lkdGgoc291cmNlRXh0ZW50KTtcbiAgICAgIHdvcmxkc0F3YXkgPSBnZXRXb3JsZHNBd2F5KGNvb3JkLCBzb3VyY2VQcm9qLCBzb3VyY2VFeHRlbnRXaWR0aCk7XG5cbiAgICAgIGlmICh3b3JsZHNBd2F5KSB7XG4gICAgICAgIC8vIE1vdmUgeCB0byB0aGUgcmVhbCB3b3JsZFxuICAgICAgICBzb3VyY2VYID0gc291cmNlWCAtIHdvcmxkc0F3YXkgKiBzb3VyY2VFeHRlbnRXaWR0aDtcbiAgICAgIH1cblxuICAgICAgc291cmNlWCA9IGNsYW1wKHNvdXJjZVgsIHNvdXJjZUV4dGVudFswXSwgc291cmNlRXh0ZW50WzJdKTtcbiAgICAgIHNvdXJjZVkgPSBjbGFtcChzb3VyY2VZLCBzb3VyY2VFeHRlbnRbMV0sIHNvdXJjZUV4dGVudFszXSk7XG4gICAgICB0cmFuc2Zvcm1lZCA9IHRyYW5zZm9ybShbc291cmNlWCwgc291cmNlWV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0cmFuc2Zvcm1lZCA9IHRyYW5zZm9ybShjb29yZCk7XG4gICAgfVxuXG4gICAgaWYgKHdvcmxkc0F3YXkgJiYgZGVzdFByb2ouY2FuV3JhcFgoKSkge1xuICAgICAgLy8gTW92ZSB0cmFuc2Zvcm1lZCBjb29yZGluYXRlIGJhY2sgdG8gdGhlIG9mZnNldCB3b3JsZFxuICAgICAgdHJhbnNmb3JtZWRbMF0gKz0gd29ybGRzQXdheSAqIGdldFdpZHRoKGRlc3RQcm9qLmdldEV4dGVudCgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJhbnNmb3JtZWQ7XG4gIH07XG59XG4vKipcbiAqIEFkZCB0cmFuc2Zvcm1zIHRvIGFuZCBmcm9tIEVQU0c6NDMyNiBhbmQgRVBTRzozODU3LiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWRcbiAqIGJ5IHdoZW4gdGhpcyBtb2R1bGUgaXMgZXhlY3V0ZWQgYW5kIHNob3VsZCBvbmx5IG5lZWQgdG8gYmUgY2FsbGVkIGFnYWluIGFmdGVyXG4gKiBgY2xlYXJBbGxQcm9qZWN0aW9ucygpYCBpcyBjYWxsZWQgKGUuZy4gaW4gdGVzdHMpLlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb21tb24oKSB7XG4gIC8vIEFkZCB0cmFuc2Zvcm1hdGlvbnMgdGhhdCBkb24ndCBhbHRlciBjb29yZGluYXRlcyB0byBjb252ZXJ0IHdpdGhpbiBzZXQgb2ZcbiAgLy8gcHJvamVjdGlvbnMgd2l0aCBlcXVhbCBtZWFuaW5nLlxuICBhZGRFcXVpdmFsZW50UHJvamVjdGlvbnMoRVBTRzM4NTdfUFJPSkVDVElPTlMpO1xuICBhZGRFcXVpdmFsZW50UHJvamVjdGlvbnMoRVBTRzQzMjZfUFJPSkVDVElPTlMpOyAvLyBBZGQgdHJhbnNmb3JtYXRpb25zIHRvIGNvbnZlcnQgRVBTRzo0MzI2IGxpa2UgY29vcmRpbmF0ZXMgdG8gRVBTRzozODU3IGxpa2VcbiAgLy8gY29vcmRpbmF0ZXMgYW5kIGJhY2suXG5cbiAgYWRkRXF1aXZhbGVudFRyYW5zZm9ybXMoRVBTRzQzMjZfUFJPSkVDVElPTlMsIEVQU0czODU3X1BST0pFQ1RJT05TLCBmcm9tRVBTRzQzMjYsIHRvRVBTRzQzMjYpO1xufVxuYWRkQ29tbW9uKCk7IiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIG1hcENvbnRhaW5lciA9IFwib3BlbmxheWVyc01hcC1tb2R1bGUtLW1hcENvbnRhaW5lci0tMVY3YnRcIjsiLCJpbXBvcnQgUmVhY3QsIHt1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWZ9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBNYXAgZnJvbSAnb2wvTWFwJztcbmltcG9ydCBWaWV3IGZyb20gJ29sL1ZpZXcnO1xuaW1wb3J0IEZlYXR1cmUsIHtGZWF0dXJlTGlrZX0gZnJvbSAnb2wvRmVhdHVyZSc7XG5pbXBvcnQgR2VvbWV0cnkgZnJvbSAnb2wvZ2VvbS9HZW9tZXRyeSc7XG5pbXBvcnQgVmVjdG9yTGF5ZXIgZnJvbSAnb2wvbGF5ZXIvVmVjdG9yJztcbmltcG9ydCBWZWN0b3JTb3VyY2UgZnJvbSAnb2wvc291cmNlL1ZlY3Rvcic7XG5pbXBvcnQge2Zyb21Mb25MYXR9IGZyb20gJ29sL3Byb2onO1xuaW1wb3J0IHtDb29yZGluYXRlfSBmcm9tICdvbC9jb29yZGluYXRlJztcbmltcG9ydCBvbG1zIGZyb20gJ29sLW1hcGJveC1zdHlsZSc7XG5pbXBvcnQgbWFwU3R5bGUgZnJvbSAnLi4vZGF0YS9tYXBTdHlsZSc7XG5pbXBvcnQgWm9vbVdhcm5pbmcgZnJvbSAnLi96b29tV2FybmluZyc7XG5pbXBvcnQgT3BlbmxheWVyc1BvcHVwIGZyb20gJy4vb3BlbmxheWVyc1BvcHVwJztcbmltcG9ydCB7dHJhbnNmb3JtRXh0ZW50fSBmcm9tICdvbC9zcmMvcHJvaic7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi9vcGVubGF5ZXJzTWFwLm1vZHVsZS5zY3NzJztcbmltcG9ydCAqIGFzIGNvbnN0YW50cyBmcm9tICcuLi9kYXRhL2NvbnN0YW50cyc7XG5pbXBvcnQge0V4dGVudH0gZnJvbSAnb2wvc3JjL2V4dGVudCc7XG5cbmludGVyZmFjZSBJTWFwV3JhcHBlclByb3BzIHtcbiAgZmVhdHVyZXM6IEZlYXR1cmU8R2VvbWV0cnk+W10sXG59XG5cbi8vIFRoZSBiZWxvdyBhZGFwdGVkIGZyb21cbi8vIGh0dHBzOi8vdGF5bG9yLmNhbGxzZW4ubWUvdXNpbmctb3BlbmxheWVycy13aXRoLXJlYWN0LWZ1bmN0aW9uYWwtY29tcG9uZW50cy9cbmNvbnN0IE1hcFdyYXBwZXIgPSAoe2ZlYXR1cmVzfTogSU1hcFdyYXBwZXJQcm9wcykgPT4ge1xuICBjb25zdCBbbWFwLCBzZXRNYXBdID0gdXNlU3RhdGU8TWFwPigpO1xuICBjb25zdCBbZmVhdHVyZXNMYXllciwgc2V0RmVhdHVyZXNMYXllcl0gPSB1c2VTdGF0ZTxWZWN0b3JMYXllcj4oKTtcbiAgY29uc3QgW3NlbGVjdGVkRmVhdHVyZSwgc2V0U2VsZWN0ZWRGZWF0dXJlXSA9IHVzZVN0YXRlPEZlYXR1cmVMaWtlPigpO1xuICBjb25zdCBbY3VycmVudFpvb20sIHNldEN1cnJlbnRab29tXSA9IHVzZVN0YXRlPG51bWJlcj4oNCk7XG4gIGNvbnN0IFtjdXJyZW50T3ZlcmxheVBvc2l0aW9uLCBzZXRDdXJyZW50T3ZlcmxheVBvc2l0aW9uXSA9IHVzZVN0YXRlPENvb3JkaW5hdGU+KFtdKTtcblxuICBjb25zdCBtYXBFbGVtZW50ID0gdXNlUmVmKCkgYXNcbiAgICBSZWFjdC5NdXRhYmxlUmVmT2JqZWN0PEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIC8vIGNyZWF0ZSBzdGF0ZSByZWYgdGhhdCBjYW4gYmUgYWNjZXNzZWQgaW4gT3BlbkxheWVycyBvbmNsaWNrIGNhbGxiYWNrIGZ1bmN0aW9uXG4gIC8vICBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNjA2NDM2NzBcbiAgY29uc3QgbWFwUmVmID0gdXNlUmVmKCkgYXMgUmVhY3QuTXV0YWJsZVJlZk9iamVjdDxNYXA+O1xuICBpZiAobWFwKSB7XG4gICAgbWFwUmVmLmN1cnJlbnQgPSBtYXA7XG4gIH1cblxuICBjb25zdCB0cmFuc2Zvcm0gPSAoZXh0ZW50OiBFeHRlbnQpIDogRXh0ZW50ID0+IHtcbiAgICByZXR1cm4gdHJhbnNmb3JtRXh0ZW50KGV4dGVudCwgJ0VQU0c6NDMyNicsICdFUFNHOjM4NTcnKTtcbiAgfTtcblxuXG4gIHVzZUVmZmVjdCggKCkgPT4ge1xuICAgIGNvbnN0IHZpZXcgPSBuZXcgVmlldyh7XG4gICAgICBjZW50ZXI6IGZyb21Mb25MYXQoY29uc3RhbnRzLkRFRkFVTFRfQ0VOVEVSKSxcbiAgICAgIHpvb206IDQsXG4gICAgICBtYXhab29tOiBjb25zdGFudHMuR0xPQkFMX01BWF9aT09NLFxuICAgICAgbWluWm9vbTogY29uc3RhbnRzLkdMT0JBTF9NSU5fWk9PTSxcbiAgICAgIGV4dGVudDogdHJhbnNmb3JtKGNvbnN0YW50cy5HTE9CQUxfTUFYX0JPVU5EUy5mbGF0KCkpIGFzIFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuICAgIH0pO1xuXG4gICAgLy8gY3JlYXRlIGFuZCBhZGQgaW5pdGlhbCB2ZWN0b3Igc291cmNlIGxheWVyLCB0byBiZSByZXBsYWNlZCBsYXllclxuICAgIGNvbnN0IGluaXRpYWxGZWF0dXJlc0xheWVyID0gbmV3IFZlY3RvckxheWVyKHtcbiAgICAgIHNvdXJjZTogbmV3IFZlY3RvclNvdXJjZSgpLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaW5pdGlhbE1hcCA9IG5ldyBNYXAoe1xuICAgICAgdGFyZ2V0OiBtYXBFbGVtZW50LmN1cnJlbnQsXG4gICAgICB2aWV3OiB2aWV3LFxuICAgICAgY29udHJvbHM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IGN1cnJlbnRab29tID0gTWF0aC5mbG9vcihpbml0aWFsTWFwLmdldFZpZXcoKS5nZXRab29tKCkgfHwgY29uc3RhbnRzLkdMT0JBTF9NSU5fWk9PTSk7XG5cbiAgICBpbml0aWFsTWFwLm9uKCdtb3ZlZW5kJywgaGFuZGxlTW92ZUVuZCk7XG4gICAgaW5pdGlhbE1hcC5vbignY2xpY2snLCBoYW5kbGVNYXBDbGljayk7XG4gICAgc2V0TWFwKGluaXRpYWxNYXApO1xuICAgIHNldEN1cnJlbnRab29tKGN1cnJlbnRab29tKTtcbiAgICBzZXRGZWF0dXJlc0xheWVyKGluaXRpYWxGZWF0dXJlc0xheWVyKTtcbiAgICBvbG1zKGluaXRpYWxNYXAsIG1hcFN0eWxlKTtcbiAgfSwgW10pO1xuXG5cbiAgLy8gdXBkYXRlIG1hcCBpZiBmZWF0dXJlcyBwcm9wIGNoYW5nZXNcbiAgdXNlRWZmZWN0KCAoKSA9PiB7XG4gICAgaWYgKGZlYXR1cmVzLmxlbmd0aCkgeyAvLyBtYXkgYmUgZW1wdHkgb24gZmlyc3QgcmVuZGVyXG4gICAgICAvLyBzZXQgZmVhdHVyZXMgdG8gbWFwXG4gICAgICBmZWF0dXJlc0xheWVyPy5zZXRTb3VyY2UoXG4gICAgICAgICAgbmV3IFZlY3RvclNvdXJjZSh7XG4gICAgICAgICAgICBmZWF0dXJlczogZmVhdHVyZXMsXG4gICAgICAgICAgfSksXG4gICAgICApO1xuICAgICAgY29uc3QgZXh0ZW50ID0gZmVhdHVyZXNMYXllcj8uZ2V0U291cmNlKCkuZ2V0RXh0ZW50KCk7XG4gICAgICBpZiAoZXh0ZW50KSB7XG4gICAgICAgIC8vIGZpdCBtYXAgdG8gZmVhdHVyZSBleHRlbnQgKHdpdGggMTAwcHggb2YgcGFkZGluZylcbiAgICAgICAgbWFwPy5nZXRWaWV3KCkuZml0KGV4dGVudCwge1xuICAgICAgICAgIHBhZGRpbmc6IFsxMDAsIDEwMCwgMTAwLCAxMDBdLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtmZWF0dXJlc10pO1xuXG4gIGNvbnN0IGhhbmRsZU1hcENsaWNrID0gKGV2ZW50OiB7IHBpeGVsOiBhbnkgfSkgPT4ge1xuICAgIGNvbnN0IGNsaWNrZWRDb29yZCA9IG1hcFJlZi5jdXJyZW50LmdldENvb3JkaW5hdGVGcm9tUGl4ZWwoZXZlbnQucGl4ZWwpO1xuXG4gICAgbGV0IGZlYXR1cmVGb3VuZCA9IGZhbHNlO1xuICAgIG1hcFJlZi5jdXJyZW50LmZvckVhY2hGZWF0dXJlQXRQaXhlbChldmVudC5waXhlbCwgKGZlYXR1cmUpID0+IHtcbiAgICAgIGZlYXR1cmVGb3VuZCA9IHRydWU7XG4gICAgICBzZXRTZWxlY3RlZEZlYXR1cmUoZmVhdHVyZSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIGlmICghZmVhdHVyZUZvdW5kKSB7XG4gICAgICBzZXRTZWxlY3RlZEZlYXR1cmUodW5kZWZpbmVkKTtcbiAgICB9XG5cbiAgICBzZXRDdXJyZW50T3ZlcmxheVBvc2l0aW9uKGNsaWNrZWRDb29yZCk7XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlTW92ZUVuZCA9ICgpID0+IHtcbiAgICBjb25zdCBuZXdab29tID0gTWF0aC5mbG9vcihtYXBSZWYuY3VycmVudC5nZXRWaWV3KCkuZ2V0Wm9vbSgpIHx8IGNvbnN0YW50cy5HTE9CQUxfTUlOX1pPT00pO1xuICAgIGlmIChjdXJyZW50Wm9vbSAhPSBuZXdab29tKSB7XG4gICAgICBzZXRDdXJyZW50Wm9vbShuZXdab29tKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAgPGRpdiByZWY9e21hcEVsZW1lbnR9IGNsYXNzTmFtZT17c3R5bGVzLm1hcENvbnRhaW5lcn0vPlxuICAgICAge21hcD9cbiAgICAgICAgPE9wZW5sYXllcnNQb3B1cCBzZWxlY3RlZEZlYXR1cmU9e3NlbGVjdGVkRmVhdHVyZSF9IG1hcD17bWFwIX0gcG9zaXRpb249e2N1cnJlbnRPdmVybGF5UG9zaXRpb259IC8+IDpcbiAgICAgICAgJydcbiAgICAgIH1cbiAgICAgIDxab29tV2FybmluZyB6b29tTGV2ZWw9e2N1cnJlbnRab29tfSAvPlxuICAgIDwvPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTWFwV3JhcHBlcjtcbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7dXNlRmxhZ3N9IGZyb20gJy4uL2NvbnRleHRzL0ZsYWdDb250ZXh0JztcbmltcG9ydCBNYXBib3hNYXAgZnJvbSAnLi9tYXBib3hNYXAnO1xuaW1wb3J0IE9wZW5MYXllcnNNYXAgZnJvbSAnLi9vcGVubGF5ZXJzTWFwJztcblxuY29uc3QgTWFwV3JhcHBlciA9ICgpID0+IHtcbiAgY29uc3QgZmxhZ3MgPSB1c2VGbGFncygpO1xuICByZXR1cm4gKFxuICAgIDxkaXY+XG4gICAgICB7XG4gICAgICAgICAgICBmbGFncy5pbmNsdWRlcygnbWInKSA/XG4gICAgICAgICAgICA8TWFwYm94TWFwIC8+IDpcbiAgICAgICAgICAgIDxPcGVuTGF5ZXJzTWFwIGZlYXR1cmVzPXtbXX0vPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICApO1xufTtcblxuXG5leHBvcnQgZGVmYXVsdCBNYXBXcmFwcGVyO1xuIiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIGhvd1lvdUNhbkhlbHBDb250YWluZXIgPSBcIkhvd1lvdUNhbkhlbHAtbW9kdWxlLS1ob3dZb3VDYW5IZWxwQ29udGFpbmVyLS0ya3FCYVwiOyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi9Ib3dZb3VDYW5IZWxwLm1vZHVsZS5zY3NzJztcblxuY29uc3QgSG93WW91Q2FuSGVscCA9ICgpID0+IHtcbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmhvd1lvdUNhbkhlbHBDb250YWluZXJ9PlxuICAgICAgPGgyPkhvdyBZb3UgQ2FuIEhlbHAgSW1wcm92ZSB0aGUgVG9vbDwvaDI+XG4gICAgICA8dWw+XG4gICAgICAgIDxsaT5JZiB5b3UgaGF2ZSBpbmZvcm1hdGlvbiB0aGF0IGNvdWxkIGhlbHAsIHdl4oCZZCBsb3ZlIHRvIGhlYXIgZnJvbSB5b3UuPC9saT5cbiAgICAgICAgPGxpPlZpZXcgb3VyIGZ1bGwgc2V0IG9mIGRhdGEgc291cmNlcyBhbmQgbWV0aG9kb2xvZ3lcbiAgICAgICAgICAgIHdoZXJlIHlvdSBjYW4gYWRkIG9yIGRvd25sb2FkIHNvdXJjZXMgYW5kIGNoZWNrIHN0YXR1c2VzIG9uIG91ciBkYXRhIHJvYWRtYXAuPC9saT5cbiAgICAgICAgPGxpPkNoZWNrIG91dCBvdXIgdGltZWxpbmUgYW5kIHNlbmQgZmVlZGJhY2sgb3IgYXR0ZW5kIHJlbGV2YW50IGV2ZW50cy48L2xpPlxuICAgICAgICA8bGk+Q29udGFjdCB1cyBhbmQgc2hhcmUgdGhlIHN0b3JpZXMgb2YgeW91ciBjb21tdW5pdHkuPC9saT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBIb3dZb3VDYW5IZWxwO1xuIiwiLy8gZXh0cmFjdGVkIGJ5IG1pbmktY3NzLWV4dHJhY3QtcGx1Z2luXG5leHBvcnQgdmFyIGxlZ2VuZENvbnRhaW5lciA9IFwibGVnZW5kLW1vZHVsZS0tbGVnZW5kQ29udGFpbmVyLS0zWDQ2MFwiO1xuZXhwb3J0IHZhciBzd2F0Y2hDb250YWluZXIgPSBcImxlZ2VuZC1tb2R1bGUtLXN3YXRjaENvbnRhaW5lci0tMkdvWGlcIjtcbmV4cG9ydCB2YXIgbGVnZW5kSXRlbSA9IFwibGVnZW5kLW1vZHVsZS0tbGVnZW5kSXRlbS0tMUNKcDJcIjtcbmV4cG9ydCB2YXIgY29sb3JTd2F0Y2ggPSBcImxlZ2VuZC1tb2R1bGUtLWNvbG9yU3dhdGNoLS0yeDZrelwiO1xuZXhwb3J0IHZhciBwcmlvcml0aXplZCA9IFwibGVnZW5kLW1vZHVsZS0tcHJpb3JpdGl6ZWQtLTFMV1FVXCI7XG5leHBvcnQgdmFyIHRocmVzaG9sZCA9IFwibGVnZW5kLW1vZHVsZS0tdGhyZXNob2xkLS0xMVZfQVwiO1xuZXhwb3J0IHZhciBub25Qcmlvcml0aXplZCA9IFwibGVnZW5kLW1vZHVsZS0tbm9uUHJpb3JpdGl6ZWQtLUFKcWhwXCI7IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCAqIGFzIHN0eWxlcyBmcm9tICcuL2xlZ2VuZC5tb2R1bGUuc2Nzcyc7XG5cbmNvbnN0IExlZ2VuZCA9ICgpID0+IHtcbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmxlZ2VuZENvbnRhaW5lcn0+XG4gICAgICA8aDMgY2xhc3NOYW1lPXtzdHlsZXMubGVnZW5kSGVhZGVyfT5DT0xPUiBLRVk8L2gzPlxuICAgICAgPGRpdiBjbGFzc05hbWU9e3N0eWxlcy5zd2F0Y2hDb250YWluZXJ9PlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmxlZ2VuZEl0ZW19PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtzdHlsZXMuY29sb3JTd2F0Y2h9IGlkPXtzdHlsZXMucHJpb3JpdGl6ZWR9IC8+XG4gICAgICAgICAgPHNwYW4+UHJpb3JpdGl6ZWQgQ29tbXVuaXR5PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9e3N0eWxlcy5sZWdlbmRJdGVtfT5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmNvbG9yU3dhdGNofSBpZD17c3R5bGVzLnRocmVzaG9sZH0gLz5cbiAgICAgICAgICA8c3Bhbj5UaHJlc2hvbGQgQ29tbXVuaXR5PC9zcGFuPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9e3N0eWxlcy5sZWdlbmRJdGVtfT5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17c3R5bGVzLmNvbG9yU3dhdGNofSBpZD17c3R5bGVzLm5vblByaW9yaXRpemVkfSAvPlxuICAgICAgICAgIDxzcGFuPk5vbi1Qcmlvcml0aXplZCBDb21tdW5pdHk8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBMZWdlbmQ7XG4iLCIvLyBleHRyYWN0ZWQgYnkgbWluaS1jc3MtZXh0cmFjdC1wbHVnaW5cbmV4cG9ydCB2YXIgZGlzY2xhaW1lciA9IFwiY2Vqc3QtbW9kdWxlLS1kaXNjbGFpbWVyLS0zTEMxeVwiOyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgTGF5b3V0IGZyb20gJy4uL2NvbXBvbmVudHMvbGF5b3V0Jztcbi8vIGltcG9ydCBNYXBXcmFwcGVyIGZyb20gJy4uL2NvbXBvbmVudHMvbWFwJztcbmltcG9ydCBNYXBXcmFwcGVyIGZyb20gJy4uL2NvbXBvbmVudHMvbWFwV3JhcHBlcic7XG5pbXBvcnQgSG93WW91Q2FuSGVscCBmcm9tICcuLi9jb21wb25lbnRzL0hvd1lvdUNhbkhlbHAnO1xuaW1wb3J0IExlZ2VuZCBmcm9tICcuLi9jb21wb25lbnRzL2xlZ2VuZCc7XG5pbXBvcnQge0FsZXJ0fSBmcm9tICdAdHJ1c3N3b3Jrcy9yZWFjdC11c3dkcyc7XG5pbXBvcnQgKiBhcyBzdHlsZXMgZnJvbSAnLi9jZWpzdC5tb2R1bGUuc2Nzcyc7XG5cblxuaW50ZXJmYWNlIElNYXBQYWdlUHJvcHMge1xuICBsb2NhdGlvbjogTG9jYXRpb247XG59XG5cbmNvbnN0IENFSlNUUGFnZSA9ICh7bG9jYXRpb259OiBJTWFwUGFnZVByb3BzKSA9PiB7XG4gIC8vIFdlIHRlbXBvcmFyaWx5IHJlbW92ZWQgTWFwQ29udHJvbHMsIHdoaWNoIHdvdWxkIGVuYWJsZSB5b3UgdG8gYHNldEZlYXR1cmVzYCBhbHNvLCBmb3Igbm93XG4gIC8vICAgV2Ugd2lsbCBicmluZyBiYWNrIGxhdGVyIHdoZW4gd2UgaGF2ZSBpbnRlcmFjdGl2ZSBjb250cm9scy5cbiAgcmV0dXJuIChcbiAgICA8TGF5b3V0IGxvY2F0aW9uPXtsb2NhdGlvbn0+XG4gICAgICA8bWFpbiBpZD1cIm1haW4tY29udGVudFwiIHJvbGU9XCJtYWluXCI+XG4gICAgICAgIDxwIGNsYXNzTmFtZT17c3R5bGVzLmRpc2NsYWltZXJ9PlxuICAgICAgICAgIFRoZSBDbGltYXRlIGFuZCBFY29ub21pYyBKdXN0aWNlIFNjcmVlbmluZyBUb29sIGhlbHBzXG4gICAgICAgICAgaWRlbnRpZnkgYW5kIHByaW9yaXRpemUgY29tbXVuaXRpZXMgYWNyb3NzIHRoZSBVbml0ZWRcbiAgICAgICAgICBTdGF0ZXMgYW5kIFVTIHRlcnJpdG9yaWVzIHRoYXQgaGF2ZSBiZWVuIGhpc3RvcmljYWxseVxuICAgICAgICAgIG92ZXJidXJkZW5lZCBhbmQgdW5kZXJzZXJ2ZWQgc28gdGhhdCB0aGV5IG1heSByZWNlaXZlXG4gICAgICAgICAgNDAlIG9mIHRoZSBiZW5lZml0cyBmcm9tIGludmVzdG1lbnRzIGluIHNpeCBrZXkgYXJlYXMgYXNcbiAgICAgICAgICBvdXRsaW5lZCBpbiB0aGUgPGFcbiAgICAgICAgICAgIGhyZWY9eydodHRwczovL3d3dy53aGl0ZWhvdXNlLmdvdi9icmllZmluZy1yb29tLycgK1xuICAgICAgICAgICAgICAgICAgICAncHJlc2lkZW50aWFsLWFjdGlvbnMvMjAyMS8wMS8yNy8nICtcbiAgICAgICAgICAgICAgICAgICAgJ2V4ZWN1dGl2ZS1vcmRlci1vbi10YWNrbGluZy10aGUtY2xpbWF0ZS0nICtcbiAgICAgICAgICAgICAgICAgICAgJ2NyaXNpcy1hdC1ob21lLWFuZC1hYnJvYWQvJ31cbiAgICAgICAgICAgIHRhcmdldD17J19ibGFuayd9XG4gICAgICAgICAgICByZWw9eydub3JlZmVycmVyJ30+XG4gICAgICAgICAgICAgICAgICAgIEV4ZWN1dGl2ZSBPcmRlciBvbiBUYWNrbGluZyB0aGUgQ2xpbWF0ZSBDcmlzaXMgYXQgSG9tZSBhbmRcbiAgICAgICAgICAgICAgICAgICAgQWJyb2FkPC9hPi5cbiAgICAgICAgICBFeHBsb3JlIHRoZSBtYXAgYmVsb3cgb3IgbGVhcm5cbiAgICAgICAgICBtb3JlIGFib3V0IHRoZSBtZXRob2RvbG9neSBhbmQgZGF0YSBpbmRpY2F0b3JzIHVzZWQgdG9cbiAgICAgICAgICBwcmlvcml0aXplIEp1c3RpY2U0MCBjb21tdW5pdGllcy5cbiAgICAgICAgPC9wPlxuICAgICAgICA8QWxlcnRcbiAgICAgICAgICB0eXBlPVwid2FybmluZ1wiXG4gICAgICAgICAgaGVhZGluZz1cIkxpbWl0ZWQgRGF0YSBTb3VyY2VzXCI+XG4gICAgICAgICAgPHA+XG4gICAgICAgICAgICBJbiB0aGlzIHRvb2wsIHdlIGFyZSB1c2luZyBkYXRhIHNvdXJjZXMgdGhhdCBvdXJcbiAgICAgICAgICAgIGNvbWJpbmVkIGJ5IG91ciBjdW11bGF0aXZlIGltcGFjdCBtZXRob2RvbG9neS5cbiAgICAgICAgICAgIE91ciBzb3VyY2VzIHdlcmUgc2VsZWN0ZWQgYmVjYXVzZSBzaXQgYW1ldCxcbiAgICAgICAgICAgIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcuIFNlZSBhbGwgdGhlIHNvdXJjZXMgd2VcbiAgICAgICAgICAgIGFyZSBpbnZlc3RpZ2F0aW5nIG9uIG91ciBkYXRhIHJvYWRtYXAuXG4gICAgICAgICAgPC9wPlxuICAgICAgICA8L0FsZXJ0PlxuICAgICAgICA8aDI+RXhwbG9yZSB0aGUgVG9vbDwvaDI+XG4gICAgICAgIDxNYXBXcmFwcGVyLz5cbiAgICAgICAgPExlZ2VuZCAvPlxuICAgICAgICA8SG93WW91Q2FuSGVscCAvPlxuICAgICAgPC9tYWluPlxuICAgIDwvTGF5b3V0PlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQ0VKU1RQYWdlO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7998\n')}}]); |