@preply/ds-docs 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{0.7b8b9609.iframe.bundle.js → 0.6ada39c2.iframe.bundle.js} +1 -1
- package/dist/{10.33abb5a2.iframe.bundle.js → 10.e192e6e4.iframe.bundle.js} +1 -1
- package/dist/{11.afacd9f9.iframe.bundle.js → 11.b6e0dad2.iframe.bundle.js} +1 -1
- package/dist/{12.6b86b479.iframe.bundle.js → 12.e98fba11.iframe.bundle.js} +1 -1
- package/dist/{9.dd9559d9.iframe.bundle.js → 9.09e2ab27.iframe.bundle.js} +1 -1
- package/dist/iframe.html +1 -1
- package/dist/main~493df0b3.fe189233.iframe.bundle.js +1 -0
- package/dist/{runtime~main.13162a7e.iframe.bundle.js → runtime~main.d90d47fd.iframe.bundle.js} +1 -1
- package/dist/vendors~main~253ae210.bfb233d6.iframe.bundle.js +1 -0
- package/dist/{vendors~main~4134d62c.6ff79cb1.iframe.bundle.js → vendors~main~4134d62c.704da3e3.iframe.bundle.js} +1 -1
- package/dist/vendors~main~678f84af.748734a2.iframe.bundle.js +1 -0
- package/dist/vendors~main~a353122d.088ca20f.iframe.bundle.js +1 -0
- package/dist/{vendors~main~bdc480fb.797488f6.iframe.bundle.js → vendors~main~bdc480fb.b2a1c79b.iframe.bundle.js} +1 -1
- package/dist/vendors~main~d88e64ba.d8e7775c.iframe.bundle.js +1 -0
- package/package.json +2 -2
- package/dist/main~493df0b3.3f30eb67.iframe.bundle.js +0 -1
- package/dist/vendors~main~253ae210.d1f8c192.iframe.bundle.js +0 -1
- package/dist/vendors~main~678f84af.ca8c63c3.iframe.bundle.js +0 -1
- package/dist/vendors~main~a353122d.690113e0.iframe.bundle.js +0 -1
- package/dist/vendors~main~d88e64ba.b6b4d491.iframe.bundle.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{1011:function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OverlayScrollbarsComponent", function() { return OverlayScrollbarsComponent; });\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(577);\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(120);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(48);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(28);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(51);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(71);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(118);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(20);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(18);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(4);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(1);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(1090);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__);\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n\n\n\n/**\n * Using overlayscrollbars-react component results use the esm modules\n * which doesn\'t go through babel leading to IE 11 uncompatibility\n * A PR is submitted that may fix this:\n * https://github.com/KingSora/OverlayScrollbars/pull/218\n * */\nvar OverlayScrollbarsComponent = function OverlayScrollbarsComponent(_ref) {\n var _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n extensions = _ref.extensions,\n className = _ref.className,\n children = _ref.children,\n rest = _objectWithoutProperties(_ref, ["options", "extensions", "className", "children"]);\n\n var osTargetRef = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n var osInstance = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n osInstance.current = overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default()(osTargetRef.current, options, extensions);\n mergeHostClassNames(osInstance.current, className);\n return function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.destroy();\n osInstance.current = null;\n }\n };\n }, []);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.options(options);\n }\n }, [options]);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n mergeHostClassNames(osInstance.current, className);\n }\n }, [className]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", _extends({\n className: "os-host"\n }, rest, {\n ref: osTargetRef\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-resize-observer-host"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-padding"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-viewport"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-content"\n }, children))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-horizontal "\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-vertical"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-corner"\n }));\n};\nOverlayScrollbarsComponent.displayName = "OverlayScrollbarsComponent";\n\nfunction mergeHostClassNames(osInstance, className) {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance)) {\n var _osInstance$getElemen = osInstance.getElements(),\n host = _osInstance$getElemen.host;\n\n var regex = new RegExp("(^os-host([-_].+|)$)|".concat(osInstance.options().className.replace(/\\s/g, \'$|\'), "$"), \'g\');\n var osClassNames = host.className.split(\' \').filter(function (name) {\n return name.match(regex);\n }).join(\' \');\n host.className = "".concat(osClassNames, " ").concat(className || \'\');\n }\n}\n\n/* harmony default export */ __webpack_exports__["default"] = (OverlayScrollbarsComponent);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHN0b3J5Ym9vay9jb21wb25lbnRzL2Rpc3QvZXNtL1Njcm9sbEFyZWEvT3ZlcmxheVNjcm9sbGJhcnMuanM/ZmIzZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0Q7QUFDUDtBQUNLO0FBQ0Y7QUFDSjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Q7QUFDTDtBQUNPOztBQUU3QyxxQkFBcUIsZ0RBQWdELGdCQUFnQixzQkFBc0IsT0FBTywyQkFBMkIsMEJBQTBCLHlEQUF5RCwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsZUFBZSxHQUFHLHdDQUF3Qzs7QUFFM1QscURBQXFELCtCQUErQiw4REFBOEQsWUFBWSxvQ0FBb0MsNkRBQTZELFlBQVksNkJBQTZCLE9BQU8sMkJBQTJCLDBDQUEwQyx3RUFBd0UsMkJBQTJCLEVBQUUsRUFBRSxlQUFlOztBQUUxZSwwREFBMEQsK0JBQStCLGlCQUFpQixzQ0FBc0MsWUFBWSxZQUFZLHVCQUF1QixPQUFPLHFCQUFxQiwwQ0FBMEMsMkJBQTJCLEVBQUUsZUFBZTs7QUFFdlI7QUFDd0I7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLDZDQUFLO0FBQ3pCLG1CQUFtQiw2Q0FBSztBQUN4QixFQUFFLDZDQUFLO0FBQ1AseUJBQXlCLHlEQUFpQjtBQUMxQztBQUNBO0FBQ0EsVUFBVSx5REFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCLDZDQUFLO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRyxnQkFBZ0IsNkNBQUs7QUFDeEI7QUFDQSxHQUFHLGdCQUFnQiw2Q0FBSztBQUN4QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsNEJBQTRCLDZDQUFLO0FBQ3BDO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxrQkFBa0IsNkNBQUs7QUFDMUI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGtCQUFrQiw2Q0FBSztBQUMxQjtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsTUFBTSx5REFBaUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVlLHlGQUEwQiIsImZpbGUiOiIxMDExLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuam9pbi5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZpbHRlci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmNvbmNhdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC5rZXlzLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuc3ltYm9sLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LmFzc2lnbi5qc1wiO1xuXG5mdW5jdGlvbiBfZXh0ZW5kcygpIHsgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OyByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpOyB2YXIga2V5LCBpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTsgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHsga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTsgaWYgKCFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoc291cmNlLCBrZXkpKSBjb250aW51ZTsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IHt9OyB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7IHZhciBrZXksIGk7IGZvciAoaSA9IDA7IGkgPCBzb3VyY2VLZXlzLmxlbmd0aDsgaSsrKSB7IGtleSA9IHNvdXJjZUtleXNbaV07IGlmIChleGNsdWRlZC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE92ZXJsYXlTY3JvbGxiYXJzIGZyb20gJ292ZXJsYXlzY3JvbGxiYXJzJztcblxuLyoqXG4gKiBVc2luZyBvdmVybGF5c2Nyb2xsYmFycy1yZWFjdCBjb21wb25lbnQgcmVzdWx0cyB1c2UgdGhlIGVzbSBtb2R1bGVzXG4gKiB3aGljaCBkb2Vzbid0IGdvIHRocm91Z2ggYmFiZWwgbGVhZGluZyB0byBJRSAxMSB1bmNvbXBhdGliaWxpdHlcbiAqIEEgUFIgaXMgc3VibWl0dGVkIHRoYXQgbWF5IGZpeCB0aGlzOlxuICogaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhL092ZXJsYXlTY3JvbGxiYXJzL3B1bGwvMjE4XG4gKiAqL1xuZXhwb3J0IHZhciBPdmVybGF5U2Nyb2xsYmFyc0NvbXBvbmVudCA9IGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50KF9yZWYpIHtcbiAgdmFyIF9yZWYkb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG9wdGlvbnMgPSBfcmVmJG9wdGlvbnMgPT09IHZvaWQgMCA/IHt9IDogX3JlZiRvcHRpb25zLFxuICAgICAgZXh0ZW5zaW9ucyA9IF9yZWYuZXh0ZW5zaW9ucyxcbiAgICAgIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLFxuICAgICAgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgICAgcmVzdCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhfcmVmLCBbXCJvcHRpb25zXCIsIFwiZXh0ZW5zaW9uc1wiLCBcImNsYXNzTmFtZVwiLCBcImNoaWxkcmVuXCJdKTtcblxuICB2YXIgb3NUYXJnZXRSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgdmFyIG9zSW5zdGFuY2UgPSBSZWFjdC51c2VSZWYoKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBvc0luc3RhbmNlLmN1cnJlbnQgPSBPdmVybGF5U2Nyb2xsYmFycyhvc1RhcmdldFJlZi5jdXJyZW50LCBvcHRpb25zLCBleHRlbnNpb25zKTtcbiAgICBtZXJnZUhvc3RDbGFzc05hbWVzKG9zSW5zdGFuY2UuY3VycmVudCwgY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50LmRlc3Ryb3koKTtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbXSk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgIG9zSW5zdGFuY2UuY3VycmVudC5vcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cbiAgfSwgW29wdGlvbnNdKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoT3ZlcmxheVNjcm9sbGJhcnMudmFsaWQob3NJbnN0YW5jZS5jdXJyZW50KSkge1xuICAgICAgbWVyZ2VIb3N0Q2xhc3NOYW1lcyhvc0luc3RhbmNlLmN1cnJlbnQsIGNsYXNzTmFtZSk7XG4gICAgfVxuICB9LCBbY2xhc3NOYW1lXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgY2xhc3NOYW1lOiBcIm9zLWhvc3RcIlxuICB9LCByZXN0LCB7XG4gICAgcmVmOiBvc1RhcmdldFJlZlxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdFwiXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXBhZGRpbmdcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXZpZXdwb3J0XCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1jb250ZW50XCJcbiAgfSwgY2hpbGRyZW4pKSksIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiXG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyLXRyYWNrXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItaGFuZGxlXCJcbiAgfSkpKSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItdHJhY2tcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1oYW5kbGVcIlxuICB9KSkpLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1jb3JuZXJcIlxuICB9KSk7XG59O1xuT3ZlcmxheVNjcm9sbGJhcnNDb21wb25lbnQuZGlzcGxheU5hbWUgPSBcIk92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50XCI7XG5cbmZ1bmN0aW9uIG1lcmdlSG9zdENsYXNzTmFtZXMob3NJbnN0YW5jZSwgY2xhc3NOYW1lKSB7XG4gIGlmIChPdmVybGF5U2Nyb2xsYmFycy52YWxpZChvc0luc3RhbmNlKSkge1xuICAgIHZhciBfb3NJbnN0YW5jZSRnZXRFbGVtZW4gPSBvc0luc3RhbmNlLmdldEVsZW1lbnRzKCksXG4gICAgICAgIGhvc3QgPSBfb3NJbnN0YW5jZSRnZXRFbGVtZW4uaG9zdDtcblxuICAgIHZhciByZWdleCA9IG5ldyBSZWdFeHAoXCIoXm9zLWhvc3QoWy1fXS4rfCkkKXxcIi5jb25jYXQob3NJbnN0YW5jZS5vcHRpb25zKCkuY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCAnJHwnKSwgXCIkXCIpLCAnZycpO1xuICAgIHZhciBvc0NsYXNzTmFtZXMgPSBob3N0LmNsYXNzTmFtZS5zcGxpdCgnICcpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xuICAgICAgcmV0dXJuIG5hbWUubWF0Y2gocmVnZXgpO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgICBob3N0LmNsYXNzTmFtZSA9IFwiXCIuY29uY2F0KG9zQ2xhc3NOYW1lcywgXCIgXCIpLmNvbmNhdChjbGFzc05hbWUgfHwgJycpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1011\n')},1090:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * OverlayScrollbars\r\n * https://github.com/KingSora/OverlayScrollbars\r\n *\r\n * Version: 1.13.0\r\n *\r\n * Copyright KingSora | Rene Haas.\r\n * https://github.com/KingSora\r\n *\r\n * Released under the MIT license.\r\n * Date: 02.08.2020\r\n */\r\n\r\n(function (global, factory) {\r\n if (true)\r\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { return factory(global, global.document, undefined); }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n else {}\r\n}(typeof window !== 'undefined' ? window : this,\r\n function (window, document, undefined) {\r\n 'use strict';\r\n var PLUGINNAME = 'OverlayScrollbars';\r\n var TYPES = {\r\n o: 'object',\r\n f: 'function',\r\n a: 'array',\r\n s: 'string',\r\n b: 'boolean',\r\n n: 'number',\r\n u: 'undefined',\r\n z: 'null'\r\n //d : 'date',\r\n //e : 'error',\r\n //r : 'regexp',\r\n //y : 'symbol'\r\n };\r\n var LEXICON = {\r\n c: 'class',\r\n s: 'style',\r\n i: 'id',\r\n l: 'length',\r\n p: 'prototype',\r\n ti: 'tabindex',\r\n oH: 'offsetHeight',\r\n cH: 'clientHeight',\r\n sH: 'scrollHeight',\r\n oW: 'offsetWidth',\r\n cW: 'clientWidth',\r\n sW: 'scrollWidth',\r\n hOP: 'hasOwnProperty',\r\n bCR: 'getBoundingClientRect'\r\n };\r\n var VENDORS = (function () {\r\n //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix\r\n var jsCache = {};\r\n var cssCache = {};\r\n var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-'];\r\n var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS'];\r\n function firstLetterToUpper(str) {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n }\r\n\r\n return {\r\n _cssPrefixes: cssPrefixes,\r\n _jsPrefixes: jsPrefixes,\r\n _cssProperty: function (name) {\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var uppercasedName = firstLetterToUpper(name);\r\n var elmStyle = document.createElement('div')[LEXICON.s];\r\n var resultPossibilities;\r\n var i = 0;\r\n var v;\r\n var currVendorWithoutDashes;\r\n\r\n for (; i < cssPrefixes.length; i++) {\r\n currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, '');\r\n resultPossibilities = [\r\n name, //transition\r\n cssPrefixes[i] + name, //-webkit-transition\r\n currVendorWithoutDashes + uppercasedName, //webkitTransition\r\n firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition\r\n ];\r\n for (v = 0; v < resultPossibilities[LEXICON.l]; v++) {\r\n if (elmStyle[resultPossibilities[v]] !== undefined) {\r\n result = resultPossibilities[v];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _cssPropertyValue: function (property, values, suffix) {\r\n var name = property + ' ' + values;\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var dummyStyle = document.createElement('div')[LEXICON.s];\r\n var possbleValues = values.split(' ');\r\n var preparedSuffix = suffix || '';\r\n var i = 0;\r\n var v = -1;\r\n var prop;\r\n\r\n for (; i < possbleValues[LEXICON.l]; i++) {\r\n for (; v < VENDORS._cssPrefixes[LEXICON.l]; v++) {\r\n prop = v < 0 ? possbleValues[i] : VENDORS._cssPrefixes[v] + possbleValues[i];\r\n dummyStyle.cssText = property + ':' + prop + preparedSuffix;\r\n if (dummyStyle[LEXICON.l]) {\r\n result = prop;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _jsAPI: function (name, isInterface, fallback) {\r\n var i = 0;\r\n var result = jsCache[name];\r\n\r\n if (!jsCache[LEXICON.hOP](name)) {\r\n result = window[name];\r\n for (; i < jsPrefixes[LEXICON.l]; i++)\r\n result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)];\r\n jsCache[name] = result;\r\n }\r\n return result || fallback;\r\n }\r\n }\r\n })();\r\n var COMPATIBILITY = (function () {\r\n function windowSize(x) {\r\n return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH];\r\n }\r\n function bind(func, thisObj) {\r\n if (typeof func != TYPES.f) {\r\n throw \"Can't bind function!\";\r\n // closest thing possible to the ECMAScript 5\r\n // internal IsCallable function\r\n //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');\r\n }\r\n var proto = LEXICON.p;\r\n var aArgs = Array[proto].slice.call(arguments, 2);\r\n var fNOP = function () { };\r\n var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); };\r\n\r\n if (func[proto])\r\n fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property\r\n fBound[proto] = new fNOP();\r\n\r\n return fBound;\r\n }\r\n\r\n return {\r\n /**\r\n * Gets the current window width.\r\n * @returns {Number|number} The current window width in pixel.\r\n */\r\n wW: bind(windowSize, 0, true),\r\n\r\n /**\r\n * Gets the current window height.\r\n * @returns {Number|number} The current window height in pixel.\r\n */\r\n wH: bind(windowSize, 0),\r\n\r\n /**\r\n * Gets the MutationObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined.\r\n */\r\n mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true),\r\n\r\n /**\r\n * Gets the ResizeObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined.\r\n */\r\n rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true),\r\n\r\n /**\r\n * Gets the RequestAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill.\r\n */\r\n rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }),\r\n\r\n /**\r\n * Gets the CancelAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill.\r\n */\r\n cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }),\r\n\r\n /**\r\n * Gets the current time.\r\n * @returns {number} The current time.\r\n */\r\n now: function () {\r\n return Date.now && Date.now() || new Date().getTime();\r\n },\r\n\r\n /**\r\n * Stops the propagation of the given event.\r\n * @param event The event of which the propagation shall be stoped.\r\n */\r\n stpP: function (event) {\r\n if (event.stopPropagation)\r\n event.stopPropagation();\r\n else\r\n event.cancelBubble = true;\r\n },\r\n\r\n /**\r\n * Prevents the default action of the given event.\r\n * @param event The event of which the default action shall be prevented.\r\n */\r\n prvD: function (event) {\r\n if (event.preventDefault && event.cancelable)\r\n event.preventDefault();\r\n else\r\n event.returnValue = false;\r\n },\r\n\r\n /**\r\n * Gets the pageX and pageY values of the given mouse event.\r\n * @param event The mouse event of which the pageX and pageX shall be got.\r\n * @returns {{x: number, y: number}} x = pageX value, y = pageY value.\r\n */\r\n page: function (event) {\r\n event = event.originalEvent || event;\r\n\r\n var strPage = 'page';\r\n var strClient = 'client';\r\n var strX = 'X';\r\n var strY = 'Y';\r\n var target = event.target || event.srcElement || document;\r\n var eventDoc = target.ownerDocument || document;\r\n var doc = eventDoc.documentElement;\r\n var body = eventDoc.body;\r\n\r\n //if touch event return return pageX/Y of it\r\n if (event.touches !== undefined) {\r\n var touch = event.touches[0];\r\n return {\r\n x: touch[strPage + strX],\r\n y: touch[strPage + strY]\r\n }\r\n }\r\n\r\n // Calculate pageX/Y if not native supported\r\n if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) {\r\n\r\n return {\r\n x: event[strClient + strX] +\r\n (doc && doc.scrollLeft || body && body.scrollLeft || 0) -\r\n (doc && doc.clientLeft || body && body.clientLeft || 0),\r\n y: event[strClient + strY] +\r\n (doc && doc.scrollTop || body && body.scrollTop || 0) -\r\n (doc && doc.clientTop || body && body.clientTop || 0)\r\n }\r\n }\r\n return {\r\n x: event[strPage + strX],\r\n y: event[strPage + strY]\r\n };\r\n },\r\n\r\n /**\r\n * Gets the clicked mouse button of the given mouse event.\r\n * @param event The mouse event of which the clicked button shal be got.\r\n * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton)\r\n */\r\n mBtn: function (event) {\r\n var button = event.button;\r\n if (!event.which && button !== undefined)\r\n return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));\r\n else\r\n return event.which;\r\n },\r\n\r\n /**\r\n * Checks whether a item is in the given array and returns its index.\r\n * @param item The item of which the position in the array shall be determined.\r\n * @param arr The array.\r\n * @returns {number} The zero based index of the item or -1 if the item isn't in the array.\r\n */\r\n inA: function (item, arr) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++)\r\n //Sometiems in IE a \"SCRIPT70\" Permission denied error occurs if HTML elements in a iFrame are compared\r\n try {\r\n if (arr[i] === item)\r\n return i;\r\n }\r\n catch (e) { }\r\n return -1;\r\n },\r\n\r\n /**\r\n * Returns true if the given value is a array.\r\n * @param arr The potential array.\r\n * @returns {boolean} True if the given value is a array, false otherwise.\r\n */\r\n isA: function (arr) {\r\n var def = Array.isArray;\r\n return def ? def(arr) : this.type(arr) == TYPES.a;\r\n },\r\n\r\n /**\r\n * Determine the internal JavaScript [[Class]] of the given object.\r\n * @param obj The object of which the type shall be determined.\r\n * @returns {string} The type of the given object.\r\n */\r\n type: function (obj) {\r\n if (obj === undefined)\r\n return obj + '';\r\n if (obj === null)\r\n return obj + '';\r\n return Object[LEXICON.p].toString.call(obj).replace(/^\\[object (.+)\\]$/, '$1').toLowerCase();\r\n },\r\n\r\n\r\n bind: bind\r\n\r\n /**\r\n * Gets the vendor-prefixed CSS property by the given name.\r\n * For example the given name is \"transform\" and you're using a old Firefox browser then the returned value would be \"-moz-transform\".\r\n * If the browser doesn't need a vendor-prefix, then the returned string is the given name.\r\n * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null.\r\n * @param propName The unprefixed CSS property name.\r\n * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property.\r\n\r\n cssProp: function(propName) {\r\n return VENDORS._cssProperty(propName);\r\n }\r\n */\r\n }\r\n })();\r\n\r\n\r\n var MATH = Math;\r\n var JQUERY = window.jQuery;\r\n var EASING = (function () {\r\n var _easingsMath = {\r\n p: MATH.PI,\r\n c: MATH.cos,\r\n s: MATH.sin,\r\n w: MATH.pow,\r\n t: MATH.sqrt,\r\n n: MATH.asin,\r\n a: MATH.abs,\r\n o: 1.70158\r\n };\r\n\r\n /*\r\n x : current percent (0 - 1),\r\n t : current time (duration * percent),\r\n b : start value (from),\r\n c : end value (to),\r\n d : duration\r\n\r\n easingName : function(x, t, b, c, d) { return easedValue; }\r\n */\r\n\r\n return {\r\n swing: function (x, t, b, c, d) {\r\n return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2;\r\n },\r\n linear: function (x, t, b, c, d) {\r\n return x;\r\n },\r\n easeInQuad: function (x, t, b, c, d) {\r\n return c * (t /= d) * t + b;\r\n },\r\n easeOutQuad: function (x, t, b, c, d) {\r\n return -c * (t /= d) * (t - 2) + b;\r\n },\r\n easeInOutQuad: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b;\r\n },\r\n easeInCubic: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t + b;\r\n },\r\n easeOutCubic: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t + 1) + b;\r\n },\r\n easeInOutCubic: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b;\r\n },\r\n easeInQuart: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t + b;\r\n },\r\n easeOutQuart: function (x, t, b, c, d) {\r\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r\n },\r\n easeInOutQuart: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b;\r\n },\r\n easeInQuint: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t * t + b;\r\n },\r\n easeOutQuint: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\r\n },\r\n easeInOutQuint: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\r\n },\r\n easeInSine: function (x, t, b, c, d) {\r\n return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b;\r\n },\r\n easeOutSine: function (x, t, b, c, d) {\r\n return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b;\r\n },\r\n easeInOutSine: function (x, t, b, c, d) {\r\n return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b;\r\n },\r\n easeInExpo: function (x, t, b, c, d) {\r\n return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b;\r\n },\r\n easeOutExpo: function (x, t, b, c, d) {\r\n return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b;\r\n },\r\n easeInOutExpo: function (x, t, b, c, d) {\r\n if (t == 0) return b;\r\n if (t == d) return b + c;\r\n if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b;\r\n return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b;\r\n },\r\n easeInCirc: function (x, t, b, c, d) {\r\n return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b;\r\n },\r\n easeOutCirc: function (x, t, b, c, d) {\r\n return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b;\r\n },\r\n easeInOutCirc: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b;\r\n },\r\n easeInElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n },\r\n easeOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d) == 1) return b + c;\r\n if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b;\r\n },\r\n easeInOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d / 2) == 2) return b + c;\r\n if (!p) p = d * (.3 * 1.5);\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b;\r\n },\r\n easeInBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\r\n },\r\n easeOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\r\n },\r\n easeInOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\r\n },\r\n easeInBounce: function (x, t, b, c, d) {\r\n return c - this.easeOutBounce(x, d - t, 0, c, d) + b;\r\n },\r\n easeOutBounce: function (x, t, b, c, d) {\r\n var o = 7.5625;\r\n if ((t /= d) < (1 / 2.75)) {\r\n return c * (o * t * t) + b;\r\n } else if (t < (2 / 2.75)) {\r\n return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b;\r\n } else if (t < (2.5 / 2.75)) {\r\n return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b;\r\n } else {\r\n return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b;\r\n }\r\n },\r\n easeInOutBounce: function (x, t, b, c, d) {\r\n return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;\r\n }\r\n };\r\n /*\r\n *\r\n * TERMS OF USE - EASING EQUATIONS\r\n * \r\n * Open source under the BSD License. \r\n * \r\n * Copyright © 2001 Robert Penner\r\n * All rights reserved.\r\n * \r\n * Redistribution and use in source and binary forms, with or without modification, \r\n * are permitted provided that the following conditions are met:\r\n * \r\n * Redistributions of source code must retain the above copyright notice, this list of \r\n * conditions and the following disclaimer.\r\n * Redistributions in binary form must reproduce the above copyright notice, this list \r\n * of conditions and the following disclaimer in the documentation and/or other materials \r\n * provided with the distribution.\r\n * \r\n * Neither the name of the author nor the names of contributors may be used to endorse \r\n * or promote products derived from this software without specific prior written permission.\r\n * \r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY \r\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r\n * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \r\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \r\n * OF THE POSSIBILITY OF SUCH DAMAGE. \r\n *\r\n */\r\n })();\r\n var FRAMEWORK = (function () {\r\n var _rnothtmlwhite = (/[^\\x20\\t\\r\\n\\f]+/g);\r\n var _strSpace = ' ';\r\n var _strEmpty = '';\r\n var _strScrollLeft = 'scrollLeft';\r\n var _strScrollTop = 'scrollTop';\r\n var _animations = [];\r\n var _type = COMPATIBILITY.type;\r\n var _cssNumber = {\r\n animationIterationCount: true,\r\n columnCount: true,\r\n fillOpacity: true,\r\n flexGrow: true,\r\n flexShrink: true,\r\n fontWeight: true,\r\n lineHeight: true,\r\n opacity: true,\r\n order: true,\r\n orphans: true,\r\n widows: true,\r\n zIndex: true,\r\n zoom: true\r\n };\r\n\r\n function extend() {\r\n var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {},\r\n i = 1,\r\n length = arguments[LEXICON.l],\r\n deep = false;\r\n\r\n // Handle a deep copy situation\r\n if (_type(target) == TYPES.b) {\r\n deep = target;\r\n target = arguments[1] || {};\r\n // skip the boolean and the target\r\n i = 2;\r\n }\r\n\r\n // Handle case when target is a string or something (possible in deep copy)\r\n if (_type(target) != TYPES.o && !_type(target) == TYPES.f) {\r\n target = {};\r\n }\r\n\r\n // extend jQuery itself if only one argument is passed\r\n if (length === i) {\r\n target = FakejQuery;\r\n --i;\r\n }\r\n\r\n for (; i < length; i++) {\r\n // Only deal with non-null/undefined values\r\n if ((options = arguments[i]) != null) {\r\n // Extend the base object\r\n for (name in options) {\r\n src = target[name];\r\n copy = options[name];\r\n\r\n // Prevent never-ending loop\r\n if (target === copy) {\r\n continue;\r\n }\r\n\r\n // Recurse if we're merging plain objects or arrays\r\n if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) {\r\n if (copyIsArray) {\r\n copyIsArray = false;\r\n clone = src && COMPATIBILITY.isA(src) ? src : [];\r\n\r\n } else {\r\n clone = src && isPlainObject(src) ? src : {};\r\n }\r\n\r\n // Never move original objects, clone them\r\n target[name] = extend(deep, clone, copy);\r\n\r\n // Don't bring in undefined values\r\n } else if (copy !== undefined) {\r\n target[name] = copy;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Return the modified object\r\n return target;\r\n };\r\n\r\n function inArray(item, arr, fromIndex) {\r\n for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++)\r\n if (arr[i] === item)\r\n return i;\r\n return -1;\r\n }\r\n\r\n function isFunction(obj) {\r\n return _type(obj) == TYPES.f;\r\n };\r\n\r\n function isEmptyObject(obj) {\r\n for (var name in obj)\r\n return false;\r\n return true;\r\n };\r\n\r\n function isPlainObject(obj) {\r\n if (!obj || _type(obj) != TYPES.o)\r\n return false;\r\n\r\n var key;\r\n var proto = LEXICON.p;\r\n var hasOwnProperty = Object[proto].hasOwnProperty;\r\n var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor');\r\n var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf');\r\n\r\n if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\r\n return false;\r\n }\r\n\r\n\r\n for (key in obj) { /**/ }\r\n\r\n return _type(key) == TYPES.u || hasOwnProperty.call(obj, key);\r\n };\r\n\r\n function each(obj, callback) {\r\n var i = 0;\r\n\r\n if (isArrayLike(obj)) {\r\n for (; i < obj[LEXICON.l]; i++) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n else {\r\n for (i in obj) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n\r\n return obj;\r\n };\r\n\r\n function isArrayLike(obj) {\r\n var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l];\r\n var t = _type(obj);\r\n return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj);\r\n }\r\n\r\n function stripAndCollapse(value) {\r\n var tokens = value.match(_rnothtmlwhite) || [];\r\n return tokens.join(_strSpace);\r\n }\r\n\r\n function matches(elem, selector) {\r\n var nodeList = (elem.parentNode || document).querySelectorAll(selector) || [];\r\n var i = nodeList[LEXICON.l];\r\n\r\n while (i--)\r\n if (nodeList[i] == elem)\r\n return true;\r\n\r\n return false;\r\n }\r\n\r\n function insertAdjacentElement(el, strategy, child) {\r\n if (COMPATIBILITY.isA(child)) {\r\n for (var i = 0; i < child[LEXICON.l]; i++)\r\n insertAdjacentElement(el, strategy, child[i]);\r\n }\r\n else if (_type(child) == TYPES.s)\r\n el.insertAdjacentHTML(strategy, child);\r\n else\r\n el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]);\r\n }\r\n\r\n function setCSSVal(el, prop, val) {\r\n try {\r\n if (el[LEXICON.s][prop] !== undefined)\r\n el[LEXICON.s][prop] = parseCSSVal(prop, val);\r\n } catch (e) { }\r\n }\r\n\r\n function parseCSSVal(prop, val) {\r\n if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n)\r\n val += 'px';\r\n return val;\r\n }\r\n\r\n function startNextAnimationInQ(animObj, removeFromQ) {\r\n var index;\r\n var nextAnim;\r\n if (removeFromQ !== false)\r\n animObj.q.splice(0, 1);\r\n if (animObj.q[LEXICON.l] > 0) {\r\n nextAnim = animObj.q[0];\r\n animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true);\r\n }\r\n else {\r\n index = inArray(animObj, _animations);\r\n if (index > -1)\r\n _animations.splice(index, 1);\r\n }\r\n }\r\n\r\n function setAnimationValue(el, prop, value) {\r\n if (prop === _strScrollLeft || prop === _strScrollTop)\r\n el[prop] = value;\r\n else\r\n setCSSVal(el, prop, value);\r\n }\r\n\r\n function animate(el, props, options, easing, complete, guaranteedNext) {\r\n var hasOptions = isPlainObject(options);\r\n var from = {};\r\n var to = {};\r\n var i = 0;\r\n var key;\r\n var animObj;\r\n var start;\r\n var progress;\r\n var step;\r\n var specialEasing;\r\n var duration;\r\n if (hasOptions) {\r\n easing = options.easing;\r\n start = options.start;\r\n progress = options.progress;\r\n step = options.step;\r\n specialEasing = options.specialEasing;\r\n complete = options.complete;\r\n duration = options.duration;\r\n }\r\n else\r\n duration = options;\r\n specialEasing = specialEasing || {};\r\n duration = duration || 400;\r\n easing = easing || 'swing';\r\n guaranteedNext = guaranteedNext || false;\r\n\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n if (_animations[i].el === el) {\r\n animObj = _animations[i];\r\n break;\r\n }\r\n }\r\n\r\n if (!animObj) {\r\n animObj = {\r\n el: el,\r\n q: []\r\n };\r\n _animations.push(animObj);\r\n }\r\n\r\n for (key in props) {\r\n if (key === _strScrollLeft || key === _strScrollTop)\r\n from[key] = el[key];\r\n else\r\n from[key] = FakejQuery(el).css(key);\r\n }\r\n\r\n for (key in from) {\r\n if (from[key] !== props[key] && props[key] !== undefined)\r\n to[key] = props[key];\r\n }\r\n\r\n if (!isEmptyObject(to)) {\r\n var timeNow;\r\n var end;\r\n var percent;\r\n var fromVal;\r\n var toVal;\r\n var easedVal;\r\n var timeStart;\r\n var frame;\r\n var elapsed;\r\n var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q);\r\n var qObj = {\r\n props: to,\r\n duration: hasOptions ? options : duration,\r\n easing: easing,\r\n complete: complete\r\n };\r\n if (qPos === -1) {\r\n qPos = animObj.q[LEXICON.l];\r\n animObj.q.push(qObj);\r\n }\r\n\r\n if (qPos === 0) {\r\n if (duration > 0) {\r\n timeStart = COMPATIBILITY.now();\r\n frame = function () {\r\n timeNow = COMPATIBILITY.now();\r\n elapsed = (timeNow - timeStart);\r\n end = qObj.stop || elapsed >= duration;\r\n percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0);\r\n\r\n for (key in to) {\r\n fromVal = parseFloat(from[key]);\r\n toVal = parseFloat(to[key]);\r\n easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal;\r\n setAnimationValue(el, key, easedVal);\r\n if (isFunction(step)) {\r\n step(easedVal, {\r\n elem: el,\r\n prop: key,\r\n start: fromVal,\r\n now: easedVal,\r\n end: toVal,\r\n pos: percent,\r\n options: {\r\n easing: easing,\r\n speacialEasing: specialEasing,\r\n duration: duration,\r\n complete: complete,\r\n step: step\r\n },\r\n startTime: timeStart\r\n });\r\n }\r\n }\r\n\r\n if (isFunction(progress))\r\n progress({}, percent, MATH.max(0, duration - elapsed));\r\n\r\n if (end) {\r\n startNextAnimationInQ(animObj);\r\n if (isFunction(complete))\r\n complete();\r\n }\r\n else\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n };\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n }\r\n else {\r\n for (key in to)\r\n setAnimationValue(el, key, to[key]);\r\n startNextAnimationInQ(animObj);\r\n }\r\n }\r\n }\r\n else if (guaranteedNext)\r\n startNextAnimationInQ(animObj);\r\n }\r\n\r\n function stop(el, clearQ, jumpToEnd) {\r\n var animObj;\r\n var qObj;\r\n var key;\r\n var i = 0;\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n animObj = _animations[i];\r\n if (animObj.el === el) {\r\n if (animObj.q[LEXICON.l] > 0) {\r\n qObj = animObj.q[0];\r\n qObj.stop = true;\r\n COMPATIBILITY.cAF()(qObj.frame);\r\n animObj.q.splice(0, 1);\r\n\r\n if (jumpToEnd)\r\n for (key in qObj.props)\r\n setAnimationValue(el, key, qObj.props[key]);\r\n\r\n if (clearQ)\r\n animObj.q = [];\r\n else\r\n startNextAnimationInQ(animObj, false);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function elementIsVisible(el) {\r\n return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]);\r\n }\r\n\r\n function FakejQuery(selector) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var base = new FakejQuery();\r\n var elements = selector;\r\n var i = 0;\r\n var elms;\r\n var el;\r\n\r\n if (_type(selector) == TYPES.s) {\r\n elements = [];\r\n if (selector.charAt(0) === '<') {\r\n el = document.createElement('div');\r\n el.innerHTML = selector;\r\n elms = el.children;\r\n }\r\n else {\r\n elms = document.querySelectorAll(selector);\r\n }\r\n\r\n for (; i < elms[LEXICON.l]; i++)\r\n elements.push(elms[i]);\r\n }\r\n\r\n if (elements) {\r\n if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self))\r\n elements = [elements];\r\n\r\n for (i = 0; i < elements[LEXICON.l]; i++)\r\n base[i] = elements[i];\r\n\r\n base[LEXICON.l] = elements[LEXICON.l];\r\n }\r\n\r\n return base;\r\n };\r\n\r\n FakejQuery[LEXICON.p] = {\r\n\r\n //EVENTS:\r\n\r\n on: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.addEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.addEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.attachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n off: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.removeEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.removeEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.detachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n one: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n FakejQuery.each(eventName, function (i, oneEventName) {\r\n var oneHandler = function (e) {\r\n handler.call(this, e);\r\n el.off(oneEventName, oneHandler);\r\n };\r\n el.on(oneEventName, oneHandler);\r\n });\r\n });\r\n },\r\n\r\n trigger: function (eventName) {\r\n var el;\r\n var event;\r\n return this.each(function () {\r\n el = this;\r\n if (document.createEvent) {\r\n event = document.createEvent('HTMLEvents');\r\n event.initEvent(eventName, true, false);\r\n el.dispatchEvent(event);\r\n }\r\n else {\r\n el.fireEvent('on' + eventName);\r\n }\r\n });\r\n },\r\n\r\n //DOM NODE INSERTING / REMOVING:\r\n\r\n append: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforeend', child); });\r\n },\r\n\r\n prepend: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); });\r\n },\r\n\r\n before: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); });\r\n },\r\n\r\n after: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterend', child); });\r\n },\r\n\r\n remove: function () {\r\n return this.each(function () {\r\n var el = this;\r\n var parentNode = el.parentNode;\r\n if (parentNode != null)\r\n parentNode.removeChild(el);\r\n });\r\n },\r\n\r\n unwrap: function () {\r\n var parents = [];\r\n var i;\r\n var el;\r\n var parent;\r\n\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (inArray(parent, parents) === - 1)\r\n parents.push(parent);\r\n });\r\n\r\n for (i = 0; i < parents[LEXICON.l]; i++) {\r\n el = parents[i];\r\n parent = el.parentNode;\r\n while (el.firstChild)\r\n parent.insertBefore(el.firstChild, el);\r\n parent.removeChild(el);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n wrapAll: function (wrapperHTML) {\r\n var i;\r\n var nodes = this;\r\n var wrapper = FakejQuery(wrapperHTML)[0];\r\n var deepest = wrapper;\r\n var parent = nodes[0].parentNode;\r\n var previousSibling = nodes[0].previousSibling;\r\n while (deepest.childNodes[LEXICON.l] > 0)\r\n deepest = deepest.childNodes[0];\r\n\r\n for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++)\r\n deepest.appendChild(nodes[i]);\r\n\r\n var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild;\r\n parent.insertBefore(wrapper, nextSibling);\r\n\r\n return this;\r\n },\r\n\r\n wrapInner: function (wrapperHTML) {\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n var contents = el.contents();\r\n\r\n if (contents[LEXICON.l])\r\n contents.wrapAll(wrapperHTML);\r\n else\r\n el.append(wrapperHTML);\r\n });\r\n },\r\n\r\n wrap: function (wrapperHTML) {\r\n return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); });\r\n },\r\n\r\n\r\n //DOM NODE MANIPULATION / INFORMATION:\r\n\r\n css: function (styles, val) {\r\n var el;\r\n var key;\r\n var cptStyle;\r\n var getCptStyle = window.getComputedStyle;\r\n if (_type(styles) == TYPES.s) {\r\n if (val === undefined) {\r\n el = this[0];\r\n cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles];\r\n\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!)\r\n return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle;\r\n }\r\n else {\r\n return this.each(function () {\r\n setCSSVal(this, styles, val);\r\n });\r\n }\r\n }\r\n else {\r\n return this.each(function () {\r\n for (key in styles)\r\n setCSSVal(this, key, styles[key]);\r\n });\r\n }\r\n },\r\n\r\n hasClass: function (className) {\r\n var elem, i = 0;\r\n var classNamePrepared = _strSpace + className + _strSpace;\r\n var classList;\r\n\r\n while ((elem = this[i++])) {\r\n classList = elem.classList;\r\n if (classList && classList.contains(className))\r\n return true;\r\n else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1)\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n addClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.add(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n if (cur.indexOf(_strSpace + clazz + _strSpace) < 0)\r\n cur += clazz + _strSpace;\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n removeClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.remove(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n while (cur.indexOf(_strSpace + clazz + _strSpace) > -1)\r\n cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace);\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n hide: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'none'; });\r\n },\r\n\r\n show: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'block'; });\r\n },\r\n\r\n attr: function (attrName, value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el.getAttribute(attrName);\r\n el.setAttribute(attrName, value);\r\n }\r\n return this;\r\n },\r\n\r\n removeAttr: function (attrName) {\r\n return this.each(function () { this.removeAttribute(attrName); });\r\n },\r\n\r\n offset: function () {\r\n var el = this[0];\r\n var rect = el[LEXICON.bCR]();\r\n var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft];\r\n var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop];\r\n return {\r\n top: rect.top + scrollTop,\r\n left: rect.left + scrollLeft\r\n };\r\n },\r\n\r\n position: function () {\r\n var el = this[0];\r\n return {\r\n top: el.offsetTop,\r\n left: el.offsetLeft\r\n };\r\n },\r\n\r\n scrollLeft: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollLeft];\r\n el[_strScrollLeft] = value;\r\n }\r\n return this;\r\n },\r\n\r\n scrollTop: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollTop];\r\n el[_strScrollTop] = value;\r\n }\r\n return this;\r\n },\r\n\r\n val: function (value) {\r\n var el = this[0];\r\n if (!value)\r\n return el.value;\r\n el.value = value;\r\n return this;\r\n },\r\n\r\n\r\n //DOM TRAVERSAL / FILTERING:\r\n\r\n first: function () {\r\n return this.eq(0);\r\n },\r\n\r\n last: function () {\r\n return this.eq(-1);\r\n },\r\n\r\n eq: function (index) {\r\n return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]);\r\n },\r\n\r\n find: function (selector) {\r\n var children = [];\r\n var i;\r\n this.each(function () {\r\n var el = this;\r\n var ch = el.querySelectorAll(selector);\r\n for (i = 0; i < ch[LEXICON.l]; i++)\r\n children.push(ch[i]);\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n children: function (selector) {\r\n var children = [];\r\n var el;\r\n var ch;\r\n var i;\r\n\r\n this.each(function () {\r\n ch = this.children;\r\n for (i = 0; i < ch[LEXICON.l]; i++) {\r\n el = ch[i];\r\n if (selector) {\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n children.push(el);\r\n }\r\n else\r\n children.push(el);\r\n }\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n parent: function (selector) {\r\n var parents = [];\r\n var parent;\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (selector ? FakejQuery(parent).is(selector) : true)\r\n parents.push(parent);\r\n });\r\n return FakejQuery(parents);\r\n },\r\n\r\n is: function (selector) {\r\n\r\n var el;\r\n var i;\r\n for (i = 0; i < this[LEXICON.l]; i++) {\r\n el = this[i];\r\n if (selector === ':visible')\r\n return elementIsVisible(el);\r\n if (selector === ':hidden')\r\n return !elementIsVisible(el);\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n contents: function () {\r\n var contents = [];\r\n var childs;\r\n var i;\r\n\r\n this.each(function () {\r\n childs = this.childNodes;\r\n for (i = 0; i < childs[LEXICON.l]; i++)\r\n contents.push(childs[i]);\r\n });\r\n\r\n return FakejQuery(contents);\r\n },\r\n\r\n each: function (callback) {\r\n return each(this, callback);\r\n },\r\n\r\n\r\n //ANIMATION:\r\n\r\n animate: function (props, duration, easing, complete) {\r\n return this.each(function () { animate(this, props, duration, easing, complete); });\r\n },\r\n\r\n stop: function (clearQ, jump) {\r\n return this.each(function () { stop(this, clearQ, jump); });\r\n }\r\n };\r\n\r\n extend(FakejQuery, {\r\n extend: extend,\r\n inArray: inArray,\r\n isEmptyObject: isEmptyObject,\r\n isPlainObject: isPlainObject,\r\n each: each\r\n });\r\n\r\n return FakejQuery;\r\n })();\r\n var INSTANCES = (function () {\r\n var _targets = [];\r\n var _instancePropertyString = '__overlayScrollbars__';\r\n\r\n /**\r\n * Register, unregister or get a certain (or all) instances.\r\n * Register: Pass the target and the instance.\r\n * Unregister: Pass the target and null.\r\n * Get Instance: Pass the target from which the instance shall be got.\r\n * Get Targets: Pass no arguments.\r\n * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got\r\n * @param instance The instance.\r\n * @returns {*|void} Returns the instance from the given target.\r\n */\r\n return function (target, instance) {\r\n var argLen = arguments[LEXICON.l];\r\n if (argLen < 1) {\r\n //return all targets\r\n return _targets;\r\n }\r\n else {\r\n if (instance) {\r\n //register instance\r\n target[_instancePropertyString] = instance;\r\n _targets.push(target);\r\n }\r\n else {\r\n var index = COMPATIBILITY.inA(target, _targets);\r\n if (index > -1) {\r\n if (argLen > 1) {\r\n //unregister instance\r\n delete target[_instancePropertyString];\r\n _targets.splice(index, 1);\r\n }\r\n else {\r\n //get instance from target\r\n return _targets[index][_instancePropertyString];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n var PLUGIN = (function () {\r\n var _plugin;\r\n var _pluginsGlobals;\r\n var _pluginsAutoUpdateLoop;\r\n var _pluginsExtensions = [];\r\n var _pluginsOptions = (function () {\r\n var type = COMPATIBILITY.type;\r\n var possibleTemplateTypes = [\r\n TYPES.b, //boolean\r\n TYPES.n, //number\r\n TYPES.s, //string\r\n TYPES.a, //array\r\n TYPES.o, //object\r\n TYPES.f, //function\r\n TYPES.z //null\r\n ];\r\n var restrictedStringsSplit = ' ';\r\n var restrictedStringsPossibilitiesSplit = ':';\r\n var classNameAllowedValues = [TYPES.z, TYPES.s];\r\n var numberAllowedValues = TYPES.n;\r\n var booleanNullAllowedValues = [TYPES.z, TYPES.b];\r\n var booleanTrueTemplate = [true, TYPES.b];\r\n var booleanFalseTemplate = [false, TYPES.b];\r\n var callbackTemplate = [null, [TYPES.z, TYPES.f]];\r\n var updateOnLoadTemplate = [['img'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical';\r\n var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden';\r\n var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto';\r\n var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move';\r\n var optionsDefaultsAndTemplate = {\r\n className: ['os-theme-dark', classNameAllowedValues], //null || string\r\n resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v\r\n sizeAutoCapable: booleanTrueTemplate, //true || false\r\n clipAlways: booleanTrueTemplate, //true || false\r\n normalizeRTL: booleanTrueTemplate, //true || false\r\n paddingAbsolute: booleanFalseTemplate, //true || false\r\n autoUpdate: [null, booleanNullAllowedValues], //true || false || null\r\n autoUpdateInterval: [33, numberAllowedValues], //number\r\n updateOnLoad: updateOnLoadTemplate, //string || array || null\r\n nativeScrollbarsOverlaid: {\r\n showNativeScrollbars: booleanFalseTemplate, //true || false\r\n initialize: booleanTrueTemplate //true || false\r\n },\r\n overflowBehavior: {\r\n x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n },\r\n scrollbars: {\r\n visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a\r\n autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m\r\n autoHideDelay: [800, numberAllowedValues], //number\r\n dragScrolling: booleanTrueTemplate, //true || false\r\n clickScrolling: booleanFalseTemplate, //true || false\r\n touchSupport: booleanTrueTemplate, //true || false\r\n snapHandle: booleanFalseTemplate //true || false\r\n },\r\n textarea: {\r\n dynWidth: booleanFalseTemplate, //true || false\r\n dynHeight: booleanFalseTemplate, //true || false\r\n inheritedAttrs: inheritedAttrsTemplate //string || array || null\r\n },\r\n callbacks: {\r\n onInitialized: callbackTemplate, //null || function\r\n onInitializationWithdrawn: callbackTemplate, //null || function\r\n onDestroyed: callbackTemplate, //null || function\r\n onScrollStart: callbackTemplate, //null || function\r\n onScroll: callbackTemplate, //null || function\r\n onScrollStop: callbackTemplate, //null || function\r\n onOverflowChanged: callbackTemplate, //null || function\r\n onOverflowAmountChanged: callbackTemplate, //null || function\r\n onDirectionChanged: callbackTemplate, //null || function\r\n onContentSizeChanged: callbackTemplate, //null || function\r\n onHostSizeChanged: callbackTemplate, //null || function\r\n onUpdated: callbackTemplate //null || function\r\n }\r\n };\r\n var convert = function (template) {\r\n var recursive = function (obj) {\r\n var key;\r\n var val;\r\n var valType;\r\n for (key in obj) {\r\n if (!obj[LEXICON.hOP](key))\r\n continue;\r\n val = obj[key];\r\n valType = type(val);\r\n if (valType == TYPES.a)\r\n obj[key] = val[template ? 1 : 0];\r\n else if (valType == TYPES.o)\r\n obj[key] = recursive(val);\r\n }\r\n return obj;\r\n };\r\n return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate));\r\n };\r\n\r\n return {\r\n _defaults: convert(),\r\n\r\n _template: convert(true),\r\n\r\n /**\r\n * Validates the passed object by the passed template.\r\n * @param obj The object which shall be validated.\r\n * @param template The template which defines the allowed values and types.\r\n * @param writeErrors True if errors shall be logged to the console.\r\n * @param diffObj If a object is passed then only valid differences to this object will be returned.\r\n * @returns {{}} A object which contains two objects called \"default\" and \"prepared\" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj.\r\n */\r\n _validate: function (obj, template, writeErrors, diffObj) {\r\n var validatedOptions = {};\r\n var validatedOptionsPrepared = {};\r\n var objectCopy = FRAMEWORK.extend(true, {}, obj);\r\n var inArray = FRAMEWORK.inArray;\r\n var isEmptyObj = FRAMEWORK.isEmptyObject;\r\n var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) {\r\n for (var prop in template) {\r\n if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) {\r\n var isValid = false;\r\n var isDiff = false;\r\n var templateValue = template[prop];\r\n var templateValueType = type(templateValue);\r\n var templateIsComplex = templateValueType == TYPES.o;\r\n var templateTypes = !COMPATIBILITY.isA(templateValue) ? [templateValue] : templateValue;\r\n var dataDiffValue = diffData[prop];\r\n var dataValue = data[prop];\r\n var dataValueType = type(dataValue);\r\n var propPrefix = prevPropName ? prevPropName + '.' : '';\r\n var error = \"The option \\\"\" + propPrefix + prop + \"\\\" wasn't set, because\";\r\n var errorPossibleTypes = [];\r\n var errorRestrictedStrings = [];\r\n var restrictedStringValuesSplit;\r\n var restrictedStringValuesPossibilitiesSplit;\r\n var isRestrictedValue;\r\n var mainPossibility;\r\n var currType;\r\n var i;\r\n var v;\r\n var j;\r\n\r\n dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue;\r\n\r\n //if the template has a object as value, it means that the options are complex (verschachtelt)\r\n if (templateIsComplex && dataValueType == TYPES.o) {\r\n validatedOptions[prop] = {};\r\n validatedOptionsPrepared[prop] = {};\r\n checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop);\r\n FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) {\r\n if (isEmptyObj(value[prop])) {\r\n delete value[prop];\r\n }\r\n });\r\n }\r\n else if (!templateIsComplex) {\r\n for (i = 0; i < templateTypes[LEXICON.l]; i++) {\r\n currType = templateTypes[i];\r\n templateValueType = type(currType);\r\n //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix\r\n isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1;\r\n if (isRestrictedValue) {\r\n errorPossibleTypes.push(TYPES.s);\r\n\r\n //split it into a array which contains all possible values for example: [\"y:yes\", \"n:no\", \"m:maybe\"]\r\n restrictedStringValuesSplit = currType.split(restrictedStringsSplit);\r\n errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit);\r\n for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) {\r\n //split the possible values into their possibiliteis for example: [\"y\", \"yes\"] -> the first is always the mainPossibility\r\n restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit);\r\n mainPossibility = restrictedStringValuesPossibilitiesSplit[0];\r\n for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) {\r\n //if any possibility matches with the dataValue, its valid\r\n if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n if (isValid)\r\n break;\r\n }\r\n }\r\n else {\r\n errorPossibleTypes.push(currType);\r\n\r\n if (dataValueType === currType) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (isValid) {\r\n isDiff = dataValue !== dataDiffValue;\r\n\r\n if (isDiff)\r\n validatedOptions[prop] = dataValue;\r\n\r\n if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff)\r\n validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue;\r\n }\r\n else if (writeErrors) {\r\n console.warn(error + \" it doesn't accept the type [ \" + dataValueType.toUpperCase() + \" ] with the value of \\\"\" + dataValue + \"\\\".\\r\\n\" +\r\n \"Accepted types are: [ \" + errorPossibleTypes.join(', ').toUpperCase() + \" ].\" +\r\n (errorRestrictedStrings[length] > 0 ? \"\\r\\nValid strings are: [ \" + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + \" ].\" : ''));\r\n }\r\n delete data[prop];\r\n }\r\n }\r\n }\r\n };\r\n checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared);\r\n\r\n //add values which aren't specified in the template to the finished validated object to prevent them from being discarded\r\n /*\r\n if(keepForeignProps) {\r\n FRAMEWORK.extend(true, validatedOptions, objectCopy);\r\n FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy);\r\n }\r\n */\r\n\r\n if (!isEmptyObj(objectCopy) && writeErrors)\r\n console.warn('The following options are discarded due to invalidity:\\r\\n' + window.JSON.stringify(objectCopy, null, 2));\r\n\r\n return {\r\n _default: validatedOptions,\r\n _prepared: validatedOptionsPrepared\r\n };\r\n }\r\n }\r\n }());\r\n\r\n /**\r\n * Initializes the object which contains global information about the plugin and each instance of it.\r\n */\r\n function initOverlayScrollbarsStatics() {\r\n if (!_pluginsGlobals)\r\n _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults);\r\n if (!_pluginsAutoUpdateLoop)\r\n _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals);\r\n }\r\n\r\n /**\r\n * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @param defaultOptions\r\n * @constructor\r\n */\r\n function OverlayScrollbarsGlobals(defaultOptions) {\r\n var _base = this;\r\n var strOverflow = 'overflow';\r\n var strHidden = 'hidden';\r\n var strScroll = 'scroll';\r\n var bodyElement = FRAMEWORK('body');\r\n var scrollbarDummyElement = FRAMEWORK('<div id=\"os-dummy-scrollbar-size\"><div></div></div>');\r\n var scrollbarDummyElement0 = scrollbarDummyElement[0];\r\n var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0));\r\n\r\n bodyElement.append(scrollbarDummyElement);\r\n scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring)\r\n\r\n var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0);\r\n var nativeScrollbarIsOverlaid = {\r\n x: nativeScrollbarSize.x === 0,\r\n y: nativeScrollbarSize.y === 0\r\n };\r\n var msie = (function () {\r\n var ua = window.navigator.userAgent;\r\n var strIndexOf = 'indexOf';\r\n var strSubString = 'substring';\r\n var msie = ua[strIndexOf]('MSIE ');\r\n var trident = ua[strIndexOf]('Trident/');\r\n var edge = ua[strIndexOf]('Edge/');\r\n var rv = ua[strIndexOf]('rv:');\r\n var result;\r\n var parseIntFunc = parseInt;\r\n\r\n // IE 10 or older => return version number\r\n if (msie > 0)\r\n result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10);\r\n\r\n // IE 11 => return version number\r\n else if (trident > 0)\r\n result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10);\r\n\r\n // Edge (IE 12+) => return version number\r\n else if (edge > 0)\r\n result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10);\r\n\r\n // other browser\r\n return result;\r\n })();\r\n\r\n FRAMEWORK.extend(_base, {\r\n defaultOptions: defaultOptions,\r\n msie: msie,\r\n autoUpdateLoop: false,\r\n autoUpdateRecommended: !COMPATIBILITY.mO(),\r\n nativeScrollbarSize: nativeScrollbarSize,\r\n nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid,\r\n nativeScrollbarStyling: (function () {\r\n var result = false;\r\n scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible');\r\n try {\r\n result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none';\r\n } catch (ex) { }\r\n\r\n //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style.\r\n //and set overflow to scroll\r\n //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show();\r\n //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0;\r\n\r\n return result;\r\n })(),\r\n overlayScrollbarDummySize: { x: 30, y: 30 },\r\n cssCalc: VENDORS._cssPropertyValue('width', 'calc', '(1px)') || null,\r\n restrictedMeasuring: (function () {\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305\r\n //since 1.11.0 always false -> fixed via CSS (hopefully)\r\n scrollbarDummyElement.css(strOverflow, strHidden);\r\n var scrollSize = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n scrollbarDummyElement.css(strOverflow, 'visible');\r\n var scrollSize2 = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0;\r\n })(),\r\n rtlScrollBehavior: (function () {\r\n scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0);\r\n var dummyContainerOffset = scrollbarDummyElement.offset();\r\n var dummyContainerChildOffset = dummyContainerChild.offset();\r\n //https://github.com/KingSora/OverlayScrollbars/issues/187\r\n scrollbarDummyElement.scrollLeft(-999);\r\n var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset();\r\n return {\r\n //origin direction = determines if the zero scroll position is on the left or right side\r\n //'i' means 'invert' (i === true means that the axis must be inverted to be correct)\r\n //true = on the left side\r\n //false = on the right side\r\n i: dummyContainerOffset.left === dummyContainerChildOffset.left,\r\n //negative = determines if the maximum scroll is positive or negative\r\n //'n' means 'negate' (n === true means that the axis must be negated to be correct)\r\n //true = negative\r\n //false = positive\r\n n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left\r\n };\r\n })(),\r\n supportTransform: !!VENDORS._cssProperty('transform'),\r\n supportTransition: !!VENDORS._cssProperty('transition'),\r\n supportPassiveEvents: (function () {\r\n var supportsPassive = false;\r\n try {\r\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\r\n get: function () {\r\n supportsPassive = true;\r\n }\r\n }));\r\n } catch (e) { }\r\n return supportsPassive;\r\n })(),\r\n supportResizeObserver: !!COMPATIBILITY.rO(),\r\n supportMutationObserver: !!COMPATIBILITY.mO()\r\n });\r\n\r\n scrollbarDummyElement.removeAttr(LEXICON.s).remove();\r\n\r\n //Catch zoom event:\r\n (function () {\r\n if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y)\r\n return;\r\n\r\n var abs = MATH.abs;\r\n var windowWidth = COMPATIBILITY.wW();\r\n var windowHeight = COMPATIBILITY.wH();\r\n var windowDpr = getWindowDPR();\r\n var onResize = function () {\r\n if (INSTANCES().length > 0) {\r\n var newW = COMPATIBILITY.wW();\r\n var newH = COMPATIBILITY.wH();\r\n var deltaW = newW - windowWidth;\r\n var deltaH = newH - windowHeight;\r\n\r\n if (deltaW === 0 && deltaH === 0)\r\n return;\r\n\r\n var deltaWRatio = MATH.round(newW / (windowWidth / 100.0));\r\n var deltaHRatio = MATH.round(newH / (windowHeight / 100.0));\r\n var absDeltaW = abs(deltaW);\r\n var absDeltaH = abs(deltaH);\r\n var absDeltaWRatio = abs(deltaWRatio);\r\n var absDeltaHRatio = abs(deltaHRatio);\r\n var newDPR = getWindowDPR();\r\n\r\n var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2;\r\n var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio);\r\n var dprChanged = newDPR !== windowDpr && windowDpr > 0;\r\n var isZoom = deltaIsBigger && difference && dprChanged;\r\n var oldScrollbarSize = _base.nativeScrollbarSize;\r\n var newScrollbarSize;\r\n\r\n if (isZoom) {\r\n bodyElement.append(scrollbarDummyElement);\r\n newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]);\r\n scrollbarDummyElement.remove();\r\n if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) {\r\n FRAMEWORK.each(INSTANCES(), function () {\r\n if (INSTANCES(this))\r\n INSTANCES(this).update('zoom');\r\n });\r\n }\r\n }\r\n\r\n windowWidth = newW;\r\n windowHeight = newH;\r\n windowDpr = newDPR;\r\n }\r\n };\r\n\r\n function differenceIsBiggerThanOne(valOne, valTwo) {\r\n var absValOne = abs(valOne);\r\n var absValTwo = abs(valTwo);\r\n return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo);\r\n }\r\n\r\n function getWindowDPR() {\r\n var dDPI = window.screen.deviceXDPI || 0;\r\n var sDPI = window.screen.logicalXDPI || 1;\r\n return window.devicePixelRatio || (dDPI / sDPI);\r\n }\r\n\r\n FRAMEWORK(window).on('resize', onResize);\r\n })();\r\n\r\n function calcNativeScrollbarSize(measureElement) {\r\n return {\r\n x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH],\r\n y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW]\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @constructor\r\n */\r\n function OverlayScrollbarsAutoUpdateLoop(globals) {\r\n var _base = this;\r\n var _inArray = FRAMEWORK.inArray;\r\n var _getNow = COMPATIBILITY.now;\r\n var _strAutoUpdate = 'autoUpdate';\r\n var _strAutoUpdateInterval = _strAutoUpdate + 'Interval';\r\n var _strLength = LEXICON.l;\r\n var _loopingInstances = [];\r\n var _loopingInstancesIntervalCache = [];\r\n var _loopIsActive = false;\r\n var _loopIntervalDefault = 33;\r\n var _loopInterval = _loopIntervalDefault;\r\n var _loopTimeOld = _getNow();\r\n var _loopID;\r\n\r\n\r\n /**\r\n * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds.\r\n */\r\n var loop = function () {\r\n if (_loopingInstances[_strLength] > 0 && _loopIsActive) {\r\n _loopID = COMPATIBILITY.rAF()(function () {\r\n loop();\r\n });\r\n var timeNew = _getNow();\r\n var timeDelta = timeNew - _loopTimeOld;\r\n var lowestInterval;\r\n var instance;\r\n var instanceOptions;\r\n var instanceAutoUpdateAllowed;\r\n var instanceAutoUpdateInterval;\r\n var now;\r\n\r\n if (timeDelta > _loopInterval) {\r\n _loopTimeOld = timeNew - (timeDelta % _loopInterval);\r\n lowestInterval = _loopIntervalDefault;\r\n for (var i = 0; i < _loopingInstances[_strLength]; i++) {\r\n instance = _loopingInstances[i];\r\n if (instance !== undefined) {\r\n instanceOptions = instance.options();\r\n instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate];\r\n instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]);\r\n now = _getNow();\r\n\r\n if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) {\r\n instance.update('auto');\r\n _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval);\r\n }\r\n\r\n lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval));\r\n }\r\n }\r\n _loopInterval = lowestInterval;\r\n }\r\n } else {\r\n _loopInterval = _loopIntervalDefault;\r\n }\r\n };\r\n\r\n /**\r\n * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.add = function (instance) {\r\n if (_inArray(instance, _loopingInstances) === -1) {\r\n _loopingInstances.push(instance);\r\n _loopingInstancesIntervalCache.push(_getNow());\r\n if (_loopingInstances[_strLength] > 0 && !_loopIsActive) {\r\n _loopIsActive = true;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n loop();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.remove = function (instance) {\r\n var index = _inArray(instance, _loopingInstances);\r\n if (index > -1) {\r\n //remove from loopingInstances list\r\n _loopingInstancesIntervalCache.splice(index, 1);\r\n _loopingInstances.splice(index, 1);\r\n\r\n //correct update loop behavior\r\n if (_loopingInstances[_strLength] === 0 && _loopIsActive) {\r\n _loopIsActive = false;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n if (_loopID !== undefined) {\r\n COMPATIBILITY.cAF()(_loopID);\r\n _loopID = -1;\r\n }\r\n }\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * A object which manages the scrollbars visibility of the target element.\r\n * @param pluginTargetElement The element from which the scrollbars shall be hidden.\r\n * @param options The custom options.\r\n * @param extensions The custom extensions.\r\n * @param globals\r\n * @param autoUpdateLoop\r\n * @returns {*}\r\n * @constructor\r\n */\r\n function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) {\r\n //shortcuts\r\n var type = COMPATIBILITY.type;\r\n var inArray = FRAMEWORK.inArray;\r\n var each = FRAMEWORK.each;\r\n\r\n //make correct instanceof\r\n var _base = new _plugin();\r\n var _frameworkProto = FRAMEWORK[LEXICON.p];\r\n\r\n //if passed element is no HTML element: skip and return\r\n if (!isHTMLElement(pluginTargetElement))\r\n return;\r\n\r\n //if passed element is already initialized: set passed options if there are any and return its instance\r\n if (INSTANCES(pluginTargetElement)) {\r\n var inst = INSTANCES(pluginTargetElement);\r\n inst.options(options);\r\n return inst;\r\n }\r\n\r\n //globals:\r\n var _nativeScrollbarIsOverlaid;\r\n var _overlayScrollbarDummySize;\r\n var _rtlScrollBehavior;\r\n var _autoUpdateRecommended;\r\n var _msieVersion;\r\n var _nativeScrollbarStyling;\r\n var _cssCalc;\r\n var _nativeScrollbarSize;\r\n var _supportTransition;\r\n var _supportTransform;\r\n var _supportPassiveEvents;\r\n var _supportResizeObserver;\r\n var _supportMutationObserver;\r\n var _restrictedMeasuring;\r\n\r\n //general readonly:\r\n var _initialized;\r\n var _destroyed;\r\n var _isTextarea;\r\n var _isBody;\r\n var _documentMixed;\r\n var _domExists;\r\n\r\n //general:\r\n var _isBorderBox;\r\n var _sizeAutoObserverAdded;\r\n var _paddingX;\r\n var _paddingY;\r\n var _borderX;\r\n var _borderY;\r\n var _marginX;\r\n var _marginY;\r\n var _isRTL;\r\n var _sleeping;\r\n var _contentBorderSize = {};\r\n var _scrollHorizontalInfo = {};\r\n var _scrollVerticalInfo = {};\r\n var _viewportSize = {};\r\n var _nativeScrollbarMinSize = {};\r\n\r\n //naming:\t\r\n var _strMinusHidden = '-hidden';\r\n var _strMarginMinus = 'margin-';\r\n var _strPaddingMinus = 'padding-';\r\n var _strBorderMinus = 'border-';\r\n var _strTop = 'top';\r\n var _strRight = 'right';\r\n var _strBottom = 'bottom';\r\n var _strLeft = 'left';\r\n var _strMinMinus = 'min-';\r\n var _strMaxMinus = 'max-';\r\n var _strWidth = 'width';\r\n var _strHeight = 'height';\r\n var _strFloat = 'float';\r\n var _strEmpty = '';\r\n var _strAuto = 'auto';\r\n var _strSync = 'sync';\r\n var _strScroll = 'scroll';\r\n var _strHundredPercent = '100%';\r\n var _strX = 'x';\r\n var _strY = 'y';\r\n var _strDot = '.';\r\n var _strSpace = ' ';\r\n var _strScrollbar = 'scrollbar';\r\n var _strMinusHorizontal = '-horizontal';\r\n var _strMinusVertical = '-vertical';\r\n var _strScrollLeft = _strScroll + 'Left';\r\n var _strScrollTop = _strScroll + 'Top';\r\n var _strMouseTouchDownEvent = 'mousedown touchstart';\r\n var _strMouseTouchUpEvent = 'mouseup touchend touchcancel';\r\n var _strMouseTouchMoveEvent = 'mousemove touchmove';\r\n var _strMouseEnter = 'mouseenter';\r\n var _strMouseLeave = 'mouseleave';\r\n var _strKeyDownEvent = 'keydown';\r\n var _strKeyUpEvent = 'keyup';\r\n var _strSelectStartEvent = 'selectstart';\r\n var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd';\r\n var _strResizeObserverProperty = '__overlayScrollbarsRO__';\r\n\r\n //class names:\t\r\n var _cassNamesPrefix = 'os-';\r\n var _classNameHTMLElement = _cassNamesPrefix + 'html';\r\n var _classNameHostElement = _cassNamesPrefix + 'host';\r\n var _classNameHostElementForeign = _classNameHostElement + '-foreign';\r\n var _classNameHostTextareaElement = _classNameHostElement + '-textarea';\r\n var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden;\r\n var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden;\r\n var _classNameHostTransition = _classNameHostElement + '-transition';\r\n var _classNameHostRTL = _classNameHostElement + '-rtl';\r\n var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled';\r\n var _classNameHostScrolling = _classNameHostElement + '-scrolling';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflowX = _classNameHostOverflow + '-x';\r\n var _classNameHostOverflowY = _classNameHostOverflow + '-y';\r\n var _classNameTextareaElement = _cassNamesPrefix + 'textarea';\r\n var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover';\r\n var _classNamePaddingElement = _cassNamesPrefix + 'padding';\r\n var _classNameViewportElement = _cassNamesPrefix + 'viewport';\r\n var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible';\r\n var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid';\r\n var _classNameContentElement = _cassNamesPrefix + 'content';\r\n var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange';\r\n var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue';\r\n var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer';\r\n var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer';\r\n var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item';\r\n var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final';\r\n var _classNameTextInherit = _cassNamesPrefix + 'text-inherit';\r\n var _classNameScrollbar = _cassNamesPrefix + _strScrollbar;\r\n var _classNameScrollbarTrack = _classNameScrollbar + '-track';\r\n var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off';\r\n var _classNameScrollbarHandle = _classNameScrollbar + '-handle';\r\n var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off';\r\n var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable';\r\n var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden;\r\n var _classNameScrollbarCorner = _classNameScrollbar + '-corner';\r\n var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize';\r\n var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both';\r\n var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal;\r\n var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical;\r\n var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal;\r\n var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical;\r\n var _classNameDragging = _cassNamesPrefix + 'dragging';\r\n var _classNameThemeNone = _cassNamesPrefix + 'theme-none';\r\n var _classNamesDynamicDestroy = [\r\n _classNameViewportNativeScrollbarsInvisible,\r\n _classNameViewportNativeScrollbarsOverlaid,\r\n _classNameScrollbarTrackOff,\r\n _classNameScrollbarHandleOff,\r\n _classNameScrollbarUnusable,\r\n _classNameScrollbarAutoHidden,\r\n _classNameScrollbarCornerResize,\r\n _classNameScrollbarCornerResizeB,\r\n _classNameScrollbarCornerResizeH,\r\n _classNameScrollbarCornerResizeV,\r\n _classNameDragging].join(_strSpace);\r\n\r\n //callbacks:\t\r\n var _callbacksInitQeueue = [];\r\n\r\n //attrs viewport shall inherit from target\t\r\n var _viewportAttrsFromTarget = [LEXICON.ti];\r\n\r\n //options:\t\r\n var _defaultOptions;\r\n var _currentOptions;\r\n var _currentPreparedOptions;\r\n\r\n //extensions:\t\r\n var _extensions = {};\r\n var _extensionsPrivateMethods = 'added removed on contract';\r\n\r\n //update\t\r\n var _lastUpdateTime;\r\n var _swallowedUpdateHints = {};\r\n var _swallowedUpdateTimeout;\r\n var _swallowUpdateLag = 42;\r\n var _updateOnLoadEventName = 'load';\r\n var _updateOnLoadElms = [];\r\n\r\n //DOM elements:\t\r\n var _windowElement;\r\n var _documentElement;\r\n var _htmlElement;\r\n var _bodyElement;\r\n var _targetElement; //the target element of this OverlayScrollbars object\t\r\n var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement\t\r\n var _sizeAutoObserverElement; //observes size auto changes\t\r\n var _sizeObserverElement; //observes size and padding changes\t\r\n var _paddingElement; //manages the padding\t\r\n var _viewportElement; //is the viewport of our scrollbar model\t\r\n var _contentElement; //the element which holds the content\t\r\n var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays)\t\r\n var _contentGlueElement; //has always the size of the content element\t\r\n var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling\t\r\n var _scrollbarCornerElement;\r\n var _scrollbarHorizontalElement;\r\n var _scrollbarHorizontalTrackElement;\r\n var _scrollbarHorizontalHandleElement;\r\n var _scrollbarVerticalElement;\r\n var _scrollbarVerticalTrackElement;\r\n var _scrollbarVerticalHandleElement;\r\n var _windowElementNative;\r\n var _documentElementNative;\r\n var _targetElementNative;\r\n var _hostElementNative;\r\n var _sizeAutoObserverElementNative;\r\n var _sizeObserverElementNative;\r\n var _paddingElementNative;\r\n var _viewportElementNative;\r\n var _contentElementNative;\r\n\r\n //Cache:\t\r\n var _hostSizeCache;\r\n var _contentScrollSizeCache;\r\n var _arrangeContentSizeCache;\r\n var _hasOverflowCache;\r\n var _hideOverflowCache;\r\n var _widthAutoCache;\r\n var _heightAutoCache;\r\n var _cssBoxSizingCache;\r\n var _cssPaddingCache;\r\n var _cssBorderCache;\r\n var _cssMarginCache;\r\n var _cssDirectionCache;\r\n var _cssDirectionDetectedCache;\r\n var _paddingAbsoluteCache;\r\n var _clipAlwaysCache;\r\n var _contentGlueSizeCache;\r\n var _overflowBehaviorCache;\r\n var _overflowAmountCache;\r\n var _ignoreOverlayScrollbarHidingCache;\r\n var _autoUpdateCache;\r\n var _sizeAutoCapableCache;\r\n var _contentElementScrollSizeChangeDetectedCache;\r\n var _hostElementSizeChangeDetectedCache;\r\n var _scrollbarsVisibilityCache;\r\n var _scrollbarsAutoHideCache;\r\n var _scrollbarsClickScrollingCache;\r\n var _scrollbarsDragScrollingCache;\r\n var _resizeCache;\r\n var _normalizeRTLCache;\r\n var _classNameCache;\r\n var _oldClassName;\r\n var _textareaAutoWrappingCache;\r\n var _textareaInfoCache;\r\n var _textareaSizeCache;\r\n var _textareaDynHeightCache;\r\n var _textareaDynWidthCache;\r\n var _bodyMinSizeCache;\r\n var _updateAutoCache = {};\r\n\r\n //MutationObserver:\t\r\n var _mutationObserverHost;\r\n var _mutationObserverContent;\r\n var _mutationObserverHostCallback;\r\n var _mutationObserverContentCallback;\r\n var _mutationObserversConnected;\r\n var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows'];\r\n var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget);\r\n\r\n //events:\t\r\n var _destroyEvents = [];\r\n\r\n //textarea:\t\r\n var _textareaHasFocus;\r\n\r\n //scrollbars:\t\r\n var _scrollbarsAutoHideTimeoutId;\r\n var _scrollbarsAutoHideMoveTimeoutId;\r\n var _scrollbarsAutoHideDelay;\r\n var _scrollbarsAutoHideNever;\r\n var _scrollbarsAutoHideScroll;\r\n var _scrollbarsAutoHideMove;\r\n var _scrollbarsAutoHideLeave;\r\n var _scrollbarsHandleHovered;\r\n var _scrollbarsHandlesDefineScrollPos;\r\n\r\n //resize\t\r\n var _resizeNone;\r\n var _resizeBoth;\r\n var _resizeHorizontal;\r\n var _resizeVertical;\r\n\r\n\r\n //==== Event Listener ====//\t\r\n\r\n /**\t\r\n * Adds or removes a event listener from the given element. \t\r\n * @param element The element to which the event listener shall be applied or removed.\t\r\n * @param eventNames The name(s) of the events.\t\r\n * @param listener The method which shall be called.\t\r\n * @param remove True if the handler shall be removed, false or undefined if the handler shall be added.\t\r\n * @param passiveOrOptions The options for the event.\r\n */\r\n function setupResponsiveEventListener(element, eventNames, listener, remove, passiveOrOptions) {\r\n var collected = COMPATIBILITY.isA(eventNames) && COMPATIBILITY.isA(listener);\r\n var method = remove ? 'removeEventListener' : 'addEventListener';\r\n var onOff = remove ? 'off' : 'on';\r\n var events = collected ? false : eventNames.split(_strSpace)\r\n var i = 0;\r\n\r\n var passiveOrOptionsIsObj = FRAMEWORK.isPlainObject(passiveOrOptions);\r\n var passive = (_supportPassiveEvents && (passiveOrOptionsIsObj ? (passiveOrOptions._passive) : passiveOrOptions)) || false;\r\n var capture = passiveOrOptionsIsObj && (passiveOrOptions._capture || false);\r\n var nativeParam = _supportPassiveEvents ? {\r\n passive: passive,\r\n capture: capture,\r\n } : capture;\r\n\r\n if (collected) {\r\n for (; i < eventNames[LEXICON.l]; i++)\r\n setupResponsiveEventListener(element, eventNames[i], listener[i], remove, passiveOrOptions);\r\n }\r\n else {\r\n for (; i < events[LEXICON.l]; i++) {\r\n if(_supportPassiveEvents) {\r\n element[0][method](events[i], listener, nativeParam);\r\n }\r\n else {\r\n element[onOff](events[i], listener);\r\n } \r\n }\r\n }\r\n }\r\n\r\n\r\n function addDestroyEventListener(element, eventNames, listener, passive) {\r\n setupResponsiveEventListener(element, eventNames, listener, false, passive);\r\n _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive));\r\n }\r\n\r\n //==== Resize Observer ====//\r\n\r\n /**\r\n * Adds or removes a resize observer from the given element.\r\n * @param targetElement The element to which the resize observer shall be added or removed.\r\n * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed.\r\n */\r\n function setupResizeObserver(targetElement, onElementResizedCallback) {\r\n if (targetElement) {\r\n var resizeObserver = COMPATIBILITY.rO();\r\n var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart';\r\n var strChildNodes = 'childNodes';\r\n var constScroll = 3333333;\r\n var callback = function () {\r\n targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll);\r\n onElementResizedCallback();\r\n };\r\n //add resize observer:\r\n if (onElementResizedCallback) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0];\r\n var observer = element[_strResizeObserverProperty] = new resizeObserver(callback);\r\n observer.observe(element);\r\n }\r\n else {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n targetElement.prepend(\r\n generateDiv(_classNameResizeObserverElement,\r\n generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' },\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv(_classNameResizeObserverItemFinalElement)\r\n ) +\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' })\r\n )\r\n )\r\n )\r\n );\r\n\r\n var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0];\r\n var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]);\r\n var expandElement = FRAMEWORK(observerElement[strChildNodes][0]);\r\n var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]);\r\n var widthCache = observerElement[LEXICON.oW];\r\n var heightCache = observerElement[LEXICON.oH];\r\n var isDirty;\r\n var rAFId;\r\n var currWidth;\r\n var currHeight;\r\n var factor = 2;\r\n var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!!\r\n var reset = function () {\r\n /*\r\n var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var expandChildCSS = {};\r\n expandChildCSS[_strWidth] = sizeResetWidth;\r\n expandChildCSS[_strHeight] = sizeResetHeight;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n\r\n expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n */\r\n expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n };\r\n var onResized = function () {\r\n rAFId = 0;\r\n if (!isDirty)\r\n return;\r\n\r\n widthCache = currWidth;\r\n heightCache = currHeight;\r\n callback();\r\n };\r\n var onScroll = function (event) {\r\n currWidth = observerElement[LEXICON.oW];\r\n currHeight = observerElement[LEXICON.oH];\r\n isDirty = currWidth != widthCache || currHeight != heightCache;\r\n\r\n if (event && isDirty && !rAFId) {\r\n COMPATIBILITY.cAF()(rAFId);\r\n rAFId = COMPATIBILITY.rAF()(onResized);\r\n }\r\n else if (!event)\r\n onResized();\r\n\r\n reset();\r\n if (event) {\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n return false;\r\n };\r\n var expandChildCSS = {};\r\n var observerElementCSS = {};\r\n\r\n setTopRightBottomLeft(observerElementCSS, _strEmpty, [\r\n -((nativeScrollbarSize.y + 1) * factor),\r\n nativeScrollbarSize.x * -factor,\r\n nativeScrollbarSize.y * -factor,\r\n -((nativeScrollbarSize.x + 1) * factor)\r\n ]);\r\n\r\n FRAMEWORK(observerElement).css(observerElementCSS);\r\n expandElement.on(_strScroll, onScroll);\r\n shrinkElement.on(_strScroll, onScroll);\r\n targetElement.on(strAnimationStartEvent, function () {\r\n onScroll(false);\r\n });\r\n //lets assume that the divs will never be that large and a constant value is enough\r\n expandChildCSS[_strWidth] = constScroll;\r\n expandChildCSS[_strHeight] = constScroll;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n reset();\r\n }\r\n else {\r\n var attachEvent = _documentElementNative.attachEvent;\r\n var isIE = _msieVersion !== undefined;\r\n if (attachEvent) {\r\n targetElement.prepend(generateDiv(_classNameResizeObserverElement));\r\n findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback);\r\n }\r\n else {\r\n var obj = _documentElementNative.createElement(TYPES.o);\r\n obj.setAttribute(LEXICON.ti, '-1');\r\n obj.setAttribute(LEXICON.c, _classNameResizeObserverElement);\r\n obj.onload = function () {\r\n var wnd = this.contentDocument.defaultView;\r\n wnd.addEventListener('resize', callback);\r\n wnd.document.documentElement.style.display = 'none';\r\n };\r\n obj.type = 'text/html';\r\n if (isIE)\r\n targetElement.prepend(obj);\r\n obj.data = 'about:blank';\r\n if (!isIE)\r\n targetElement.prepend(obj);\r\n targetElement.on(strAnimationStartEvent, callback);\r\n }\r\n }\r\n }\r\n\r\n if (targetElement[0] === _sizeObserverElementNative) {\r\n var directionChanged = function () {\r\n var dir = _hostElement.css('direction');\r\n var css = {};\r\n var scrollLeftValue = 0;\r\n var result = false;\r\n if (dir !== _cssDirectionDetectedCache) {\r\n if (dir === 'ltr') {\r\n css[_strLeft] = 0;\r\n css[_strRight] = _strAuto;\r\n scrollLeftValue = constScroll;\r\n }\r\n else {\r\n css[_strLeft] = _strAuto;\r\n css[_strRight] = 0;\r\n scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll;\r\n }\r\n //execution order is important for IE!!!\r\n _sizeObserverElement.children().eq(0).css(css);\r\n _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll);\r\n _cssDirectionDetectedCache = dir;\r\n result = true;\r\n }\r\n return result;\r\n };\r\n directionChanged();\r\n addDestroyEventListener(targetElement, _strScroll, function (event) {\r\n if (directionChanged())\r\n update();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n });\r\n }\r\n }\r\n //remove resize observer:\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n var resizeObserverObj = element[_strResizeObserverProperty];\r\n if (resizeObserverObj) {\r\n resizeObserverObj.disconnect();\r\n delete element[_strResizeObserverProperty];\r\n }\r\n }\r\n else {\r\n remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0));\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Freezes or unfreezes the given resize observer.\r\n * @param targetElement The element to which the target resize observer is applied.\r\n * @param freeze True if the resize observer shall be frozen, false otherwise.\r\n \r\n function freezeResizeObserver(targetElement, freeze) {\r\n if (targetElement !== undefined) {\r\n if(freeze) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].unobserve(element);\r\n }\r\n else {\r\n targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0);\r\n var w = targetElement.css(_strWidth);\r\n var h = targetElement.css(_strHeight);\r\n var css = {};\r\n css[_strWidth] = w;\r\n css[_strHeight] = h;\r\n targetElement.css(css);\r\n }\r\n }\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].observe(element);\r\n }\r\n else {\r\n var css = { };\r\n css[_strHeight] = _strEmpty;\r\n css[_strWidth] = _strEmpty;\r\n targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css);\r\n }\r\n }\r\n }\r\n }\r\n */\r\n\r\n\r\n //==== Mutation Observers ====//\r\n\r\n /**\r\n * Creates MutationObservers for the host and content Element if they are supported.\r\n */\r\n function createMutationObservers() {\r\n if (_supportMutationObserver) {\r\n var mutationObserverContentLag = 11;\r\n var mutationObserver = COMPATIBILITY.mO();\r\n var contentLastUpdate = COMPATIBILITY.now();\r\n var mutationTarget;\r\n var mutationAttrName;\r\n var mutationIsClass;\r\n var oldMutationVal;\r\n var newClassVal;\r\n var hostClassNameRegex;\r\n var contentTimeout;\r\n var now;\r\n var sizeAuto;\r\n var action;\r\n\r\n _mutationObserverHostCallback = function (mutations) {\r\n\r\n var doUpdate = false;\r\n var doUpdateForce = false;\r\n var mutation;\r\n var mutatedAttrs = [];\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n mutationTarget = mutation.target;\r\n mutationAttrName = mutation.attributeName;\r\n mutationIsClass = mutationAttrName === LEXICON.c;\r\n oldMutationVal = mutation.oldValue;\r\n newClassVal = mutationTarget.className;\r\n\r\n if (_domExists && mutationIsClass && !doUpdateForce) {\r\n // if old class value contains _classNameHostElementForeign and new class value doesn't\r\n if (oldMutationVal.indexOf(_classNameHostElementForeign) > -1 && newClassVal.indexOf(_classNameHostElementForeign) < 0) {\r\n hostClassNameRegex = createHostClassNameRegExp(true);\r\n _hostElementNative.className = newClassVal.split(_strSpace).concat(oldMutationVal.split(_strSpace).filter(function (name) {\r\n return name.match(hostClassNameRegex);\r\n })).join(_strSpace);\r\n doUpdate = doUpdateForce = true;\r\n }\r\n }\r\n\r\n if (!doUpdate) {\r\n doUpdate = mutationIsClass\r\n ? hostClassNamesChanged(oldMutationVal, newClassVal)\r\n : mutationAttrName === LEXICON.s\r\n ? oldMutationVal !== mutationTarget[LEXICON.s].cssText\r\n : true;\r\n }\r\n\r\n mutatedAttrs.push(mutationAttrName);\r\n });\r\n\r\n updateViewportAttrsFromTarget(mutatedAttrs);\r\n\r\n if (doUpdate)\r\n _base.update(doUpdateForce || _strAuto);\r\n }\r\n return doUpdate;\r\n };\r\n _mutationObserverContentCallback = function (mutations) {\r\n var doUpdate = false;\r\n var mutation;\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n doUpdate = isUnknownMutation(mutation);\r\n return !doUpdate;\r\n });\r\n\r\n if (doUpdate) {\r\n now = COMPATIBILITY.now();\r\n sizeAuto = (_heightAutoCache || _widthAutoCache);\r\n action = function () {\r\n if (!_destroyed) {\r\n contentLastUpdate = now;\r\n\r\n //if cols, rows or wrap attr was changed\r\n if (_isTextarea)\r\n textareaUpdate();\r\n\r\n if (sizeAuto)\r\n update();\r\n else\r\n _base.update(_strAuto);\r\n }\r\n };\r\n clearTimeout(contentTimeout);\r\n if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto)\r\n action();\r\n else\r\n contentTimeout = setTimeout(action, mutationObserverContentLag);\r\n }\r\n }\r\n return doUpdate;\r\n }\r\n\r\n _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback);\r\n _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Connects the MutationObservers if they are supported.\r\n */\r\n function connectMutationObservers() {\r\n if (_supportMutationObserver && !_mutationObserversConnected) {\r\n _mutationObserverHost.observe(_hostElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n attributeFilter: _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n subtree: !_isTextarea,\r\n childList: !_isTextarea,\r\n characterData: !_isTextarea,\r\n attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserversConnected = true;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnects the MutationObservers if they are supported.\r\n */\r\n function disconnectMutationObservers() {\r\n if (_supportMutationObserver && _mutationObserversConnected) {\r\n _mutationObserverHost.disconnect();\r\n _mutationObserverContent.disconnect();\r\n\r\n _mutationObserversConnected = false;\r\n }\r\n }\r\n\r\n\r\n //==== Events of elements ====//\r\n\r\n /**\r\n * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!!\r\n * It refreshes the hostResizedEventArgs and the hostSizeResizeCache.\r\n * If there are any size changes, the update method gets called.\r\n */\r\n function hostOnResized() {\r\n if (!_sleeping) {\r\n var changed;\r\n var hostSize = {\r\n w: _sizeObserverElementNative[LEXICON.sW],\r\n h: _sizeObserverElementNative[LEXICON.sH]\r\n };\r\n\r\n changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache);\r\n _hostElementSizeChangeDetectedCache = hostSize;\r\n if (changed)\r\n update({ _hostSizeChanged: true });\r\n }\r\n }\r\n\r\n /**\r\n * The mouse enter event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseEnter() {\r\n if (_scrollbarsAutoHideLeave)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n\r\n /**\r\n * The mouse leave event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseLeave() {\r\n if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging))\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n\r\n /**\r\n * The mouse move event of the host element. This event is only needed for the autoHide \"move\" feature.\r\n */\r\n function hostOnMouseMove() {\r\n if (_scrollbarsAutoHideMove) {\r\n refreshScrollbarsAutoHide(true);\r\n clearTimeout(_scrollbarsAutoHideMoveTimeoutId);\r\n _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () {\r\n if (_scrollbarsAutoHideMove && !_destroyed)\r\n refreshScrollbarsAutoHide(false);\r\n }, 100);\r\n }\r\n }\r\n\r\n /**\r\n * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element.\r\n * @param event The select start event.\r\n */\r\n function documentOnSelectStart(event) {\r\n COMPATIBILITY.prvD(event);\r\n return false;\r\n }\r\n\r\n /**\t\r\n * A callback which will be called after a element has loaded.\t\r\n */\r\n function updateOnLoadCallback(event) {\r\n var elm = FRAMEWORK(event.target);\r\n\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n if (elm.is(updateOnLoadSelector)) {\r\n update({ _contentSizeChanged: true });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars)\r\n * @param destroy Indicates whether the events shall be added or removed.\r\n */\r\n function setupHostMouseTouchEvents(destroy) {\r\n if (!destroy)\r\n setupHostMouseTouchEvents(true);\r\n\r\n setupResponsiveEventListener(_hostElement,\r\n _strMouseTouchMoveEvent.split(_strSpace)[0],\r\n hostOnMouseMove,\r\n (!_scrollbarsAutoHideMove || destroy), true);\r\n setupResponsiveEventListener(_hostElement,\r\n [_strMouseEnter, _strMouseLeave],\r\n [hostOnMouseEnter, hostOnMouseLeave],\r\n (!_scrollbarsAutoHideLeave || destroy), true);\r\n\r\n //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible\r\n if (!_initialized && !destroy)\r\n _hostElement.one('mouseover', hostOnMouseEnter);\r\n }\r\n\r\n\r\n //==== Update Detection ====//\r\n\r\n /**\r\n * Measures the min width and min height of the body element and refreshes the related cache.\r\n * @returns {boolean} True if the min width or min height has changed, false otherwise.\r\n */\r\n function bodyMinSizeChanged() {\r\n var bodyMinSize = {};\r\n if (_isBody && _contentArrangeElement) {\r\n bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth));\r\n bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight));\r\n bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache);\r\n bodyMinSize.f = true; //flag for \"measured at least once\"\r\n }\r\n _bodyMinSizeCache = bodyMinSize;\r\n return !!bodyMinSize.c;\r\n }\r\n\r\n /**\r\n * Returns true if the class names really changed (new class without plugin host prefix)\r\n * @param oldClassNames The old ClassName string or array.\r\n * @param newClassNames The new ClassName string or array.\r\n * @returns {boolean} True if the class names has really changed, false otherwise.\r\n */\r\n function hostClassNamesChanged(oldClassNames, newClassNames) {\r\n var currClasses = typeof newClassNames == TYPES.s ? newClassNames.split(_strSpace) : [];\r\n var oldClasses = typeof oldClassNames == TYPES.s ? oldClassNames.split(_strSpace) : [];\r\n var diff = getArrayDifferences(oldClasses, currClasses);\r\n\r\n // remove none theme from diff list to prevent update\r\n var idx = inArray(_classNameThemeNone, diff);\r\n var i;\r\n var regex;\r\n\r\n if (idx > -1)\r\n diff.splice(idx, 1);\r\n\r\n if (diff[LEXICON.l] > 0) {\r\n regex = createHostClassNameRegExp(true, true);\r\n for (i = 0; i < diff.length; i++) {\r\n if (!diff[i].match(regex)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown.\r\n * @param mutation The mutation which shall be checked.\r\n * @returns {boolean} True if the mutation is from a unknown element, false otherwise.\r\n */\r\n function isUnknownMutation(mutation) {\r\n var attributeName = mutation.attributeName;\r\n var mutationTarget = mutation.target;\r\n var mutationType = mutation.type;\r\n var strClosest = 'closest';\r\n\r\n if (mutationTarget === _contentElementNative)\r\n return attributeName === null;\r\n if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) {\r\n //ignore className changes by the plugin\t\r\n if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement))\r\n return hostClassNamesChanged(mutation.oldValue, mutationTarget.className);\r\n\r\n //only do it of browser support it natively\t\r\n if (typeof mutationTarget[strClosest] != TYPES.f)\r\n return true;\r\n if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null)\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true if the content size was changed since the last time this method was called.\r\n * @returns {boolean} True if the content size was changed, false otherwise.\r\n */\r\n function updateAutoContentSizeChanged() {\r\n if (_sleeping)\r\n return false;\r\n\r\n var contentMeasureElement = getContentMeasureElement();\r\n var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0;\r\n var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea;\r\n var css = {};\r\n var float;\r\n var bodyMinSizeC;\r\n var changed;\r\n var contentElementScrollSize;\r\n\r\n if (setCSS) {\r\n float = _contentElement.css(_strFloat);\r\n css[_strFloat] = _isRTL ? _strRight : _strLeft;\r\n css[_strWidth] = _strAuto;\r\n _contentElement.css(css);\r\n }\r\n contentElementScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW] + textareaValueLength,\r\n h: contentMeasureElement[LEXICON.sH] + textareaValueLength\r\n };\r\n if (setCSS) {\r\n css[_strFloat] = float;\r\n css[_strWidth] = _strHundredPercent;\r\n _contentElement.css(css);\r\n }\r\n\r\n bodyMinSizeC = bodyMinSizeChanged();\r\n changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache);\r\n\r\n _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize;\r\n\r\n return changed || bodyMinSizeC;\r\n }\r\n\r\n /**\r\n * Returns true when a attribute which the MutationObserver would observe has changed. \r\n * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise.\r\n */\r\n function meaningfulAttrsChanged() {\r\n if (_sleeping || _mutationObserversConnected)\r\n return;\r\n\r\n var elem;\r\n var curr;\r\n var cache;\r\n var changedAttrs = [];\r\n var checks = [\r\n {\r\n _elem: _hostElement,\r\n _attrs: _mutationObserverAttrsHost.concat(':visible')\r\n },\r\n {\r\n _elem: _isTextarea ? _targetElement : undefined,\r\n _attrs: _mutationObserverAttrsTextarea\r\n }\r\n ];\r\n\r\n each(checks, function (index, check) {\r\n elem = check._elem;\r\n if (elem) {\r\n each(check._attrs, function (index, attr) {\r\n curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr);\r\n cache = _updateAutoCache[attr];\r\n\r\n if (checkCache(curr, cache)) {\r\n changedAttrs.push(attr);\r\n }\r\n\r\n _updateAutoCache[attr] = curr;\r\n });\r\n }\r\n });\r\n\r\n updateViewportAttrsFromTarget(changedAttrs);\r\n\r\n return changedAttrs[LEXICON.l] > 0;\r\n }\r\n\r\n /**\r\n * Checks is a CSS Property of a child element is affecting the scroll size of the content.\r\n * @param propertyName The CSS property name.\r\n * @returns {boolean} True if the property is affecting the content scroll size, false otherwise.\r\n */\r\n function isSizeAffectingCSSProperty(propertyName) {\r\n if (!_initialized)\r\n return true;\r\n var flexGrow = 'flex-grow';\r\n var flexShrink = 'flex-shrink';\r\n var flexBasis = 'flex-basis';\r\n var affectingPropsX = [\r\n _strWidth,\r\n _strMinMinus + _strWidth,\r\n _strMaxMinus + _strWidth,\r\n _strMarginMinus + _strLeft,\r\n _strMarginMinus + _strRight,\r\n _strLeft,\r\n _strRight,\r\n 'font-weight',\r\n 'word-spacing',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsXContentBox = [\r\n _strPaddingMinus + _strLeft,\r\n _strPaddingMinus + _strRight,\r\n _strBorderMinus + _strLeft + _strWidth,\r\n _strBorderMinus + _strRight + _strWidth\r\n ];\r\n var affectingPropsY = [\r\n _strHeight,\r\n _strMinMinus + _strHeight,\r\n _strMaxMinus + _strHeight,\r\n _strMarginMinus + _strTop,\r\n _strMarginMinus + _strBottom,\r\n _strTop,\r\n _strBottom,\r\n 'line-height',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsYContentBox = [\r\n _strPaddingMinus + _strTop,\r\n _strPaddingMinus + _strBottom,\r\n _strBorderMinus + _strTop + _strWidth,\r\n _strBorderMinus + _strBottom + _strWidth\r\n ];\r\n var _strS = 's';\r\n var _strVS = 'v-s';\r\n var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS;\r\n var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS;\r\n var sizeIsAffected = false;\r\n var checkPropertyName = function (arr, name) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++) {\r\n if (arr[i] === name)\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n if (checkY) {\r\n sizeIsAffected = checkPropertyName(affectingPropsY, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName);\r\n }\r\n if (checkX && !sizeIsAffected) {\r\n sizeIsAffected = checkPropertyName(affectingPropsX, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName);\r\n }\r\n return sizeIsAffected;\r\n }\r\n\r\n\r\n //==== Update ====//\r\n\r\n /**\r\n * Sets the attribute values of the viewport element to the values from the target element.\r\n * The value of a attribute is only set if the attribute is whitelisted.\r\n * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set.\r\n */\r\n function updateViewportAttrsFromTarget(attrs) {\r\n attrs = attrs || _viewportAttrsFromTarget;\r\n each(attrs, function (index, attr) {\r\n if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) {\r\n var targetAttr = _targetElement.attr(attr);\r\n if (type(targetAttr) == TYPES.s) {\r\n _viewportElement.attr(attr, targetAttr);\r\n }\r\n else {\r\n _viewportElement.removeAttr(attr);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Updates the variables and size of the textarea element, and manages the scroll on new line or new character.\r\n */\r\n function textareaUpdate() {\r\n if (!_sleeping) {\r\n var wrapAttrOff = !_textareaAutoWrappingCache;\r\n var minWidth = _viewportSize.w;\r\n var minHeight = _viewportSize.h;\r\n var css = {};\r\n var doMeasure = _widthAutoCache || wrapAttrOff;\r\n var origWidth;\r\n var width;\r\n var origHeight;\r\n var height;\r\n\r\n //reset min size\r\n css[_strMinMinus + _strWidth] = _strEmpty;\r\n css[_strMinMinus + _strHeight] = _strEmpty;\r\n\r\n //set width auto\r\n css[_strWidth] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure width\r\n origWidth = _targetElementNative[LEXICON.oW];\r\n width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1;\r\n /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/\r\n\r\n //set measured width\r\n css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent;\r\n css[_strMinMinus + _strWidth] = _strHundredPercent;\r\n\r\n //set height auto\r\n css[_strHeight] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure height\r\n origHeight = _targetElementNative[LEXICON.oH];\r\n height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1);\r\n\r\n //append correct size values\r\n css[_strWidth] = width;\r\n css[_strHeight] = height;\r\n _textareaCoverElement.css(css);\r\n\r\n //apply min width / min height to prevent textarea collapsing\r\n css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/;\r\n css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/;\r\n _targetElement.css(css);\r\n\r\n return {\r\n _originalWidth: origWidth,\r\n _originalHeight: origHeight,\r\n _dynamicWidth: width,\r\n _dynamicHeight: height\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param updateHints A objects which contains hints for this update:\r\n * {\r\n * _hostSizeChanged : boolean,\r\n * _contentSizeChanged : boolean,\r\n * _force : boolean, == preventSwallowing\r\n * _changedOptions : { }, == preventSwallowing && preventSleep\r\n * }\r\n */\r\n function update(updateHints) {\r\n clearTimeout(_swallowedUpdateTimeout);\r\n updateHints = updateHints || {};\r\n _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged;\r\n _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged;\r\n _swallowedUpdateHints._force |= updateHints._force;\r\n\r\n var now = COMPATIBILITY.now();\r\n var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged;\r\n var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged;\r\n var force = !!_swallowedUpdateHints._force;\r\n var changedOptions = updateHints._changedOptions;\r\n var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache);\r\n var displayIsHidden;\r\n\r\n if (swallow)\r\n _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag);\r\n\r\n //abort update due to:\r\n //destroyed\r\n //swallowing\r\n //sleeping\r\n //host is hidden or has false display\r\n if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline')\r\n return;\r\n\r\n _lastUpdateTime = now;\r\n _swallowedUpdateHints = {};\r\n\r\n //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely.\r\n if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n //native scrollbars are hidden, so change the values to zero\r\n _nativeScrollbarSize.x = 0;\r\n _nativeScrollbarSize.y = 0;\r\n }\r\n else {\r\n //refresh native scrollbar size (in case of zoom)\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n }\r\n\r\n // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small.\r\n // The calculation: [scrollbar size +3 *3]\r\n // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar)\r\n // (*3 because (1)increase / (2)decrease -button and (3)resize handle)\r\n _nativeScrollbarMinSize = {\r\n x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3,\r\n y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3\r\n };\r\n\r\n changedOptions = changedOptions || {};\r\n //freezeResizeObserver(_sizeObserverElement, true);\r\n //freezeResizeObserver(_sizeAutoObserverElement, true);\r\n\r\n var checkCacheAutoForce = function () {\r\n return checkCache.apply(this, [].slice.call(arguments).concat([force]));\r\n };\r\n\r\n //save current scroll offset\r\n var currScroll = {\r\n x: _viewportElement[_strScrollLeft](),\r\n y: _viewportElement[_strScrollTop]()\r\n };\r\n\r\n var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars;\r\n var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea;\r\n\r\n //scrollbars visibility:\r\n var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility;\r\n var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache);\r\n\r\n //scrollbars autoHide:\r\n var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide;\r\n var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache);\r\n\r\n //scrollbars click scrolling\r\n var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling;\r\n var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache);\r\n\r\n //scrollbars drag scrolling\r\n var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling;\r\n var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache);\r\n\r\n //className\r\n var className = _currentPreparedOptions.className;\r\n var classNameChanged = checkCacheAutoForce(className, _classNameCache);\r\n\r\n //resize\r\n var resize = _currentPreparedOptions.resize;\r\n var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility.\r\n\r\n //paddingAbsolute\r\n var paddingAbsolute = _currentPreparedOptions.paddingAbsolute;\r\n var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache);\r\n\r\n //clipAlways\r\n var clipAlways = _currentPreparedOptions.clipAlways;\r\n var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache);\r\n\r\n //sizeAutoCapable\r\n var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport.\r\n var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache);\r\n\r\n //showNativeScrollbars\r\n var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars;\r\n var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache);\r\n\r\n //autoUpdate\r\n var autoUpdate = _currentPreparedOptions.autoUpdate;\r\n var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache);\r\n\r\n //overflowBehavior\r\n var overflowBehavior = _currentPreparedOptions.overflowBehavior;\r\n var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force);\r\n\r\n //dynWidth:\r\n var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth;\r\n var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth);\r\n\r\n //dynHeight:\r\n var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight;\r\n var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight);\r\n\r\n //scrollbars visibility\r\n _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n';\r\n _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's';\r\n _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm';\r\n _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l';\r\n\r\n //scrollbars autoHideDelay\r\n _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay;\r\n\r\n //old className\r\n _oldClassName = _classNameCache;\r\n\r\n //resize\r\n _resizeNone = resize === 'n';\r\n _resizeBoth = resize === 'b';\r\n _resizeHorizontal = resize === 'h';\r\n _resizeVertical = resize === 'v';\r\n\r\n //normalizeRTL\r\n _normalizeRTLCache = _currentPreparedOptions.normalizeRTL;\r\n\r\n //ignore overlay scrollbar hiding\r\n ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y);\r\n\r\n //refresh options cache\r\n _scrollbarsVisibilityCache = scrollbarsVisibility;\r\n _scrollbarsAutoHideCache = scrollbarsAutoHide;\r\n _scrollbarsClickScrollingCache = scrollbarsClickScrolling;\r\n _scrollbarsDragScrollingCache = scrollbarsDragScrolling;\r\n _classNameCache = className;\r\n _resizeCache = resize;\r\n _paddingAbsoluteCache = paddingAbsolute;\r\n _clipAlwaysCache = clipAlways;\r\n _sizeAutoCapableCache = sizeAutoCapable;\r\n _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding;\r\n _autoUpdateCache = autoUpdate;\r\n _overflowBehaviorCache = extendDeep({}, overflowBehavior);\r\n _textareaDynWidthCache = textareaDynWidth;\r\n _textareaDynHeightCache = textareaDynHeight;\r\n _hasOverflowCache = _hasOverflowCache || { x: false, y: false };\r\n\r\n //set correct class name to the host element\r\n if (classNameChanged) {\r\n removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone);\r\n addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone);\r\n }\r\n\r\n //set correct auto Update\r\n if (autoUpdateChanged) {\r\n if (autoUpdate === true || (autoUpdate === null && _autoUpdateRecommended)) {\r\n disconnectMutationObservers();\r\n autoUpdateLoop.add(_base);\r\n }\r\n else {\r\n autoUpdateLoop.remove(_base);\r\n connectMutationObservers();\r\n }\r\n }\r\n\r\n //activate or deactivate size auto capability\r\n if (sizeAutoCapableChanged) {\r\n if (sizeAutoCapable) {\r\n if (_contentGlueElement) {\r\n _contentGlueElement.show();\r\n }\r\n else {\r\n _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement));\r\n _paddingElement.before(_contentGlueElement);\r\n }\r\n if (_sizeAutoObserverAdded) {\r\n _sizeAutoObserverElement.show();\r\n }\r\n else {\r\n _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement));\r\n _sizeAutoObserverElementNative = _sizeAutoObserverElement[0];\r\n\r\n _contentGlueElement.before(_sizeAutoObserverElement);\r\n var oldSize = { w: -1, h: -1 };\r\n setupResizeObserver(_sizeAutoObserverElement, function () {\r\n var newSize = {\r\n w: _sizeAutoObserverElementNative[LEXICON.oW],\r\n h: _sizeAutoObserverElementNative[LEXICON.oH]\r\n };\r\n if (checkCache(newSize, oldSize)) {\r\n if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) {\r\n update();\r\n }\r\n else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) {\r\n update();\r\n }\r\n }\r\n oldSize = newSize;\r\n });\r\n _sizeAutoObserverAdded = true;\r\n //fix heightAuto detector bug if height is fixed but contentHeight is 0.\r\n //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8.\r\n if (_cssCalc !== null)\r\n _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)');\r\n }\r\n }\r\n else {\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.hide();\r\n if (_contentGlueElement)\r\n _contentGlueElement.hide();\r\n }\r\n }\r\n\r\n //if force, update all resizeObservers too\r\n if (force) {\r\n _sizeObserverElement.find('*').trigger(_strScroll);\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.find('*').trigger(_strScroll);\r\n }\r\n\r\n //display hidden:\r\n displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden;\r\n\r\n //textarea AutoWrapping:\r\n var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false;\r\n var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache);\r\n\r\n //detect direction:\r\n var cssDirection = _hostElement.css('direction');\r\n var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache);\r\n\r\n //detect box-sizing:\r\n var boxSizing = _hostElement.css('box-sizing');\r\n var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache);\r\n\r\n //detect padding:\r\n var padding = getTopRightBottomLeftHost(_strPaddingMinus);\r\n\r\n //width + height auto detecting var:\r\n var sizeAutoObserverElementBCRect;\r\n //exception occurs in IE8 sometimes (unknown exception)\r\n try {\r\n sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null;\r\n } catch (ex) {\r\n return;\r\n }\r\n\r\n _isRTL = cssDirection === 'rtl';\r\n _isBorderBox = (boxSizing === 'border-box');\r\n var isRTLLeft = _isRTL ? _strLeft : _strRight;\r\n var isRTLRight = _isRTL ? _strRight : _strLeft;\r\n\r\n //detect width auto:\r\n var widthAutoResizeDetection = false;\r\n var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false;\r\n if (sizeAutoCapable && !widthAutoObserverDetection) {\r\n var tmpCurrHostWidth = _hostElementNative[LEXICON.oW];\r\n var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth);\r\n _contentGlueElement.css(_strWidth, _strAuto);\r\n\r\n var tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n if (!widthAutoResizeDetection) {\r\n _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1);\r\n tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n }\r\n }\r\n var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden;\r\n var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache);\r\n var wasWidthAuto = !widthAuto && _widthAutoCache;\r\n\r\n //detect height auto:\r\n var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false;\r\n var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache);\r\n var wasHeightAuto = !heightAuto && _heightAutoCache;\r\n\r\n //detect border:\r\n //we need the border only if border box and auto size\r\n var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox;\r\n var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox;\r\n var border = getTopRightBottomLeftHost(_strBorderMinus, '-' + _strWidth, !updateBorderX, !updateBorderY)\r\n\r\n //detect margin:\r\n var margin = getTopRightBottomLeftHost(_strMarginMinus);\r\n\r\n //vars to apply correct css\r\n var contentElementCSS = {};\r\n var contentGlueElementCSS = {};\r\n\r\n //funcs\r\n var getHostSize = function () {\r\n //has to be clientSize because offsetSize respect borders\r\n return {\r\n w: _hostElementNative[LEXICON.cW],\r\n h: _hostElementNative[LEXICON.cH]\r\n };\r\n };\r\n var getViewportSize = function () {\r\n //viewport size is padding container because it never has padding, margin and a border\r\n //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height\r\n //if this happens add the difference to the viewportSize to compensate the rounding error\r\n return {\r\n w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]),\r\n h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH])\r\n };\r\n };\r\n\r\n //set info for padding\r\n var paddingAbsoluteX = _paddingX = padding.l + padding.r;\r\n var paddingAbsoluteY = _paddingY = padding.t + padding.b;\r\n paddingAbsoluteX *= paddingAbsolute ? 1 : 0;\r\n paddingAbsoluteY *= paddingAbsolute ? 1 : 0;\r\n padding.c = checkCacheAutoForce(padding, _cssPaddingCache);\r\n\r\n //set info for border\r\n _borderX = border.l + border.r;\r\n _borderY = border.t + border.b;\r\n border.c = checkCacheAutoForce(border, _cssBorderCache);\r\n\r\n //set info for margin\r\n _marginX = margin.l + margin.r;\r\n _marginY = margin.t + margin.b;\r\n margin.c = checkCacheAutoForce(margin, _cssMarginCache);\r\n\r\n //refresh cache\r\n _textareaAutoWrappingCache = textareaAutoWrapping;\r\n _cssDirectionCache = cssDirection;\r\n _cssBoxSizingCache = boxSizing;\r\n _widthAutoCache = widthAuto;\r\n _heightAutoCache = heightAuto;\r\n _cssPaddingCache = padding;\r\n _cssBorderCache = border;\r\n _cssMarginCache = margin;\r\n\r\n //IEFix direction changed\r\n if (cssDirectionChanged && _sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.css(_strFloat, isRTLRight);\r\n\r\n //apply padding:\r\n if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) {\r\n var paddingElementCSS = {};\r\n var textareaCSS = {};\r\n var paddingValues = [padding.t, padding.r, padding.b, padding.l];\r\n\r\n setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]);\r\n if (paddingAbsolute) {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty, paddingValues);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus);\r\n }\r\n else {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus, paddingValues);\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _targetElement.css(textareaCSS);\r\n }\r\n\r\n //viewport size is padding container because it never has padding, margin and a border.\r\n _viewportSize = getViewportSize();\r\n\r\n //update Textarea\r\n var textareaSize = _isTextarea ? textareaUpdate() : false;\r\n var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache);\r\n var textareaDynOrigSize = _isTextarea && textareaSize ? {\r\n w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth,\r\n h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight\r\n } : {};\r\n _textareaSizeCache = textareaSize;\r\n\r\n //fix height auto / width auto in cooperation with current padding & boxSizing behavior:\r\n if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c)) {\r\n contentElementCSS[_strHeight] = _strAuto;\r\n }\r\n else if (heightAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strHeight] = _strHundredPercent;\r\n }\r\n if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c || cssDirectionChanged)) {\r\n contentElementCSS[_strWidth] = _strAuto;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix\r\n }\r\n else if (widthAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n contentElementCSS[_strFloat] = _strEmpty;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix\r\n }\r\n if (widthAuto) {\r\n //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width\r\n contentGlueElementCSS[_strWidth] = _strAuto;\r\n\r\n contentElementCSS[_strWidth] = VENDORS._cssPropertyValue(_strWidth, 'max-content intrinsic') || _strAuto;\r\n contentElementCSS[_strFloat] = isRTLRight;\r\n }\r\n else {\r\n contentGlueElementCSS[_strWidth] = _strEmpty;\r\n }\r\n if (heightAuto) {\r\n //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping\r\n contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH];\r\n }\r\n else {\r\n contentGlueElementCSS[_strHeight] = _strEmpty;\r\n }\r\n if (sizeAutoCapable)\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n _contentElement.css(contentElementCSS);\r\n\r\n //CHECKPOINT HERE ~\r\n contentElementCSS = {};\r\n contentGlueElementCSS = {};\r\n\r\n //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true\r\n if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) {\r\n var strOverflow = 'overflow';\r\n var strOverflowX = strOverflow + '-x';\r\n var strOverflowY = strOverflow + '-y';\r\n var strHidden = 'hidden';\r\n var strVisible = 'visible';\r\n\r\n //Reset the viewport (very important for natively overlaid scrollbars and zoom change\r\n //don't change the overflow prop as it is very expensive and affects performance !A LOT!\r\n if (!_nativeScrollbarStyling) {\r\n var viewportElementResetCSS = {};\r\n var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0;\r\n var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0;\r\n setTopRightBottomLeft(viewportElementResetCSS, _strEmpty);\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n\r\n //measure several sizes:\r\n var contentMeasureElement = getContentMeasureElement();\r\n //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid\r\n var contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW],\r\n h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH]\r\n };\r\n var scrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH]\r\n };\r\n\r\n //apply the correct viewport style and measure viewport size\r\n if (!_nativeScrollbarStyling) {\r\n viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp;\r\n viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp;\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n _viewportSize = getViewportSize();\r\n\r\n //measure and correct several sizes\r\n var hostSize = getHostSize();\r\n var hostAbsoluteRectSize = {\r\n w: hostSize.w - _marginX - _borderX - (_isBorderBox ? 0 : _paddingX),\r\n h: hostSize.h - _marginY - _borderY - (_isBorderBox ? 0 : _paddingY)\r\n };\r\n var contentGlueSize = {\r\n //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually\r\n //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding\r\n w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostAbsoluteRectSize.w),\r\n h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostAbsoluteRectSize.h)\r\n };\r\n contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache);\r\n _contentGlueSizeCache = contentGlueSize;\r\n\r\n //apply correct contentGlue size\r\n if (sizeAutoCapable) {\r\n //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto\r\n if (contentGlueSize.c || (heightAuto || widthAuto)) {\r\n contentGlueElementCSS[_strWidth] = contentGlueSize.w;\r\n contentGlueElementCSS[_strHeight] = contentGlueSize.h;\r\n\r\n //textarea-sizes are already calculated correctly at this point\r\n if (!_isTextarea) {\r\n contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: contentMeasureElement[LEXICON.cW],\r\n h: contentMeasureElement[LEXICON.cH]\r\n };\r\n }\r\n }\r\n var textareaCoverCSS = {};\r\n var setContentGlueElementCSSfunction = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var wh = scrollbarVars._w_h;\r\n var strWH = scrollbarVars._width_height;\r\n var autoSize = horizontal ? widthAuto : heightAuto;\r\n var borderSize = horizontal ? _borderX : _borderY;\r\n var paddingSize = horizontal ? _paddingX : _paddingY;\r\n var marginSize = horizontal ? _marginX : _marginY;\r\n var viewportSize = _viewportSize[wh] - borderSize - marginSize - (_isBorderBox ? 0 : paddingSize);\r\n\r\n //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks\r\n if (!autoSize || (!autoSize && border.c))\r\n contentGlueElementCSS[strWH] = hostAbsoluteRectSize[wh] - 1;\r\n\r\n //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0)\r\n if (autoSize && (contentSize[wh] < viewportSize) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) {\r\n if (_isTextarea)\r\n textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1;\r\n contentGlueElementCSS[strWH] -= 1;\r\n }\r\n\r\n //make sure content glue size is at least 1\r\n if (contentSize[wh] > 0)\r\n contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]);\r\n };\r\n setContentGlueElementCSSfunction(true);\r\n setContentGlueElementCSSfunction(false);\r\n\r\n if (_isTextarea)\r\n _textareaCoverElement.css(textareaCoverCSS);\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n }\r\n if (widthAuto)\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n if (widthAuto && !_isBorderBox && !_mutationObserversConnected)\r\n contentElementCSS[_strFloat] = 'none';\r\n\r\n //apply and reset content style\r\n _contentElement.css(contentElementCSS);\r\n contentElementCSS = {};\r\n\r\n //measure again, but this time all correct sizes:\r\n var contentScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH],\r\n };\r\n contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache);\r\n _contentScrollSizeCache = contentScrollSize;\r\n\r\n //refresh viewport size after correct measuring\r\n _viewportSize = getViewportSize();\r\n\r\n hostSize = getHostSize();\r\n hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache);\r\n _hostSizeCache = hostSize;\r\n\r\n var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0);\r\n var previousOverflowAmount = _overflowAmountCache;\r\n var overflowBehaviorIsVS = {};\r\n var overflowBehaviorIsVH = {};\r\n var overflowBehaviorIsS = {};\r\n var overflowAmount = {};\r\n var hasOverflow = {};\r\n var hideOverflow = {};\r\n var canScroll = {};\r\n var viewportRect = _paddingElementNative[LEXICON.bCR]();\r\n var setOverflowVariables = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xyI = scrollbarVarsInverted._x_y;\r\n var xy = scrollbarVars._x_y;\r\n var wh = scrollbarVars._w_h;\r\n var widthHeight = scrollbarVars._width_height;\r\n var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max';\r\n var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0;\r\n var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0;\r\n overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s';\r\n overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h';\r\n overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's';\r\n overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100);\r\n overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1;\r\n hasOverflow[xy] = overflowAmount[xy] > 0;\r\n\r\n //hideOverflow:\r\n //x || y : true === overflow is hidden by \"overflow: scroll\" OR \"overflow: hidden\"\r\n //xs || ys : true === overflow is hidden by \"overflow: scroll\"\r\n hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy];\r\n hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false;\r\n\r\n canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's'];\r\n };\r\n setOverflowVariables(true);\r\n setOverflowVariables(false);\r\n\r\n overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache);\r\n _overflowAmountCache = overflowAmount;\r\n hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache);\r\n _hasOverflowCache = hasOverflow;\r\n hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache);\r\n _hideOverflowCache = hideOverflow;\r\n\r\n //if native scrollbar is overlay at x OR y axis, prepare DOM\r\n if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) {\r\n var borderDesign = 'px solid transparent';\r\n var contentArrangeElementCSS = {};\r\n var arrangeContent = {};\r\n var arrangeChanged = force;\r\n var setContentElementCSS;\r\n\r\n if (hasOverflow.x || hasOverflow.y) {\r\n arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty;\r\n arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty;\r\n arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache);\r\n _arrangeContentSizeCache = arrangeContent;\r\n }\r\n\r\n if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) {\r\n contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty;\r\n setContentElementCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n var invertedAutoSize = horizontal ? heightAuto : widthAuto;\r\n\r\n if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty;\r\n contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty;\r\n }\r\n else {\r\n arrangeContent[scrollbarVarsInverted._w_h] =\r\n contentElementCSS[_strMarginMinus + strDirection] =\r\n contentElementCSS[_strBorderMinus + strDirection] = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n };\r\n\r\n if (_nativeScrollbarStyling) {\r\n addRemoveClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible, !ignoreOverlayScrollbarHiding)\r\n }\r\n else {\r\n setContentElementCSS(true);\r\n setContentElementCSS(false);\r\n }\r\n }\r\n if (ignoreOverlayScrollbarHiding) {\r\n arrangeContent.w = arrangeContent.h = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n if (arrangeChanged && !_nativeScrollbarStyling) {\r\n contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty;\r\n contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty;\r\n\r\n if (!_contentArrangeElement) {\r\n _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement));\r\n _viewportElement.prepend(_contentArrangeElement);\r\n }\r\n _contentArrangeElement.css(contentArrangeElementCSS);\r\n }\r\n _contentElement.css(contentElementCSS);\r\n }\r\n\r\n var viewportElementCSS = {};\r\n var paddingElementCSS = {};\r\n var setViewportCSS;\r\n if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) {\r\n viewportElementCSS[isRTLRight] = _strEmpty;\r\n setViewportCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n\r\n var reset = function () {\r\n viewportElementCSS[strDirection] = _strEmpty;\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = 0;\r\n };\r\n if (hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n viewportElementCSS[strOverflow + XY] = _strScroll;\r\n if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) {\r\n reset();\r\n }\r\n else {\r\n viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]);\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0;\r\n }\r\n } else {\r\n viewportElementCSS[strOverflow + XY] = _strEmpty;\r\n reset();\r\n }\r\n };\r\n setViewportCSS(true);\r\n setViewportCSS(false);\r\n\r\n // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), \r\n // make viewport element greater in size (Firefox hide Scrollbars fix)\r\n // because firefox starts hiding scrollbars on too small elements\r\n // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly\r\n // https://bugzilla.mozilla.org/show_bug.cgi?id=292284\r\n if (!_nativeScrollbarStyling\r\n && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y)\r\n && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) {\r\n viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x;\r\n viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x;\r\n\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y;\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y;\r\n }\r\n else {\r\n viewportElementCSS[_strPaddingMinus + _strTop] =\r\n viewportElementCSS[_strMarginMinus + _strTop] =\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] =\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty;\r\n }\r\n viewportElementCSS[_strPaddingMinus + isRTLLeft] =\r\n viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty;\r\n\r\n //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible\r\n if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) {\r\n //only hide if is Textarea\r\n if (_isTextarea && hideOverflowForceTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = strHidden;\r\n }\r\n }\r\n else {\r\n if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) {\r\n //only un-hide if Textarea\r\n if (_isTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = _strEmpty;\r\n }\r\n viewportElementCSS[strOverflowX] =\r\n viewportElementCSS[strOverflowY] = strVisible;\r\n }\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _viewportElement.css(viewportElementCSS);\r\n viewportElementCSS = {};\r\n\r\n //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions\r\n if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n var elementStyle = _contentElementNative[LEXICON.s];\r\n var dump;\r\n elementStyle.webkitTransform = 'scale(1)';\r\n elementStyle.display = 'run-in';\r\n dump = _contentElementNative[LEXICON.oH];\r\n elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify\r\n elementStyle.webkitTransform = _strEmpty;\r\n }\r\n /*\r\n //force hard redraw in webkit if native overlaid scrollbars shall appear\r\n if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) {\r\n _hostElement.hide();\r\n var dump = _hostElementNative[LEXICON.oH];\r\n _hostElement.show();\r\n }\r\n */\r\n }\r\n\r\n //change to direction RTL and width auto Bugfix in Webkit\r\n //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left\r\n contentElementCSS = {};\r\n if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) {\r\n if (_isRTL && widthAuto) {\r\n var floatTmp = _contentElement.css(_strFloat);\r\n var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left);\r\n _contentElement.css(_strFloat, floatTmp);\r\n var posLeftWithFloat = MATH.round(_contentElement.position().left);\r\n\r\n if (posLeftWithoutFloat !== posLeftWithFloat)\r\n contentElementCSS[_strLeft] = posLeftWithoutFloat;\r\n }\r\n else {\r\n contentElementCSS[_strLeft] = _strEmpty;\r\n }\r\n }\r\n _contentElement.css(contentElementCSS);\r\n\r\n //handle scroll position\r\n if (_isTextarea && contentSizeChanged) {\r\n var textareaInfo = getTextareaInfo();\r\n if (textareaInfo) {\r\n var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows;\r\n var cursorRow = textareaInfo._cursorRow;\r\n var cursorCol = textareaInfo._cursorColumn;\r\n var widestRow = textareaInfo._widestRow;\r\n var lastRow = textareaInfo._rows;\r\n var lastCol = textareaInfo._columns;\r\n var cursorPos = textareaInfo._cursorPosition;\r\n var cursorMax = textareaInfo._cursorMax;\r\n var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus);\r\n var textareaScrollAmount = {\r\n x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1,\r\n y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1\r\n };\r\n currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset.\r\n currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y;\r\n }\r\n _textareaInfoCache = textareaInfo;\r\n }\r\n if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache)\r\n currScroll.x += _contentBorderSize.w || 0;\r\n if (widthAuto)\r\n _hostElement[_strScrollLeft](0);\r\n if (heightAuto)\r\n _hostElement[_strScrollTop](0);\r\n _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y);\r\n\r\n //scrollbars management:\r\n var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v';\r\n var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h';\r\n var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a';\r\n var refreshScrollbarsVisibility = function (showX, showY) {\r\n showY = showY === undefined ? showX : showY;\r\n refreshScrollbarAppearance(true, showX, canScroll.x)\r\n refreshScrollbarAppearance(false, showY, canScroll.y)\r\n };\r\n\r\n //manage class name which indicates scrollable overflow\r\n addRemoveClass(_hostElement, _classNameHostOverflow, hideOverflow.x || hideOverflow.y);\r\n addRemoveClass(_hostElement, _classNameHostOverflowX, hideOverflow.x);\r\n addRemoveClass(_hostElement, _classNameHostOverflowY, hideOverflow.y);\r\n\r\n //add or remove rtl class name for styling purposes except when its body, then the scrollbar stays\r\n if (cssDirectionChanged && !_isBody) {\r\n addRemoveClass(_hostElement, _classNameHostRTL, _isRTL);\r\n }\r\n\r\n //manage the resize feature (CSS3 resize \"polyfill\" for this plugin)\r\n if (_isBody)\r\n addClass(_hostElement, _classNameHostResizeDisabled);\r\n if (resizeChanged) {\r\n addRemoveClass(_hostElement, _classNameHostResizeDisabled, _resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResize, !_resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB, _resizeBoth);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH, _resizeHorizontal);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV, _resizeVertical);\r\n }\r\n\r\n //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name)\r\n if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) {\r\n if (ignoreOverlayScrollbarHiding) {\r\n if (ignoreOverlayScrollbarHidingChanged) {\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n if (ignoreOverlayScrollbarHiding) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n }\r\n else if (scrollbarsVisibilityAuto) {\r\n refreshScrollbarsVisibility(canScroll.x, canScroll.y);\r\n }\r\n else if (scrollbarsVisibilityVisible) {\r\n refreshScrollbarsVisibility(true);\r\n }\r\n else if (scrollbarsVisibilityHidden) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n\r\n //manage the scrollbars auto hide feature (auto hide them after specific actions)\r\n if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) {\r\n setupHostMouseTouchEvents(!_scrollbarsAutoHideLeave && !_scrollbarsAutoHideMove);\r\n refreshScrollbarsAutoHide(_scrollbarsAutoHideNever, !_scrollbarsAutoHideNever);\r\n }\r\n\r\n //manage scrollbars handle length & offset - don't remove!\r\n if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) {\r\n refreshScrollbarHandleLength(true);\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleLength(false);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n\r\n //manage interactivity\r\n if (scrollbarsClickScrollingChanged)\r\n refreshScrollbarsInteractive(true, scrollbarsClickScrolling);\r\n if (scrollbarsDragScrollingChanged)\r\n refreshScrollbarsInteractive(false, scrollbarsDragScrolling);\r\n\r\n //callbacks:\r\n dispatchCallback('onDirectionChanged', {\r\n isRTL: _isRTL,\r\n dir: cssDirection\r\n }, cssDirectionChanged);\r\n dispatchCallback('onHostSizeChanged', {\r\n width: _hostSizeCache.w,\r\n height: _hostSizeCache.h\r\n }, hostSizeChanged);\r\n dispatchCallback('onContentSizeChanged', {\r\n width: _contentScrollSizeCache.w,\r\n height: _contentScrollSizeCache.h\r\n }, contentSizeChanged);\r\n dispatchCallback('onOverflowChanged', {\r\n x: hasOverflow.x,\r\n y: hasOverflow.y,\r\n xScrollable: hideOverflow.xs,\r\n yScrollable: hideOverflow.ys,\r\n clipped: hideOverflow.x || hideOverflow.y\r\n }, hasOverflow.c || hideOverflow.c);\r\n dispatchCallback('onOverflowAmountChanged', {\r\n x: overflowAmount.x,\r\n y: overflowAmount.y\r\n }, overflowAmount.c);\r\n }\r\n\r\n //fix body min size\r\n if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) {\r\n //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size.\r\n if (!_bodyMinSizeCache.f)\r\n bodyMinSizeChanged();\r\n if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x)\r\n _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y);\r\n if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y)\r\n _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x);\r\n _bodyMinSizeCache.c = false;\r\n }\r\n\r\n if (_initialized && changedOptions.updateOnLoad) {\r\n updateElementsOnLoad();\r\n }\r\n\r\n //freezeResizeObserver(_sizeObserverElement, false);\r\n //freezeResizeObserver(_sizeAutoObserverElement, false);\r\n\r\n dispatchCallback('onUpdated', { forced: force });\r\n }\r\n\r\n /**\r\n * Updates the found elements of which the load event shall be handled.\r\n */\r\n function updateElementsOnLoad() {\r\n if (!_isTextarea) {\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n _contentElement.find(updateOnLoadSelector).each(function (i, el) {\r\n // if element doesn't have a updateOnLoadCallback applied\r\n if (COMPATIBILITY.inA(el, _updateOnLoadElms) < 0) {\r\n _updateOnLoadElms.push(el);\r\n FRAMEWORK(el)\r\n .off(_updateOnLoadEventName, updateOnLoadCallback)\r\n .on(_updateOnLoadEventName, updateOnLoadCallback);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n //==== Options ====//\r\n\r\n /**\r\n * Sets new options but doesn't call the update method.\r\n * @param newOptions The object which contains the new options.\r\n * @returns {*} A object which contains the changed options.\r\n */\r\n function setOptions(newOptions) {\r\n var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions)\r\n\r\n _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default);\r\n _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared);\r\n\r\n return validatedOpts._prepared;\r\n }\r\n\r\n\r\n //==== Structure ====//\r\n\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupStructureDOM(destroy) {\r\n var strParent = 'parent';\r\n var classNameResizeObserverHost = 'os-resize-observer-host';\r\n var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit;\r\n var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty;\r\n var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs;\r\n var adoptAttrsMap = {};\r\n var applyAdoptedAttrs = function () {\r\n var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement;\r\n each(adoptAttrsMap, function (key, value) {\r\n if (type(value) == TYPES.s) {\r\n if (key == LEXICON.c)\r\n applyAdoptedAttrsElm.addClass(value);\r\n else\r\n applyAdoptedAttrsElm.attr(key, value);\r\n }\r\n });\r\n };\r\n var hostElementClassNames = [\r\n _classNameHostElement,\r\n _classNameHostElementForeign,\r\n _classNameHostTextareaElement,\r\n _classNameHostResizeDisabled,\r\n _classNameHostRTL,\r\n _classNameHostScrollbarHorizontalHidden,\r\n _classNameHostScrollbarVerticalHidden,\r\n _classNameHostTransition,\r\n _classNameHostScrolling,\r\n _classNameHostOverflow,\r\n _classNameHostOverflowX,\r\n _classNameHostOverflowY,\r\n _classNameThemeNone,\r\n _classNameTextareaElement,\r\n _classNameTextInherit,\r\n _classNameCache].join(_strSpace);\r\n var hostElementCSS = {};\r\n\r\n //get host element as first element, because that's the most upper element and required for the other elements\r\n _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement);\r\n _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass);\r\n _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass);\r\n _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass);\r\n _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost);\r\n _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined);\r\n\r\n //add this class to workaround class changing issues with UI frameworks especially Vue\r\n if (_domExists)\r\n addClass(_hostElement, _classNameHostElementForeign);\r\n\r\n //on destroy, remove all generated class names from the host element before collecting the adopted attributes \r\n //to prevent adopting generated class names\r\n if (destroy)\r\n removeClass(_hostElement, hostElementClassNames);\r\n\r\n //collect all adopted attributes\r\n adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs;\r\n if (COMPATIBILITY.isA(adoptAttrs) && _isTextarea) {\r\n each(adoptAttrs, function (i, v) {\r\n if (type(v) == TYPES.s) {\r\n adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v);\r\n }\r\n });\r\n }\r\n\r\n if (!destroy) {\r\n if (_isTextarea) {\r\n if (!_currentPreparedOptions.sizeAutoCapable) {\r\n hostElementCSS[_strWidth] = _targetElement.css(_strWidth);\r\n hostElementCSS[_strHeight] = _targetElement.css(_strHeight);\r\n }\r\n\r\n if (!_domExists)\r\n _targetElement.addClass(_classNameTextInherit).wrap(_hostElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _hostElement = _targetElement[strParent]().css(hostElementCSS);\r\n }\r\n\r\n if (!_domExists) {\r\n //add the correct class to the target element\r\n addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement);\r\n\r\n //wrap the content into the generated elements to create the required DOM\r\n _hostElement.wrapInner(_contentElement)\r\n .wrapInner(_viewportElement)\r\n .wrapInner(_paddingElement)\r\n .prepend(_sizeObserverElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement);\r\n _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement);\r\n _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement);\r\n\r\n if (_isTextarea) {\r\n _contentElement.prepend(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_nativeScrollbarStyling)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible);\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid);\r\n if (_isBody)\r\n addClass(_htmlElement, _classNameHTMLElement);\r\n\r\n _sizeObserverElementNative = _sizeObserverElement[0];\r\n _hostElementNative = _hostElement[0];\r\n _paddingElementNative = _paddingElement[0];\r\n _viewportElementNative = _viewportElement[0];\r\n _contentElementNative = _contentElement[0];\r\n\r\n updateViewportAttrsFromTarget();\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n //clear size observer\r\n _sizeObserverElement.children().remove();\r\n\r\n //remove the style property and classes from already generated elements\r\n each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) {\r\n if (elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n });\r\n\r\n //add classes to the host element which was removed previously to match the expected DOM\r\n addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement);\r\n }\r\n else {\r\n //remove size observer\r\n remove(_sizeObserverElement);\r\n\r\n //unwrap the content to restore DOM\r\n _contentElement.contents()\r\n .unwrap()\r\n .unwrap()\r\n .unwrap();\r\n\r\n if (_isTextarea) {\r\n _targetElement.unwrap();\r\n remove(_hostElement);\r\n remove(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_isTextarea)\r\n _targetElement.removeAttr(LEXICON.s);\r\n\r\n if (_isBody)\r\n removeClass(_htmlElement, _classNameHTMLElement);\r\n }\r\n }\r\n\r\n /**\r\n * Adds or removes all wrapper elements interactivity events.\r\n * @param destroy Indicates whether the Events shall be added or removed.\r\n */\r\n function setupStructureEvents() {\r\n var textareaKeyDownRestrictedKeyCodes = [\r\n 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12\r\n 33, 34, //page up, page down\r\n 37, 38, 39, 40, //left, up, right, down arrows\r\n 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock\r\n ];\r\n var textareaKeyDownKeyCodesList = [];\r\n var textareaUpdateIntervalID;\r\n var scrollStopTimeoutId;\r\n var scrollStopDelay = 175;\r\n var strFocus = 'focus';\r\n\r\n function updateTextarea(doClearInterval) {\r\n textareaUpdate();\r\n _base.update(_strAuto);\r\n if (doClearInterval && _autoUpdateRecommended)\r\n clearInterval(textareaUpdateIntervalID);\r\n }\r\n function textareaOnScroll(event) {\r\n _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0);\r\n _targetElement[_strScrollTop](0);\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n }\r\n function textareaOnDrop(event) {\r\n setTimeout(function () {\r\n if (!_destroyed)\r\n updateTextarea();\r\n }, 50);\r\n }\r\n function textareaOnFocus() {\r\n _textareaHasFocus = true;\r\n addClass(_hostElement, strFocus);\r\n }\r\n function textareaOnFocusout() {\r\n _textareaHasFocus = false;\r\n textareaKeyDownKeyCodesList = [];\r\n removeClass(_hostElement, strFocus);\r\n updateTextarea(true);\r\n }\r\n function textareaOnKeyDown(event) {\r\n var keyCode = event.keyCode;\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l]) {\r\n updateTextarea();\r\n textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60);\r\n }\r\n if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0)\r\n textareaKeyDownKeyCodesList.push(keyCode);\r\n }\r\n }\r\n function textareaOnKeyUp(event) {\r\n var keyCode = event.keyCode;\r\n var index = inArray(keyCode, textareaKeyDownKeyCodesList);\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (index > -1)\r\n textareaKeyDownKeyCodesList.splice(index, 1);\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l])\r\n updateTextarea(true);\r\n }\r\n }\r\n function contentOnTransitionEnd(event) {\r\n if (_autoUpdateCache === true)\r\n return;\r\n event = event.originalEvent || event;\r\n if (isSizeAffectingCSSProperty(event.propertyName))\r\n _base.update(_strAuto);\r\n }\r\n function viewportOnScroll(event) {\r\n if (!_sleeping) {\r\n if (scrollStopTimeoutId !== undefined)\r\n clearTimeout(scrollStopTimeoutId);\r\n else {\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n addClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStart', event);\r\n }\r\n\r\n //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset\r\n //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point\r\n //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove\r\n if (!_scrollbarsHandlesDefineScrollPos) {\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n dispatchCallback('onScroll', event);\r\n\r\n scrollStopTimeoutId = setTimeout(function () {\r\n if (!_destroyed) {\r\n //OnScrollStop:\r\n clearTimeout(scrollStopTimeoutId);\r\n scrollStopTimeoutId = undefined;\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStop', event);\r\n }\r\n }, scrollStopDelay);\r\n }\r\n }\r\n\r\n\r\n if (_isTextarea) {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n addDestroyEventListener(_targetElement, 'input', updateTextarea);\r\n }\r\n else {\r\n addDestroyEventListener(_targetElement,\r\n [_strKeyDownEvent, _strKeyUpEvent],\r\n [textareaOnKeyDown, textareaOnKeyUp]);\r\n }\r\n\r\n addDestroyEventListener(_targetElement,\r\n [_strScroll, 'drop', strFocus, strFocus + 'out'],\r\n [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]);\r\n }\r\n else {\r\n addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd);\r\n }\r\n addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true);\r\n }\r\n\r\n\r\n //==== Scrollbars ====//\r\n\r\n /**\r\n * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle)\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarsDOM(destroy) {\r\n var selectOrGenerateScrollbarDOM = function (isHorizontal) {\r\n var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical;\r\n var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true);\r\n var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar);\r\n var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar);\r\n\r\n if (!_domExists && !destroy) {\r\n scrollbar.append(track);\r\n track.append(handle);\r\n }\r\n\r\n return {\r\n _scrollbar: scrollbar,\r\n _track: track,\r\n _handle: handle\r\n };\r\n };\r\n function resetScrollbarDOM(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbar = scrollbarVars._scrollbar;\r\n var track = scrollbarVars._track;\r\n var handle = scrollbarVars._handle;\r\n\r\n if (_domExists && _initialized) {\r\n each([scrollbar, track, handle], function (i, elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n });\r\n }\r\n else {\r\n remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar);\r\n }\r\n }\r\n var horizontalElements;\r\n var verticalElements;\r\n\r\n if (!destroy) {\r\n horizontalElements = selectOrGenerateScrollbarDOM(true);\r\n verticalElements = selectOrGenerateScrollbarDOM();\r\n\r\n _scrollbarHorizontalElement = horizontalElements._scrollbar;\r\n _scrollbarHorizontalTrackElement = horizontalElements._track;\r\n _scrollbarHorizontalHandleElement = horizontalElements._handle;\r\n _scrollbarVerticalElement = verticalElements._scrollbar;\r\n _scrollbarVerticalTrackElement = verticalElements._track;\r\n _scrollbarVerticalHandleElement = verticalElements._handle;\r\n\r\n if (!_domExists) {\r\n _paddingElement.after(_scrollbarVerticalElement);\r\n _paddingElement.after(_scrollbarHorizontalElement);\r\n }\r\n }\r\n else {\r\n resetScrollbarDOM(true);\r\n resetScrollbarDOM();\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling)\r\n * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar.\r\n */\r\n function setupScrollbarEvents(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var scroll = _strScroll + scrollbarVars._Left_Top;\r\n var strActive = 'active';\r\n var strSnapHandle = 'snapHandle';\r\n var strClickEvent = 'click';\r\n var scrollDurationFactor = 1;\r\n var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl\r\n var trackTimeout;\r\n var mouseDownScroll;\r\n var mouseDownOffset;\r\n var mouseDownInvertedScale;\r\n\r\n function getPointerPosition(event) {\r\n return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames.\r\n }\r\n function getPreparedScrollbarsOption(name) {\r\n return _currentPreparedOptions.scrollbars[name];\r\n }\r\n function increaseTrackScrollAmount() {\r\n scrollDurationFactor = 0.5;\r\n }\r\n function decreaseTrackScrollAmount() {\r\n scrollDurationFactor = 1;\r\n }\r\n function stopClickEventPropagation(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function documentKeyDown(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n increaseTrackScrollAmount();\r\n }\r\n function documentKeyUp(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n decreaseTrackScrollAmount();\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale;\r\n var scrollDeltaPercent = scrollRaw / (trackLength - handleLength);\r\n var scrollDelta = (scrollRange * scrollDeltaPercent);\r\n scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.i)\r\n scrollDelta *= -1;\r\n\r\n _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta));\r\n\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta);\r\n\r\n if (!_supportPassiveEvents)\r\n COMPATIBILITY.prvD(event);\r\n }\r\n else\r\n documentMouseTouchUp(event);\r\n }\r\n function documentMouseTouchUp(event) {\r\n event = event || event.originalEvent;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart],\r\n true);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, true, { _capture: true });\r\n });\r\n \r\n \r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, true);\r\n\r\n _scrollbarsHandlesDefineScrollPos = false;\r\n removeClass(_bodyElement, _classNameDragging);\r\n removeClass(scrollbarVars._handle, strActive);\r\n removeClass(scrollbarVars._track, strActive);\r\n removeClass(scrollbarVars._scrollbar, strActive);\r\n\r\n mouseDownScroll = undefined;\r\n mouseDownOffset = undefined;\r\n mouseDownInvertedScale = 1;\r\n\r\n decreaseTrackScrollAmount();\r\n\r\n if (trackTimeout !== undefined) {\r\n _base.scrollStop();\r\n clearTimeout(trackTimeout);\r\n trackTimeout = undefined;\r\n }\r\n\r\n if (event) {\r\n var rect = _hostElementNative[LEXICON.bCR]();\r\n var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;\r\n\r\n //if mouse is outside host element\r\n if (!mouseInsideHost)\r\n hostOnMouseLeave();\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n }\r\n function onHandleMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event))\r\n onHandleMouseTouchDownAction(event);\r\n }\r\n function onHandleMouseTouchDownAction(event) {\r\n mouseDownScroll = _viewportElement[scroll]();\r\n mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL)\r\n mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll;\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = getPointerPosition(event);\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._handle, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentOnSelectStart]);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, false, { _capture: true });\r\n });\r\n \r\n\r\n if (_msieVersion || !_documentMixed)\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function onTrackMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var handleToViewportRatio = scrollbarVars._info._handleLength / Math.round(MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]) * scrollbarVars._info._trackLength);\r\n var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h] * handleToViewportRatio);\r\n var scrollBaseDuration = 270 * handleToViewportRatio;\r\n var scrollFirstIterationDelay = 400 * handleToViewportRatio;\r\n var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top];\r\n var ctrlKey = event.ctrlKey;\r\n var instantScroll = event.shiftKey;\r\n var instantScrollTransition = instantScroll && ctrlKey;\r\n var isFirstIteration = true;\r\n var easing = 'linear';\r\n var decreaseScroll;\r\n var finishedCondition;\r\n var scrollActionFinsished = function (transition) {\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, transition);\r\n };\r\n var scrollActionInstantFinished = function () {\r\n scrollActionFinsished();\r\n onHandleMouseTouchDownAction(event);\r\n };\r\n var scrollAction = function () {\r\n if (!_destroyed) {\r\n var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale;\r\n var handleOffset = scrollbarVarsInfo._handleOffset;\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var currScroll = scrollbarVarsInfo._currentScroll;\r\n var scrollDuration = scrollBaseDuration * scrollDurationFactor;\r\n var timeoutDelay = isFirstIteration ? MATH.max(scrollFirstIterationDelay, scrollDuration) : scrollDuration;\r\n var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent\r\n var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache);\r\n var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset;\r\n var scrollObj = {};\r\n var animationObj = {\r\n easing: easing,\r\n step: function (now) {\r\n if (_scrollbarsHandlesDefineScrollPos) {\r\n _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340\r\n refreshScrollbarHandleOffset(isHorizontal, now);\r\n }\r\n }\r\n };\r\n instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0;\r\n instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n\r\n //_base.scrollStop();\r\n\r\n if (instantScroll) {\r\n _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position\r\n if (instantScrollTransition) {\r\n //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position\r\n //and the animation stops at the correct point\r\n instantScrollPosition = _viewportElement[scroll]();\r\n //scroll back to the position before instant scrolling so animation can be performed\r\n _viewportElement[scroll](currScroll);\r\n\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition;\r\n\r\n scrollObj[xy] = instantScrollPosition;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: 130,\r\n complete: scrollActionInstantFinished\r\n }));\r\n }\r\n else\r\n scrollActionInstantFinished();\r\n }\r\n else {\r\n decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll;\r\n finishedCondition = rtlIsNormal\r\n ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset)\r\n : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset);\r\n\r\n if (finishedCondition) {\r\n clearTimeout(trackTimeout);\r\n _base.scrollStop();\r\n trackTimeout = undefined;\r\n scrollActionFinsished(true);\r\n }\r\n else {\r\n trackTimeout = setTimeout(scrollAction, timeoutDelay);\r\n\r\n scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: scrollDuration\r\n }));\r\n }\r\n isFirstIteration = false;\r\n }\r\n }\r\n };\r\n if (ctrlKey)\r\n increaseTrackScrollAmount();\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = COMPATIBILITY.page(event)[xy];\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._track, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]);\r\n\r\n scrollAction();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n }\r\n function onTrackMouseTouchEnter(event) {\r\n //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is \"scroll\" or \"move\".\r\n _scrollbarsHandleHovered = true;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n function onTrackMouseTouchLeave(event) {\r\n _scrollbarsHandleHovered = false;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n function onScrollbarMouseTouchDown(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n\r\n addDestroyEventListener(scrollbarVars._handle,\r\n _strMouseTouchDownEvent,\r\n onHandleMouseTouchDown);\r\n addDestroyEventListener(scrollbarVars._track,\r\n [_strMouseTouchDownEvent, _strMouseEnter, _strMouseLeave],\r\n [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]);\r\n addDestroyEventListener(scrollbarVars._scrollbar,\r\n _strMouseTouchDownEvent,\r\n onScrollbarMouseTouchDown);\r\n\r\n if (_supportTransition) {\r\n addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) {\r\n if (event.target !== scrollbarVars._scrollbar[0])\r\n return;\r\n refreshScrollbarHandleLength(isHorizontal);\r\n refreshScrollbarHandleOffset(isHorizontal);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not.\r\n * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target.\r\n * @param shallBeVisible True if the scrollbar shall be shown, false if hidden.\r\n * @param canScroll True if the scrollbar is scrollable, false otherwise.\r\n */\r\n function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) {\r\n var scrollbarHiddenClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden;\r\n var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement;\r\n\r\n addRemoveClass(_hostElement, scrollbarHiddenClassName, !shallBeVisible);\r\n addRemoveClass(scrollbarElement, _classNameScrollbarUnusable, !canScroll);\r\n }\r\n\r\n /**\r\n * Autoshows / autohides both scrollbars with.\r\n * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden.\r\n * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise.\r\n */\r\n function refreshScrollbarsAutoHide(shallBeVisible, delayfree) {\r\n clearTimeout(_scrollbarsAutoHideTimeoutId);\r\n if (shallBeVisible) {\r\n //if(_hasOverflowCache.x && _hideOverflowCache.xs)\r\n removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n //if(_hasOverflowCache.y && _hideOverflowCache.ys)\r\n removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n else {\r\n var anyActive;\r\n var strActive = 'active';\r\n var hide = function () {\r\n if (!_scrollbarsHandleHovered && !_destroyed) {\r\n anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n };\r\n if (_scrollbarsAutoHideDelay > 0 && delayfree !== true)\r\n _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay);\r\n else\r\n hide();\r\n }\r\n }\r\n\r\n /**\r\n * Refreshes the handle length of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n */\r\n function refreshScrollbarHandleLength(isHorizontal) {\r\n var handleCSS = {};\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var digit = 1000000;\r\n //get and apply intended handle length\r\n var handleRatio = MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]);\r\n handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //measure the handle length to respect min & max length\r\n scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height];\r\n scrollbarVarsInfo._handleLengthRatio = handleRatio;\r\n }\r\n\r\n /**\r\n * Refreshes the handle offset of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop)\r\n */\r\n function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) {\r\n var transition = type(scrollOrTransition) == TYPES.b;\r\n var transitionDuration = 250;\r\n var isRTLisHorizontal = _isRTL && isHorizontal;\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var strTranslateBrace = 'translate(';\r\n var strTransform = VENDORS._cssProperty('transform');\r\n var strTransition = VENDORS._cssProperty('transition');\r\n var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop]();\r\n var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition;\r\n\r\n //measure the handle length to respect min & max length\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height];\r\n var handleTrackDiff = trackLength - handleLength;\r\n var handleCSS = {};\r\n var transformOffset;\r\n var translateValue;\r\n\r\n //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'\r\n // because its a bit behind during the small delay when content size updates\r\n //(delay = mutationObserverContentLag, if its 0 then this var could be used)\r\n var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative\r\n var getScrollRatio = function (base) {\r\n return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll));\r\n };\r\n var getHandleOffset = function (scrollRatio) {\r\n var offset = handleTrackDiff * scrollRatio;\r\n offset = isNaN(offset) ? 0 : offset;\r\n offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset;\r\n offset = MATH.max(0, offset);\r\n return offset;\r\n };\r\n var scrollRatio = getScrollRatio(nativeScroll);\r\n var unsnappedScrollRatio = getScrollRatio(currentScroll);\r\n var handleOffset = getHandleOffset(unsnappedScrollRatio);\r\n var snappedHandleOffset = getHandleOffset(scrollRatio);\r\n\r\n scrollbarVarsInfo._maxScroll = maxScroll;\r\n scrollbarVarsInfo._currentScroll = nativeScroll;\r\n scrollbarVarsInfo._currentScrollRatio = scrollRatio;\r\n\r\n if (_supportTransform) {\r\n transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px\r\n //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %\r\n translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)';\r\n\r\n handleCSS[strTransform] = translateValue;\r\n\r\n //apply or clear up transition\r\n if (_supportTransition)\r\n handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty;\r\n }\r\n else\r\n handleCSS[scrollbarVars._left_top] = handleOffset;\r\n\r\n\r\n //only apply css if offset has changed and overflow exists.\r\n if (!nativeOverlayScrollbarsAreActive()) {\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //clear up transition\r\n if (_supportTransform && _supportTransition && transition) {\r\n scrollbarVars._handle.one(_strTransitionEndEvent, function () {\r\n if (!_destroyed)\r\n scrollbarVars._handle.css(strTransition, _strEmpty);\r\n });\r\n }\r\n }\r\n\r\n scrollbarVarsInfo._handleOffset = handleOffset;\r\n scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;\r\n scrollbarVarsInfo._trackLength = trackLength;\r\n }\r\n\r\n /**\r\n * Refreshes the interactivity of the given scrollbar element.\r\n * @param isTrack True if the track element is the target, false if the handle element is the target.\r\n * @param value True for interactivity false for no interactivity.\r\n */\r\n function refreshScrollbarsInteractive(isTrack, value) {\r\n var action = value ? 'removeClass' : 'addClass';\r\n var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement;\r\n var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement;\r\n var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff;\r\n\r\n element1[action](className);\r\n element2[action](className);\r\n }\r\n\r\n /**\r\n * Returns a object which is used for fast access for specific variables.\r\n * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed.\r\n * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}}\r\n */\r\n function getScrollbarVars(isHorizontal) {\r\n return {\r\n _width_height: isHorizontal ? _strWidth : _strHeight,\r\n _Width_Height: isHorizontal ? 'Width' : 'Height',\r\n _left_top: isHorizontal ? _strLeft : _strTop,\r\n _Left_Top: isHorizontal ? 'Left' : 'Top',\r\n _x_y: isHorizontal ? _strX : _strY,\r\n _X_Y: isHorizontal ? 'X' : 'Y',\r\n _w_h: isHorizontal ? 'w' : 'h',\r\n _l_t: isHorizontal ? 'l' : 't',\r\n _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement,\r\n _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement,\r\n _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement,\r\n _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo\r\n };\r\n }\r\n\r\n\r\n //==== Scrollbar Corner ====//\r\n\r\n /**\r\n * Builds or destroys the scrollbar corner DOM element.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarCornerDOM(destroy) {\r\n _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true);\r\n\r\n if (!destroy) {\r\n if (!_domExists) {\r\n _hostElement.append(_scrollbarCornerElement);\r\n }\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n else {\r\n remove(_scrollbarCornerElement);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar corner interactivity events.\r\n */\r\n function setupScrollbarCornerEvents() {\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var mouseDownPosition = {};\r\n var mouseDownSize = {};\r\n var mouseDownInvertedScale = {};\r\n var reconnectMutationObserver;\r\n\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var pageOffset = getCoordinates(event);\r\n var hostElementCSS = {};\r\n if (_resizeHorizontal || _resizeBoth)\r\n hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x);\r\n if (_resizeVertical || _resizeBoth)\r\n hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y);\r\n _hostElement.css(hostElementCSS);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n else {\r\n documentMouseTouchUp(event);\r\n }\r\n }\r\n function documentMouseTouchUp(event) {\r\n var eventIsTrusted = event !== undefined;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp],\r\n true);\r\n\r\n removeClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.releaseCapture)\r\n _scrollbarCornerElement.releaseCapture();\r\n\r\n if (eventIsTrusted) {\r\n if (reconnectMutationObserver)\r\n connectMutationObservers();\r\n _base.update(_strAuto);\r\n }\r\n reconnectMutationObserver = false;\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function getCoordinates(event) {\r\n return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event);\r\n }\r\n\r\n addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) {\r\n if (onMouseTouchDownContinue(event) && !_resizeNone) {\r\n if (_mutationObserversConnected) {\r\n reconnectMutationObserver = true;\r\n disconnectMutationObservers();\r\n }\r\n\r\n mouseDownPosition = getCoordinates(event);\r\n\r\n mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0);\r\n mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0);\r\n mouseDownInvertedScale = getHostElementInvertedScale();\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp]);\r\n\r\n addClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.setCapture)\r\n _scrollbarCornerElement.setCapture();\r\n\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n });\r\n }\r\n\r\n\r\n //==== Utils ====//\r\n\r\n /**\r\n * Calls the callback with the given name. The Context of this callback is always _base (this).\r\n * @param name The name of the target which shall be called.\r\n * @param args The args with which the callback shall be called.\r\n * @param dependent Boolean which decides whether the callback shall be fired, undefined is like a \"true\" value.\r\n */\r\n function dispatchCallback(name, args, dependent) {\r\n if (dependent === false)\r\n return;\r\n if (_initialized) {\r\n var callback = _currentPreparedOptions.callbacks[name];\r\n var extensionOnName = name;\r\n var ext;\r\n\r\n if (extensionOnName.substr(0, 2) === 'on')\r\n extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3);\r\n\r\n if (type(callback) == TYPES.f)\r\n callback.call(_base, args);\r\n\r\n each(_extensions, function () {\r\n ext = this;\r\n if (type(ext.on) == TYPES.f)\r\n ext.on(extensionOnName, args);\r\n });\r\n }\r\n else if (!_destroyed)\r\n _callbacksInitQeueue.push({ n: name, a: args });\r\n }\r\n\r\n /**\r\n * Sets the \"top, right, bottom, left\" properties, with a given prefix, of the given css object.\r\n * @param targetCSSObject The css object to which the values shall be applied.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param values A array of values which shall be applied to the \"top, right, bottom, left\" -properties. The array order is [top, right, bottom, left].\r\n * If this argument is undefined the value '' (empty string) will be applied to all properties.\r\n */\r\n function setTopRightBottomLeft(targetCSSObject, prefix, values) {\r\n prefix = prefix || _strEmpty;\r\n values = values || [_strEmpty, _strEmpty, _strEmpty, _strEmpty];\r\n\r\n targetCSSObject[prefix + _strTop] = values[0];\r\n targetCSSObject[prefix + _strRight] = values[1];\r\n targetCSSObject[prefix + _strBottom] = values[2];\r\n targetCSSObject[prefix + _strLeft] = values[3];\r\n }\r\n\r\n /**\r\n * Gets the \"top, right, bottom, left\" CSS properties of the CSS property with the given prefix from the host element.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param suffix The suffix of the \"top, right, bottom, left\" css properties. (example: 'border-' is a valid prefix with '-width' is a valid suffix)\r\n * @param zeroX True if the x axis shall be 0.\r\n * @param zeroY True if the y axis shall be 0.\r\n * @returns {{}} The object which contains the numbers of the read CSS properties.\r\n */\r\n function getTopRightBottomLeftHost(prefix, suffix, zeroX, zeroY) {\r\n suffix = suffix || _strEmpty;\r\n prefix = prefix || _strEmpty;\r\n return {\r\n t: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strTop + suffix)),\r\n r: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strRight + suffix)),\r\n b: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strBottom + suffix)),\r\n l: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strLeft + suffix))\r\n };\r\n }\r\n\r\n /**\r\n * Returns the computed CSS transition string from the given element.\r\n * @param element The element from which the transition string shall be returned.\r\n * @returns {string} The CSS transition string from the given element.\r\n */\r\n function getCSSTransitionString(element) {\r\n var transitionStr = VENDORS._cssProperty('transition');\r\n var assembledValue = element.css(transitionStr);\r\n if (assembledValue)\r\n return assembledValue;\r\n var regExpString = '\\\\s*(' + '([^,(]+(\\\\(.+?\\\\))?)+' + ')[\\\\s,]*';\r\n var regExpMain = new RegExp(regExpString);\r\n var regExpValidate = new RegExp('^(' + regExpString + ')+$');\r\n var properties = 'property duration timing-function delay'.split(' ');\r\n var result = [];\r\n var strResult;\r\n var valueArray;\r\n var i = 0;\r\n var j;\r\n var splitCssStyleByComma = function (str) {\r\n strResult = [];\r\n if (!str.match(regExpValidate))\r\n return str;\r\n while (str.match(regExpMain)) {\r\n strResult.push(RegExp.$1);\r\n str = str.replace(regExpMain, _strEmpty);\r\n }\r\n\r\n return strResult;\r\n };\r\n for (; i < properties[LEXICON.l]; i++) {\r\n valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i]));\r\n for (j = 0; j < valueArray[LEXICON.l]; j++)\r\n result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j];\r\n }\r\n return result.join(', ');\r\n }\r\n\r\n /**\r\n * Generates a Regular Expression which matches with a string which starts with 'os-host'.\r\n * @param {boolean} withCurrClassNameOption The Regular Expression also matches if the string is the current ClassName option (multiple values splitted by space possible).\r\n * @param {boolean} withOldClassNameOption The Regular Expression also matches if the string is the old ClassName option (multiple values splitted by space possible).\r\n */\r\n function createHostClassNameRegExp(withCurrClassNameOption, withOldClassNameOption) {\r\n var i;\r\n var split;\r\n var appendix;\r\n var appendClasses = function (classes, condition) {\r\n appendix = '';\r\n if (condition && typeof classes == TYPES.s) {\r\n split = classes.split(_strSpace);\r\n for (i = 0; i < split[LEXICON.l]; i++)\r\n appendix += '|' + split[i] + '$';\r\n // split[i].replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') for escaping regex characters\r\n }\r\n return appendix;\r\n };\r\n\r\n return new RegExp(\r\n '(^' + _classNameHostElement + '([-_].+|)$)' +\r\n appendClasses(_classNameCache, withCurrClassNameOption) +\r\n appendClasses(_oldClassName, withOldClassNameOption), 'g');\r\n }\r\n\r\n /**\r\n * Calculates the host-elements inverted scale. (invertedScale = 1 / scale)\r\n * @returns {{x: number, y: number}} The scale of the host-element.\r\n */\r\n function getHostElementInvertedScale() {\r\n var rect = _paddingElementNative[LEXICON.bCR]();\r\n return {\r\n x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1,\r\n y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1\r\n };\r\n }\r\n\r\n /**\r\n * Checks whether the given object is a HTMLElement.\r\n * @param o The object which shall be checked.\r\n * @returns {boolean} True the given object is a HTMLElement, false otherwise.\r\n */\r\n function isHTMLElement(o) {\r\n var strOwnerDocument = 'ownerDocument';\r\n var strHTMLElement = 'HTMLElement';\r\n var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window;\r\n return (\r\n typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2\r\n o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s\r\n );\r\n }\r\n\r\n /**\r\n * Compares 2 arrays and returns the differences between them as a array.\r\n * @param a1 The first array which shall be compared.\r\n * @param a2 The second array which shall be compared.\r\n * @returns {Array} The differences between the two arrays.\r\n */\r\n function getArrayDifferences(a1, a2) {\r\n var a = [];\r\n var diff = [];\r\n var i;\r\n var k;\r\n for (i = 0; i < a1.length; i++)\r\n a[a1[i]] = true;\r\n for (i = 0; i < a2.length; i++) {\r\n if (a[a2[i]])\r\n delete a[a2[i]];\r\n else\r\n a[a2[i]] = true;\r\n }\r\n for (k in a)\r\n diff.push(k);\r\n return diff;\r\n }\r\n\r\n /**\r\n * Returns Zero or the number to which the value can be parsed.\r\n * @param value The value which shall be parsed.\r\n * @param toFloat Indicates whether the number shall be parsed to a float.\r\n */\r\n function parseToZeroOrNumber(value, toFloat) {\r\n var num = toFloat ? parseFloat(value) : parseInt(value, 10);\r\n return isNaN(num) ? 0 : num;\r\n }\r\n\r\n /**\r\n * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it.\r\n * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported.\r\n */\r\n function getTextareaInfo() {\r\n //read needed values\r\n var textareaCursorPosition = _targetElementNative.selectionStart;\r\n if (textareaCursorPosition === undefined)\r\n return;\r\n\r\n var textareaValue = _targetElement.val();\r\n var textareaLength = textareaValue[LEXICON.l];\r\n var textareaRowSplit = textareaValue.split('\\n');\r\n var textareaLastRow = textareaRowSplit[LEXICON.l];\r\n var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\\n');\r\n var widestRow = 0;\r\n var textareaLastCol = 0;\r\n var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l];\r\n var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l];\r\n var rowCols;\r\n var i;\r\n\r\n //get widest Row and the last column of the textarea\r\n for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) {\r\n rowCols = textareaRowSplit[i][LEXICON.l];\r\n if (rowCols > textareaLastCol) {\r\n widestRow = i + 1;\r\n textareaLastCol = rowCols;\r\n }\r\n }\r\n\r\n return {\r\n _cursorRow: cursorRow, //cursorRow\r\n _cursorColumn: cursorCol, //cursorCol\r\n _rows: textareaLastRow, //rows\r\n _columns: textareaLastCol, //cols\r\n _widestRow: widestRow, //wRow\r\n _cursorPosition: textareaCursorPosition, //pos\r\n _cursorMax: textareaLength //max\r\n };\r\n }\r\n\r\n /**\r\n * Determines whether native overlay scrollbars are active.\r\n * @returns {boolean} True if native overlay scrollbars are active, false otherwise.\r\n */\r\n function nativeOverlayScrollbarsAreActive() {\r\n return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y));\r\n }\r\n\r\n /**\r\n * Gets the element which is used to measure the content size.\r\n * @returns {*} TextareaCover if target element is textarea else the ContentElement.\r\n */\r\n function getContentMeasureElement() {\r\n return _isTextarea ? _textareaCoverElement[0] : _contentElementNative;\r\n }\r\n\r\n /**\r\n * Generates a string which represents a HTML div with the given classes or attributes.\r\n * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as \"className\".)\r\n * @param content The content of the div as string.\r\n * @returns {string} The concated string which represents a HTML div and its content.\r\n */\r\n function generateDiv(classesOrAttrs, content) {\r\n return '<div ' + (classesOrAttrs ? type(classesOrAttrs) == TYPES.s ?\r\n 'class=\"' + classesOrAttrs + '\"' :\r\n (function () {\r\n var key;\r\n var attrs = _strEmpty;\r\n if (FRAMEWORK.isPlainObject(classesOrAttrs)) {\r\n for (key in classesOrAttrs)\r\n attrs += (key === 'c' ? 'class' : key) + '=\"' + classesOrAttrs[key] + '\" ';\r\n }\r\n return attrs;\r\n })() :\r\n _strEmpty) +\r\n '>' +\r\n (content || _strEmpty) +\r\n '</div>';\r\n }\r\n\r\n /**\r\n * Selects or generates a div with the given class attribute.\r\n * @param className The class names (divided by spaces) of the div which shall be selected or generated.\r\n * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement)\r\n * If its a boolean it decides whether only the children of the host element shall be selected.\r\n * @returns {*} The generated or selected element.\r\n */\r\n function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) {\r\n var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b;\r\n var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement);\r\n\r\n return (_domExists && !selectParent[LEXICON.l])\r\n ? null\r\n : _domExists\r\n ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\\s/g, _strDot)).eq(0)\r\n : FRAMEWORK(generateDiv(className))\r\n }\r\n\r\n /**\r\n * Gets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be got.\r\n * @param path The property of which the value shall be got.\r\n * @returns {*} Returns the value of the searched property or undefined of the property wasn't found.\r\n */\r\n function getObjectPropVal(obj, path) {\r\n var splits = path.split(_strDot);\r\n var i = 0;\r\n var val;\r\n for (; i < splits.length; i++) {\r\n if (!obj[LEXICON.hOP](splits[i]))\r\n return;\r\n val = obj[splits[i]];\r\n if (i < splits.length && type(val) == TYPES.o)\r\n obj = val;\r\n }\r\n return val;\r\n }\r\n\r\n /**\r\n * Sets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be set.\r\n * @param path The property of which the value shall be set.\r\n * @param val The value of the property which shall be set.\r\n */\r\n function setObjectPropVal(obj, path, val) {\r\n var splits = path.split(_strDot);\r\n var splitsLength = splits.length;\r\n var i = 0;\r\n var extendObj = {};\r\n var extendObjRoot = extendObj;\r\n for (; i < splitsLength; i++)\r\n extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val;\r\n FRAMEWORK.extend(obj, extendObjRoot, true);\r\n }\r\n\r\n /**\t\r\n * Runs a action for each selector inside the updateOnLoad option.\t\r\n * @param {Function} action The action for each updateOnLoad selector, the arguments the function takes is the index and the value (the selector).\t\r\n */\r\n function eachUpdateOnLoad(action) {\r\n var updateOnLoad = _currentPreparedOptions.updateOnLoad;\r\n updateOnLoad = type(updateOnLoad) == TYPES.s ? updateOnLoad.split(_strSpace) : updateOnLoad;\r\n\r\n if (COMPATIBILITY.isA(updateOnLoad) && !_destroyed) {\r\n each(updateOnLoad, action);\r\n }\r\n }\r\n\r\n\r\n //==== Utils Cache ====//\r\n\r\n /**\r\n * Compares two values or objects and returns true if they aren't equal.\r\n * @param current The first value or object which shall be compared.\r\n * @param cache The second value or object which shall be compared.\r\n * @param force If true the returned value is always true.\r\n * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise.\r\n */\r\n function checkCache(current, cache, force) {\r\n if (force)\r\n return force;\r\n if (type(current) == TYPES.o && type(cache) == TYPES.o) {\r\n for (var prop in current) {\r\n if (prop !== 'c') {\r\n if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) {\r\n if (checkCache(current[prop], cache[prop]))\r\n return true;\r\n }\r\n else {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n return current !== cache;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n //==== Shortcuts ====//\r\n\r\n /**\r\n * jQuery extend method shortcut with a appended \"true\" as first argument.\r\n */\r\n function extendDeep() {\r\n return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments)));\r\n }\r\n\r\n /**\r\n * jQuery addClass method shortcut.\r\n */\r\n function addClass(el, classes) {\r\n return _frameworkProto.addClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery removeClass method shortcut.\r\n */\r\n function removeClass(el, classes) {\r\n return _frameworkProto.removeClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * Adds or removes the given classes dependent on the boolean value. True for add, false for remove.\r\n */\r\n function addRemoveClass(el, classes, doAdd) {\r\n return doAdd ? addClass(el, classes) : removeClass(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery remove method shortcut.\r\n */\r\n function remove(el) {\r\n return _frameworkProto.remove.call(el);\r\n }\r\n\r\n /**\r\n * Finds the first child element with the given selector of the given element.\r\n * @param el The root element from which the selector shall be valid.\r\n * @param selector The selector of the searched element.\r\n * @returns {*} The first element which is a child of the given element and matches the givens selector.\r\n */\r\n function findFirst(el, selector) {\r\n return _frameworkProto.find.call(el, selector).eq(0);\r\n }\r\n\r\n\r\n //==== API ====//\r\n\r\n /**\r\n * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle.\r\n * This behavior can be reset by calling the update method.\r\n */\r\n _base.sleep = function () {\r\n _sleeping = true;\r\n };\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param force True if every property shall be updated and the cache shall be ignored.\r\n * !INTERNAL USAGE! : force can be a string \"auto\", \"sync\" or \"zoom\" too\r\n * if \"auto\" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called.\r\n * if \"sync\" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes.\r\n * if \"zoom\" then a update takes place where it's assumed that content and host size changed\r\n * @returns {boolean|undefined} \r\n * If force is \"sync\" then a boolean is returned which indicates whether a update was needed due to pending changes.\r\n * If force is \"auto\" then a boolean is returned whether a update was needed due to attribute or size changes.\r\n * undefined otherwise.\r\n */\r\n _base.update = function (force) {\r\n if (_destroyed)\r\n return;\r\n\r\n var attrsChanged;\r\n var contentSizeC;\r\n var isString = type(force) == TYPES.s;\r\n var doUpdateAuto;\r\n var mutHost;\r\n var mutContent;\r\n\r\n if (isString) {\r\n if (force === _strAuto) {\r\n attrsChanged = meaningfulAttrsChanged();\r\n contentSizeC = updateAutoContentSizeChanged();\r\n doUpdateAuto = attrsChanged || contentSizeC;\r\n if (doUpdateAuto) {\r\n update({\r\n _contentSizeChanged: contentSizeC,\r\n _changedOptions: _initialized ? undefined : _currentPreparedOptions\r\n });\r\n }\r\n }\r\n else if (force === _strSync) {\r\n if (_mutationObserversConnected) {\r\n mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords());\r\n mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords());\r\n }\r\n else {\r\n mutHost = _base.update(_strAuto);\r\n }\r\n }\r\n else if (force === 'zoom') {\r\n update({\r\n _hostSizeChanged: true,\r\n _contentSizeChanged: true\r\n });\r\n }\r\n }\r\n else {\r\n force = _sleeping || force;\r\n _sleeping = false;\r\n if (!_base.update(_strSync) || force)\r\n update({ _force: force });\r\n }\r\n\r\n updateElementsOnLoad();\r\n\r\n return doUpdateAuto || mutHost || mutContent;\r\n };\r\n\r\n /**\r\n Gets or sets the current options. The update method will be called automatically if new options were set.\r\n * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned.\r\n * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads.\r\n * @returns {*}\r\n */\r\n _base.options = function (newOptions, value) {\r\n var option = {};\r\n var changedOps;\r\n\r\n //return current options if newOptions are undefined or empty\r\n if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) {\r\n if (type(newOptions) == TYPES.s) {\r\n if (arguments.length > 1) {\r\n setObjectPropVal(option, newOptions, value);\r\n changedOps = setOptions(option);\r\n }\r\n else\r\n return getObjectPropVal(_currentOptions, newOptions);\r\n }\r\n else\r\n return _currentOptions;\r\n }\r\n else {\r\n changedOps = setOptions(newOptions);\r\n }\r\n\r\n if (!FRAMEWORK.isEmptyObject(changedOps)) {\r\n update({ _changedOptions: changedOps });\r\n }\r\n };\r\n\r\n /**\r\n * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep.\r\n */\r\n _base.destroy = function () {\r\n if (_destroyed)\r\n return;\r\n\r\n //remove this instance from auto update loop\r\n autoUpdateLoop.remove(_base);\r\n\r\n //disconnect all mutation observers\r\n disconnectMutationObservers();\r\n\r\n //remove all resize observers\r\n setupResizeObserver(_sizeObserverElement);\r\n setupResizeObserver(_sizeAutoObserverElement);\r\n\r\n //remove all extensions\r\n for (var extName in _extensions)\r\n _base.removeExt(extName);\r\n\r\n //remove all 'destroy' events\r\n while (_destroyEvents[LEXICON.l] > 0)\r\n _destroyEvents.pop()();\r\n\r\n //remove all events from host element\r\n setupHostMouseTouchEvents(true);\r\n\r\n //remove all helper / detection elements\r\n if (_contentGlueElement)\r\n remove(_contentGlueElement);\r\n if (_contentArrangeElement)\r\n remove(_contentArrangeElement);\r\n if (_sizeAutoObserverAdded)\r\n remove(_sizeAutoObserverElement);\r\n\r\n //remove all generated DOM\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n setupStructureDOM(true);\r\n\r\n //remove all generated image load events\r\n for (var i = 0; i < _updateOnLoadElms[LEXICON.l]; i++)\r\n FRAMEWORK(_updateOnLoadElms[i]).off(_updateOnLoadEventName, updateOnLoadCallback);\r\n _updateOnLoadElms = undefined;\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n //remove this instance from the instances list\r\n INSTANCES(pluginTargetElement, 0);\r\n dispatchCallback('onDestroyed');\r\n\r\n //remove all properties and methods\r\n //for (var property in _base)\r\n // delete _base[property];\r\n //_base = undefined;\r\n };\r\n\r\n /**\r\n * Scrolls to a given position or element.\r\n * @param coordinates\r\n * 1. Can be \"coordinates\" which looks like:\r\n * { x : ?, y : ? } OR Object with x and y properties\r\n * { left : ?, top : ? } OR Object with left and top properties\r\n * { l : ?, t : ? } OR Object with l and t properties\r\n * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y)\r\n * ? A single value which stays for both axis\r\n * A value can be a number, a string or a calculation.\r\n *\r\n * Operators:\r\n * [NONE] The current scroll will be overwritten by the value.\r\n * '+=' The value will be added to the current scroll offset\r\n * '-=' The value will be subtracted from the current scroll offset\r\n * '*=' The current scroll wil be multiplicated by the value.\r\n * '/=' The current scroll wil be divided by the value.\r\n *\r\n * Units:\r\n * [NONE] The value is the final scroll amount. final = (value * 1)\r\n * 'px' Same as none\r\n * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value)\r\n * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth)\r\n * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight)\r\n *\r\n * example final values:\r\n * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%'\r\n *\r\n * 2. Can be a HTML or jQuery element:\r\n * The final scroll offset is the offset (without margin) of the given HTML / jQuery element.\r\n *\r\n * 3. Can be a object with a HTML or jQuery element with additional settings:\r\n * {\r\n * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid.\r\n * scroll : [string, array, object], Default value is 'always'.\r\n * block : [string, array, object], Default value is 'begin'.\r\n * margin : [number, boolean, array, object] Default value is false.\r\n * }\r\n *\r\n * Possible scroll settings are:\r\n * 'always' Scrolls always.\r\n * 'ifneeded' Scrolls only if the element isnt fully in view.\r\n * 'never' Scrolls never.\r\n *\r\n * Possible block settings are:\r\n * 'begin' Both axis shall be docked to the \"begin\" edge. - The element will be docked to the top and left edge of the viewport.\r\n * 'end' Both axis shall be docked to the \"end\" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.)\r\n * 'center' Both axis shall be docked to \"center\". - The element will be centered in the viewport.\r\n * 'nearest' The element will be docked to the nearest edge(s).\r\n *\r\n * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset.\r\n * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used.\r\n * [NUMBER] The margin will be used for all edges.\r\n *\r\n * @param duration The duration of the scroll animation, OR a jQuery animation configuration object.\r\n * @param easing The animation easing.\r\n * @param complete The animation complete callback.\r\n * @returns {{\r\n * position: {x: number, y: number},\r\n * ratio: {x: number, y: number},\r\n * max: {x: number, y: number},\r\n * handleOffset: {x: number, y: number},\r\n * handleLength: {x: number, y: number},\r\n * handleLengthRatio: {x: number, y: number}, t\r\n * rackLength: {x: number, y: number},\r\n * isRTL: boolean,\r\n * isRTLNormalized: boolean\r\n * }}\r\n */\r\n _base.scroll = function (coordinates, duration, easing, complete) {\r\n if (arguments.length === 0 || coordinates === undefined) {\r\n var infoX = _scrollHorizontalInfo;\r\n var infoY = _scrollVerticalInfo;\r\n var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i;\r\n var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n;\r\n var scrollX = infoX._currentScroll;\r\n var scrollXRatio = infoX._currentScrollRatio;\r\n var maxScrollX = infoX._maxScroll;\r\n scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio;\r\n scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX;\r\n scrollX *= normalizeNegate ? -1 : 1;\r\n maxScrollX *= normalizeNegate ? -1 : 1;\r\n\r\n return {\r\n position: {\r\n x: scrollX,\r\n y: infoY._currentScroll\r\n },\r\n ratio: {\r\n x: scrollXRatio,\r\n y: infoY._currentScrollRatio\r\n },\r\n max: {\r\n x: maxScrollX,\r\n y: infoY._maxScroll\r\n },\r\n handleOffset: {\r\n x: infoX._handleOffset,\r\n y: infoY._handleOffset\r\n },\r\n handleLength: {\r\n x: infoX._handleLength,\r\n y: infoY._handleLength\r\n },\r\n handleLengthRatio: {\r\n x: infoX._handleLengthRatio,\r\n y: infoY._handleLengthRatio\r\n },\r\n trackLength: {\r\n x: infoX._trackLength,\r\n y: infoY._trackLength\r\n },\r\n snappedHandleOffset: {\r\n x: infoX._snappedHandleOffset,\r\n y: infoY._snappedHandleOffset\r\n },\r\n isRTL: _isRTL,\r\n isRTLNormalized: _normalizeRTLCache\r\n };\r\n }\r\n\r\n _base.update(_strSync);\r\n\r\n var normalizeRTL = _normalizeRTLCache;\r\n var coordinatesXAxisProps = [_strX, _strLeft, 'l'];\r\n var coordinatesYAxisProps = [_strY, _strTop, 't'];\r\n var coordinatesOperators = ['+=', '-=', '*=', '/='];\r\n var durationIsObject = type(duration) == TYPES.o;\r\n var completeCallback = durationIsObject ? duration.complete : complete;\r\n var i;\r\n var finalScroll = {};\r\n var specialEasing = {};\r\n var doScrollLeft;\r\n var doScrollTop;\r\n var animationOptions;\r\n var strEnd = 'end';\r\n var strBegin = 'begin';\r\n var strCenter = 'center';\r\n var strNearest = 'nearest';\r\n var strAlways = 'always';\r\n var strNever = 'never';\r\n var strIfNeeded = 'ifneeded';\r\n var strLength = LEXICON.l;\r\n var settingsAxis;\r\n var settingsScroll;\r\n var settingsBlock;\r\n var settingsMargin;\r\n var finalElement;\r\n var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx'];\r\n var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest];\r\n var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded];\r\n var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el');\r\n var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates;\r\n var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false;\r\n var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement);\r\n var updateScrollbarInfos = function () {\r\n if (doScrollLeft)\r\n refreshScrollbarHandleOffset(true);\r\n if (doScrollTop)\r\n refreshScrollbarHandleOffset(false);\r\n };\r\n var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () {\r\n updateScrollbarInfos();\r\n completeCallback();\r\n };\r\n function checkSettingsStringValue(currValue, allowedValues) {\r\n for (i = 0; i < allowedValues[strLength]; i++) {\r\n if (currValue === allowedValues[i])\r\n return true;\r\n }\r\n return false;\r\n }\r\n function getRawScroll(isX, coordinates) {\r\n var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps;\r\n coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates;\r\n\r\n if (COMPATIBILITY.isA(coordinates))\r\n return isX ? coordinates[0] : coordinates[1];\r\n else if (type(coordinates) == TYPES.o) {\r\n //decides RTL normalization \"hack\" with .n\r\n //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; \r\n for (i = 0; i < coordinateProps[strLength]; i++)\r\n if (coordinateProps[i] in coordinates)\r\n return coordinates[coordinateProps[i]];\r\n }\r\n }\r\n function getFinalScroll(isX, rawScroll) {\r\n var isString = type(rawScroll) == TYPES.s;\r\n var operator;\r\n var amount;\r\n var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo;\r\n var currScroll = scrollInfo._currentScroll;\r\n var maxScroll = scrollInfo._maxScroll;\r\n var mult = ' * ';\r\n var finalValue;\r\n var isRTLisX = _isRTL && isX;\r\n var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL;\r\n var strReplace = 'replace';\r\n var evalFunc = eval;\r\n var possibleOperator;\r\n if (isString) {\r\n //check operator\r\n if (rawScroll[strLength] > 2) {\r\n possibleOperator = rawScroll.substr(0, 2);\r\n if (inArray(possibleOperator, coordinatesOperators) > -1)\r\n operator = possibleOperator;\r\n }\r\n\r\n //calculate units and shortcuts\r\n rawScroll = operator ? rawScroll.substr(2) : rawScroll;\r\n rawScroll = rawScroll\r\n [strReplace](/min/g, 0) //'min' = 0%\r\n [strReplace](/</g, 0) //'<' = 0%\r\n [strReplace](/max/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'max' = 100%\r\n [strReplace](/>/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100%\r\n [strReplace](/px/g, _strEmpty)\r\n [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0))\r\n [strReplace](/vw/g, mult + _viewportSize.w)\r\n [strReplace](/vh/g, mult + _viewportSize.h);\r\n amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll);\r\n }\r\n else {\r\n amount = rawScroll;\r\n }\r\n\r\n if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) {\r\n var normalizeIsRTLisX = normalizeRTL && isRTLisX;\r\n var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1);\r\n var invert = normalizeIsRTLisX && _rtlScrollBehavior.i;\r\n var negate = normalizeIsRTLisX && _rtlScrollBehavior.n;\r\n operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll;\r\n switch (operator) {\r\n case '+=':\r\n finalValue = operatorCurrScroll + amount;\r\n break;\r\n case '-=':\r\n finalValue = operatorCurrScroll - amount;\r\n break;\r\n case '*=':\r\n finalValue = operatorCurrScroll * amount;\r\n break;\r\n case '/=':\r\n finalValue = operatorCurrScroll / amount;\r\n break;\r\n default:\r\n finalValue = amount;\r\n break;\r\n }\r\n finalValue = invert ? maxScroll - finalValue : finalValue;\r\n finalValue *= negate ? -1 : 1;\r\n finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue));\r\n }\r\n return finalValue === currScroll ? undefined : finalValue;\r\n }\r\n function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) {\r\n var resultDefault = [defaultValue, defaultValue];\r\n var valueType = type(value);\r\n var valueArrLength;\r\n var valueArrItem;\r\n\r\n //value can be [ string, or array of two strings ]\r\n if (valueType == valueInternalType) {\r\n value = [value, value];\r\n }\r\n else if (valueType == TYPES.a) {\r\n valueArrLength = value[strLength];\r\n if (valueArrLength > 2 || valueArrLength < 1)\r\n value = resultDefault;\r\n else {\r\n if (valueArrLength === 1)\r\n value[1] = defaultValue;\r\n for (i = 0; i < valueArrLength; i++) {\r\n valueArrItem = value[i];\r\n if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) {\r\n value = resultDefault;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n else if (valueType == TYPES.o)\r\n value = [value[_strX] || defaultValue, value[_strY] || defaultValue];\r\n else\r\n value = resultDefault;\r\n return { x: value[0], y: value[1] };\r\n }\r\n function generateMargin(marginTopRightBottomLeftArray) {\r\n var result = [];\r\n var currValue;\r\n var currValueType;\r\n var valueDirections = [_strTop, _strRight, _strBottom, _strLeft];\r\n for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) {\r\n if (i === valueDirections[strLength])\r\n break;\r\n currValue = marginTopRightBottomLeftArray[i];\r\n currValueType = type(currValue);\r\n if (currValueType == TYPES.b)\r\n result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0);\r\n else\r\n result.push(currValueType == TYPES.n ? currValue : 0);\r\n }\r\n return result;\r\n }\r\n\r\n if (possibleElementIsJQuery || possibleElementIsHTMLElement) {\r\n //get settings\r\n var margin = coordinatesIsElementObj ? coordinates.margin : 0;\r\n var axis = coordinatesIsElementObj ? coordinates.axis : 0;\r\n var scroll = coordinatesIsElementObj ? coordinates.scroll : 0;\r\n var block = coordinatesIsElementObj ? coordinates.block : 0;\r\n var marginDefault = [0, 0, 0, 0];\r\n var marginType = type(margin);\r\n var marginLength;\r\n finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement);\r\n\r\n if (finalElement[strLength] > 0) {\r\n //margin can be [ boolean, number, array of 2, array of 4, object ]\r\n if (marginType == TYPES.n || marginType == TYPES.b)\r\n margin = generateMargin([margin, margin, margin, margin]);\r\n else if (marginType == TYPES.a) {\r\n marginLength = margin[strLength];\r\n if (marginLength === 2)\r\n margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]);\r\n else if (marginLength >= 4)\r\n margin = generateMargin(margin);\r\n else\r\n margin = marginDefault;\r\n }\r\n else if (marginType == TYPES.o)\r\n margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]);\r\n else\r\n margin = marginDefault;\r\n\r\n //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block;\r\n settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy';\r\n settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues);\r\n settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues);\r\n settingsMargin = margin;\r\n\r\n var viewportScroll = {\r\n l: _scrollHorizontalInfo._currentScroll,\r\n t: _scrollVerticalInfo._currentScroll\r\n };\r\n // use padding element instead of viewport element because padding element has never padding, margin or position applied.\r\n var viewportOffset = _paddingElement.offset();\r\n\r\n //get coordinates\r\n var elementOffset = finalElement.offset();\r\n var doNotScroll = {\r\n x: settingsScroll.x == strNever || settingsAxis == _strY,\r\n y: settingsScroll.y == strNever || settingsAxis == _strX\r\n };\r\n elementOffset[_strTop] -= settingsMargin[0];\r\n elementOffset[_strLeft] -= settingsMargin[3];\r\n var elementScrollCoordinates = {\r\n x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l),\r\n y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t)\r\n };\r\n if (_isRTL) {\r\n if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l);\r\n if (_rtlScrollBehavior.n && normalizeRTL)\r\n elementScrollCoordinates.x *= -1;\r\n if (_rtlScrollBehavior.i && normalizeRTL)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l));\r\n }\r\n\r\n //measuring is required\r\n if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) {\r\n var measuringElm = finalElement[0];\r\n var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : {\r\n width: measuringElm[LEXICON.oW],\r\n height: measuringElm[LEXICON.oH]\r\n };\r\n var elementSize = {\r\n w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1],\r\n h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2]\r\n };\r\n var finalizeBlock = function (isX) {\r\n var vars = getScrollbarVars(isX);\r\n var wh = vars._w_h;\r\n var lt = vars._left_top;\r\n var xy = vars._x_y;\r\n var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd);\r\n var blockIsCenter = settingsBlock[xy] == strCenter;\r\n var blockIsNearest = settingsBlock[xy] == strNearest;\r\n var scrollNever = settingsScroll[xy] == strNever;\r\n var scrollIfNeeded = settingsScroll[xy] == strIfNeeded;\r\n var vpSize = _viewportSize[wh];\r\n var vpOffset = viewportOffset[lt];\r\n var elSize = elementSize[wh];\r\n var elOffset = elementOffset[lt];\r\n var divide = blockIsCenter ? 2 : 1;\r\n var elementCenterOffset = elOffset + (elSize / 2);\r\n var viewportCenterOffset = vpOffset + (vpSize / 2);\r\n var isInView =\r\n elSize <= vpSize\r\n && elOffset >= vpOffset\r\n && elOffset + elSize <= vpOffset + vpSize;\r\n\r\n if (scrollNever)\r\n doNotScroll[xy] = true;\r\n else if (!doNotScroll[xy]) {\r\n if (blockIsNearest || scrollIfNeeded) {\r\n doNotScroll[xy] = scrollIfNeeded ? isInView : false;\r\n blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset;\r\n }\r\n elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0;\r\n }\r\n };\r\n finalizeBlock(true);\r\n finalizeBlock(false);\r\n }\r\n\r\n if (doNotScroll.y)\r\n delete elementScrollCoordinates.y;\r\n if (doNotScroll.x)\r\n delete elementScrollCoordinates.x;\r\n\r\n coordinates = elementScrollCoordinates;\r\n }\r\n }\r\n\r\n finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates));\r\n finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates));\r\n doScrollLeft = finalScroll[_strScrollLeft] !== undefined;\r\n doScrollTop = finalScroll[_strScrollTop] !== undefined;\r\n\r\n if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) {\r\n if (durationIsObject) {\r\n duration.complete = proxyCompleteCallback;\r\n _viewportElement.animate(finalScroll, duration);\r\n }\r\n else {\r\n animationOptions = {\r\n duration: duration,\r\n complete: proxyCompleteCallback\r\n };\r\n if (COMPATIBILITY.isA(easing) || FRAMEWORK.isPlainObject(easing)) {\r\n specialEasing[_strScrollLeft] = easing[0] || easing.x;\r\n specialEasing[_strScrollTop] = easing[1] || easing.y;\r\n animationOptions.specialEasing = specialEasing;\r\n }\r\n else {\r\n animationOptions.easing = easing;\r\n }\r\n _viewportElement.animate(finalScroll, animationOptions);\r\n }\r\n }\r\n else {\r\n if (doScrollLeft)\r\n _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]);\r\n if (doScrollTop)\r\n _viewportElement[_strScrollTop](finalScroll[_strScrollTop]);\r\n updateScrollbarInfos();\r\n }\r\n };\r\n\r\n /**\r\n * Stops all scroll animations.\r\n * @returns {*} The current OverlayScrollbars instance (for chaining).\r\n */\r\n _base.scrollStop = function (param1, param2, param3) {\r\n _viewportElement.stop(param1, param2, param3);\r\n return _base;\r\n };\r\n\r\n /**\r\n * Returns all relevant elements.\r\n * @param elementName The name of the element which shall be returned.\r\n * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *}\r\n */\r\n _base.getElements = function (elementName) {\r\n var obj = {\r\n target: _targetElementNative,\r\n host: _hostElementNative,\r\n padding: _paddingElementNative,\r\n viewport: _viewportElementNative,\r\n content: _contentElementNative,\r\n scrollbarHorizontal: {\r\n scrollbar: _scrollbarHorizontalElement[0],\r\n track: _scrollbarHorizontalTrackElement[0],\r\n handle: _scrollbarHorizontalHandleElement[0]\r\n },\r\n scrollbarVertical: {\r\n scrollbar: _scrollbarVerticalElement[0],\r\n track: _scrollbarVerticalTrackElement[0],\r\n handle: _scrollbarVerticalHandleElement[0]\r\n },\r\n scrollbarCorner: _scrollbarCornerElement[0]\r\n };\r\n return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj;\r\n };\r\n\r\n /**\r\n * Returns a object which describes the current state of this instance.\r\n * @param stateProperty A specific property from the state object which shall be returned.\r\n * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *}\r\n */\r\n _base.getState = function (stateProperty) {\r\n function prepare(obj) {\r\n if (!FRAMEWORK.isPlainObject(obj))\r\n return obj;\r\n var extended = extendDeep({}, obj);\r\n var changePropertyName = function (from, to) {\r\n if (extended[LEXICON.hOP](from)) {\r\n extended[to] = extended[from];\r\n delete extended[from];\r\n }\r\n };\r\n changePropertyName('w', _strWidth); //change w to width\r\n changePropertyName('h', _strHeight); //change h to height\r\n delete extended.c; //delete c (the 'changed' prop)\r\n return extended;\r\n };\r\n var obj = {\r\n destroyed: !!prepare(_destroyed),\r\n sleeping: !!prepare(_sleeping),\r\n autoUpdate: prepare(!_mutationObserversConnected),\r\n widthAuto: prepare(_widthAutoCache),\r\n heightAuto: prepare(_heightAutoCache),\r\n padding: prepare(_cssPaddingCache),\r\n overflowAmount: prepare(_overflowAmountCache),\r\n hideOverflow: prepare(_hideOverflowCache),\r\n hasOverflow: prepare(_hasOverflowCache),\r\n contentScrollSize: prepare(_contentScrollSizeCache),\r\n viewportSize: prepare(_viewportSize),\r\n hostSize: prepare(_hostSizeCache),\r\n documentMixed: prepare(_documentMixed)\r\n };\r\n return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj;\r\n };\r\n\r\n /**\r\n * Gets all or specific extension instance.\r\n * @param extName The name of the extension from which the instance shall be got.\r\n * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found.\r\n */\r\n _base.ext = function (extName) {\r\n var result;\r\n var privateMethods = _extensionsPrivateMethods.split(' ');\r\n var i = 0;\r\n if (type(extName) == TYPES.s) {\r\n if (_extensions[LEXICON.hOP](extName)) {\r\n result = extendDeep({}, _extensions[extName]);\r\n for (; i < privateMethods.length; i++)\r\n delete result[privateMethods[i]];\r\n }\r\n }\r\n else {\r\n result = {};\r\n for (i in _extensions)\r\n result[i] = extendDeep({}, _base.ext(i));\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Adds a extension to this instance.\r\n * @param extName The name of the extension which shall be added.\r\n * @param extensionOptions The extension options which shall be used.\r\n * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly.\r\n */\r\n _base.addExt = function (extName, extensionOptions) {\r\n var registeredExtensionObj = _plugin.extension(extName);\r\n var instance;\r\n var instanceAdded;\r\n var instanceContract;\r\n var contractResult;\r\n var contractFulfilled = true;\r\n if (registeredExtensionObj) {\r\n if (!_extensions[LEXICON.hOP](extName)) {\r\n instance = registeredExtensionObj.extensionFactory.call(_base,\r\n extendDeep({}, registeredExtensionObj.defaultOptions),\r\n FRAMEWORK,\r\n COMPATIBILITY);\r\n\r\n if (instance) {\r\n instanceContract = instance.contract;\r\n if (type(instanceContract) == TYPES.f) {\r\n contractResult = instanceContract(window);\r\n contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled;\r\n }\r\n if (contractFulfilled) {\r\n _extensions[extName] = instance;\r\n instanceAdded = instance.added;\r\n if (type(instanceAdded) == TYPES.f)\r\n instanceAdded(extensionOptions);\r\n\r\n return _base.ext(extName);\r\n }\r\n }\r\n }\r\n else\r\n return _base.ext(extName);\r\n }\r\n else\r\n console.warn(\"A extension with the name \\\"\" + extName + \"\\\" isn't registered.\");\r\n };\r\n\r\n /**\r\n * Removes a extension from this instance.\r\n * @param extName The name of the extension which shall be removed.\r\n * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before.\r\n */\r\n _base.removeExt = function (extName) {\r\n var instance = _extensions[extName];\r\n var instanceRemoved;\r\n if (instance) {\r\n delete _extensions[extName];\r\n\r\n instanceRemoved = instance.removed;\r\n if (type(instanceRemoved) == TYPES.f)\r\n instanceRemoved();\r\n\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Constructs the plugin.\r\n * @param targetElement The element to which the plugin shall be applied.\r\n * @param options The initial options of the plugin.\r\n * @param extensions The extension(s) which shall be added right after the initialization.\r\n * @returns {boolean} True if the plugin was successfully initialized, false otherwise.\r\n */\r\n function construct(targetElement, options, extensions) {\r\n _defaultOptions = globals.defaultOptions;\r\n _nativeScrollbarStyling = globals.nativeScrollbarStyling;\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid);\r\n _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize);\r\n _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior);\r\n\r\n //parse & set options but don't update\r\n setOptions(extendDeep({}, _defaultOptions, options));\r\n\r\n _cssCalc = globals.cssCalc;\r\n _msieVersion = globals.msie;\r\n _autoUpdateRecommended = globals.autoUpdateRecommended;\r\n _supportTransition = globals.supportTransition;\r\n _supportTransform = globals.supportTransform;\r\n _supportPassiveEvents = globals.supportPassiveEvents;\r\n _supportResizeObserver = globals.supportResizeObserver;\r\n _supportMutationObserver = globals.supportMutationObserver;\r\n _restrictedMeasuring = globals.restrictedMeasuring;\r\n _documentElement = FRAMEWORK(targetElement.ownerDocument);\r\n _documentElementNative = _documentElement[0];\r\n _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow);\r\n _windowElementNative = _windowElement[0];\r\n _htmlElement = findFirst(_documentElement, 'html');\r\n _bodyElement = findFirst(_htmlElement, 'body');\r\n _targetElement = FRAMEWORK(targetElement);\r\n _targetElementNative = _targetElement[0];\r\n _isTextarea = _targetElement.is('textarea');\r\n _isBody = _targetElement.is('body');\r\n _documentMixed = _documentElementNative !== document;\r\n\r\n /* On a div Element The if checks only whether:\r\n * - the targetElement has the class \"os-host\"\r\n * - the targetElement has a a child with the class \"os-padding\"\r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-host\" element is the targetElement)\r\n *\r\n * <div class=\"os-host\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding\">\r\n * <div class=\"os-viewport\">\r\n * <div class=\"os-content\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n *\r\n * =====================================================================================\r\n * \r\n * On a Textarea Element The if checks only whether:\r\n * - the targetElement has the class \"os-textarea\" \r\n * - the targetElement is inside a element with the class \"os-content\" \r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-textarea\" (textarea) element is the targetElement)\r\n *\r\n * <div class=\"os-host-textarea\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding os-text-inherit\">\r\n * <div class=\"os-viewport os-text-inherit\">\r\n * <div class=\"os-content os-text-inherit\">\r\n * <div class=\"os-textarea-cover\"></div>\r\n * <textarea class=\"os-textarea os-text-inherit\"></textarea>\r\n * </div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n */\r\n _domExists = _isTextarea\r\n ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement)\r\n : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l];\r\n\r\n var initBodyScroll;\r\n var bodyMouseTouchDownListener;\r\n\r\n //check if the plugin hasn't to be initialized\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) {\r\n dispatchCallback('onInitializationWithdrawn');\r\n if (_domExists) {\r\n setupStructureDOM(true);\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n }\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n return _base;\r\n }\r\n\r\n if (_isBody) {\r\n initBodyScroll = {};\r\n initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]());\r\n initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]());\r\n\r\n bodyMouseTouchDownListener = function () {\r\n _viewportElement.removeAttr(LEXICON.ti);\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true);\r\n }\r\n }\r\n\r\n //build OverlayScrollbars DOM\r\n setupStructureDOM();\r\n setupScrollbarsDOM();\r\n setupScrollbarCornerDOM();\r\n\r\n //create OverlayScrollbars events\r\n setupStructureEvents();\r\n setupScrollbarEvents(true);\r\n setupScrollbarEvents(false);\r\n setupScrollbarCornerEvents();\r\n\r\n //create mutation observers\r\n createMutationObservers();\r\n\r\n //build resize observer for the host element\r\n setupResizeObserver(_sizeObserverElement, hostOnResized);\r\n\r\n if (_isBody) {\r\n //apply the body scroll to handle it right in the update method\r\n _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t);\r\n\r\n //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling\r\n if (document.activeElement == targetElement && _viewportElementNative.focus) {\r\n //set a tabindex to make the viewportElement focusable\r\n _viewportElement.attr(LEXICON.ti, '-1');\r\n _viewportElementNative.focus();\r\n\r\n /* the tabindex has to be removed due to;\r\n * If you set the tabindex attribute on an <div>, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too\r\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex\r\n */\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true);\r\n }\r\n }\r\n\r\n //update for the first time & initialize cache\r\n _base.update(_strAuto);\r\n\r\n //the plugin is initialized now!\r\n _initialized = true;\r\n dispatchCallback('onInitialized');\r\n\r\n //call all callbacks which would fire before the initialized was complete\r\n each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); });\r\n _callbacksInitQeueue = [];\r\n\r\n //add extensions\r\n if (type(extensions) == TYPES.s)\r\n extensions = [extensions];\r\n if (COMPATIBILITY.isA(extensions))\r\n each(extensions, function (index, value) { _base.addExt(value); });\r\n else if (FRAMEWORK.isPlainObject(extensions))\r\n each(extensions, function (key, value) { _base.addExt(key, value); });\r\n\r\n //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions)\r\n setTimeout(function () {\r\n if (_supportTransition && !_destroyed)\r\n addClass(_hostElement, _classNameHostTransition);\r\n }, 333);\r\n\r\n return _base;\r\n }\r\n\r\n if (_plugin.valid(construct(pluginTargetElement, options, extensions))) {\r\n INSTANCES(pluginTargetElement, _base);\r\n }\r\n\r\n return _base;\r\n }\r\n\r\n /**\r\n * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance.\r\n * @param pluginTargetElements The elements to which the Plugin shall be initialized.\r\n * @param options The custom options with which the plugin shall be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*}\r\n */\r\n _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var arr = [];\r\n var optsIsPlainObj = FRAMEWORK.isPlainObject(options);\r\n var inst;\r\n var result;\r\n\r\n //pluginTargetElements is null or undefined\r\n if (!pluginTargetElements)\r\n return optsIsPlainObj || !options ? result : arr;\r\n\r\n /*\r\n pluginTargetElements will be converted to:\r\n 1. A jQueryElement Array\r\n 2. A HTMLElement Array\r\n 3. A Array with a single HTML Element\r\n so pluginTargetElements is always a array.\r\n */\r\n pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements];\r\n initOverlayScrollbarsStatics();\r\n\r\n if (pluginTargetElements[LEXICON.l] > 0) {\r\n if (optsIsPlainObj) {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = v;\r\n if (inst !== undefined)\r\n arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop));\r\n });\r\n }\r\n else {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = INSTANCES(v);\r\n if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst)))\r\n arr.push(inst);\r\n else if (options === undefined)\r\n arr.push(inst);\r\n });\r\n }\r\n result = arr[LEXICON.l] === 1 ? arr[0] : arr;\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Returns a object which contains global information about the plugin and each instance of it.\r\n * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object.\r\n */\r\n _plugin.globals = function () {\r\n initOverlayScrollbarsStatics();\r\n var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals);\r\n delete globals['msie'];\r\n return globals;\r\n };\r\n\r\n /**\r\n * Gets or Sets the default options for each new plugin initialization.\r\n * @param newDefaultOptions The object with which the default options shall be extended.\r\n */\r\n _plugin.defaultOptions = function (newDefaultOptions) {\r\n initOverlayScrollbarsStatics();\r\n var currDefaultOptions = _pluginsGlobals.defaultOptions;\r\n if (newDefaultOptions === undefined)\r\n return FRAMEWORK.extend(true, {}, currDefaultOptions);\r\n\r\n //set the new default options\r\n _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default);\r\n };\r\n\r\n /**\r\n * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance.\r\n * @param osInstance The potential OverlayScrollbars instance which shall be checked.\r\n * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise.\r\n */\r\n _plugin.valid = function (osInstance) {\r\n return osInstance instanceof _plugin && !osInstance.getState().destroyed;\r\n };\r\n\r\n /**\r\n * Registers, Unregisters or returns a extension.\r\n * Register: Pass the name and the extension. (defaultOptions is optional)\r\n * Unregister: Pass the name and anything except a function as extension parameter.\r\n * Get extension: Pass the name of the extension which shall be got.\r\n * Get all extensions: Pass no arguments.\r\n * @param extensionName The name of the extension which shall be registered, unregistered or returned.\r\n * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension.\r\n * @param defaultOptions The default options which shall be used for the registered extension.\r\n */\r\n _plugin.extension = function (extensionName, extension, defaultOptions) {\r\n var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s;\r\n var argLen = arguments[LEXICON.l];\r\n var i = 0;\r\n if (argLen < 1 || !extNameTypeString) {\r\n //return a copy of all extension objects\r\n return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions);\r\n }\r\n else if (extNameTypeString) {\r\n if (COMPATIBILITY.type(extension) == TYPES.f) {\r\n //register extension\r\n _pluginsExtensions.push({\r\n name: extensionName,\r\n extensionFactory: extension,\r\n defaultOptions: defaultOptions\r\n });\r\n }\r\n else {\r\n for (; i < _pluginsExtensions[LEXICON.l]; i++) {\r\n if (_pluginsExtensions[i].name === extensionName) {\r\n if (argLen > 1)\r\n _pluginsExtensions.splice(i, 1); //remove extension\r\n else\r\n return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n return _plugin;\r\n })();\r\n\r\n if (JQUERY && JQUERY.fn) {\r\n /**\r\n * The jQuery initialization interface.\r\n * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected.\r\n */\r\n JQUERY.fn.overlayScrollbars = function (options, extensions) {\r\n var _elements = this;\r\n if (JQUERY.isPlainObject(options)) {\r\n JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); });\r\n return _elements;\r\n }\r\n else\r\n return PLUGIN(_elements, options);\r\n };\r\n }\r\n return PLUGIN;\r\n }\r\n));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vL2hvbWUvamVua2lucy93b3Jrc3BhY2UvZGVzaWduLXN5c3RlbV9tYWluL25vZGVfbW9kdWxlcy9vdmVybGF5c2Nyb2xsYmFycy9qcy9PdmVybGF5U2Nyb2xsYmFycy5qcz83ODhiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsSUFBMEM7QUFDbEQsUUFBUSxtQ0FBTyxhQUFhLG9EQUFvRCxFQUFFO0FBQUEsb0dBQUM7QUFDbkYsU0FBUyxFQUcyQztBQUNwRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHdCQUF3QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxvQ0FBb0M7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQiw4QkFBOEI7QUFDeEQsOEJBQThCLHFDQUFxQztBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QywwQ0FBMEMsNEdBQTRHOztBQUV0SjtBQUNBLDhDQUE4QztBQUM5Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLDZCQUE2QjtBQUMxRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QztBQUNBLDhGQUE4RiwyQ0FBMkMsRUFBRTs7QUFFM0k7QUFDQTtBQUNBLDZCQUE2QixXQUFXO0FBQ3hDO0FBQ0EsMkZBQTJGLGdDQUFnQyxFQUFFOztBQUU3SDtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHNCQUFzQjtBQUNwRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQSxtQ0FBbUMsb0JBQW9CO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixZQUFZOztBQUV6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7O0FBR1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1EQUFtRCxtQkFBbUI7QUFDdEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RCx5Q0FBeUMsaUNBQWlDO0FBQzFFLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsK0JBQStCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZGQUE2RjtBQUM3RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsWUFBWTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNENBQTRDLG9CQUFvQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLGtDQUFrQzs7QUFFbEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLG9CQUFvQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsc0JBQXNCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFlBQVk7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsNEJBQTRCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiw0QkFBNEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHFCQUFxQjtBQUMvQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IseUJBQXlCO0FBQ3hEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QixxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0Esa0RBQWtELGlEQUFpRCxFQUFFO0FBQ3JHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtREFBbUQsRUFBRTtBQUN2RyxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGdEQUFnRCxFQUFFO0FBQ3BHLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckIsK0JBQStCLHdCQUF3QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isc0JBQXNCO0FBQ3JEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsdUNBQXVDLEVBQUU7QUFDM0YsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0NBQWtDLEVBQUU7QUFDdEYsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtQ0FBbUMsRUFBRTtBQUN2RixpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsZ0NBQWdDLEVBQUU7QUFDcEYsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0IscUJBQXFCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyx1QkFBdUI7QUFDMUQ7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCwwQkFBMEIsRUFBRTtBQUM5RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsT0FBTztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvRkFBb0Y7O0FBRXBGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0EsbURBQW1ELDhCQUE4QjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELDRDQUE0QztBQUN2RztBQUNBO0FBQ0E7QUFDQSwrREFBK0QseURBQXlEO0FBQ3hIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFOztBQUU1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvREFBb0Q7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsYUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckIsZ0RBQWdELGVBQWU7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsbURBQW1ELHVFQUF1RTtBQUMxSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLHlCQUF5QixZQUFZO0FBQ3JDO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxtQ0FBbUM7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLGlDQUFpQztBQUNqQyw2Q0FBNkM7QUFDN0MseUNBQXlDO0FBQ3pDLG9DQUFvQztBQUNwQyxxQ0FBcUM7QUFDckMsb0NBQW9DO0FBQ3BDLDJDQUEyQztBQUMzQyx3Q0FBd0M7QUFDeEMsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qix1QkFBdUI7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELHFEQUFxRDtBQUM5RztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxrRUFBa0UsZ0JBQWdCO0FBQ25KO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDOztBQUVqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5QjtBQUM3RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQ0FBb0MsNEJBQTRCO0FBQ2hFO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DLGlCQUFpQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0EscUJBQXFCOztBQUVyQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLG9CQUFvQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUlBQW1JOztBQUVuSTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsRUFBRTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTREO0FBQzVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEZBQThGOztBQUU5RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEZBQThGO0FBQzlGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQSw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0Y7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFLFdBQVc7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0xBQWdMO0FBQ2hMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1EQUFtRCxnQkFBZ0I7QUFDbkU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7O0FBRUEsbURBQW1EO0FBQ25ELDJEQUEyRDs7QUFFM0Q7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdFQUF3RTtBQUN4RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1IQUFtSDtBQUNuSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRIQUE0SCxpQkFBaUI7QUFDN0kseUJBQXlCOzs7QUFHekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZIQUE2SCxpQkFBaUI7QUFDOUkseUJBQXlCOzs7QUFHekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0pBQWtKO0FBQ2xKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHdGQUF3RjtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1IQUFtSDs7QUFFbkg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrTkFBK047QUFDL047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwSEFBMEg7QUFDMUgsaUhBQWlIO0FBQ2pIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLCtFQUErRTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0QscUNBQXFDO0FBQ3BHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsbURBQW1ELG1CQUFtQjtBQUN0RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBCQUEwQiwyQkFBMkI7QUFDckQ7QUFDQSxtQ0FBbUMsMkJBQTJCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQywyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdEO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsc0JBQXNCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsTUFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBLCtCQUErQixlQUFlO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhCQUE4QixtR0FBbUc7QUFDakk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQkFBK0IsaUNBQWlDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsbUJBQW1CO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGtCQUFrQjtBQUM1QyxvRkFBb0Y7QUFDcEY7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLFNBQVM7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLGtCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxnQkFBZ0I7QUFDcEQ7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQ0FBbUMsa0NBQWtDO0FBQ3JFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixlQUFlO0FBQ3RDLHVCQUF1QixvQkFBb0I7QUFDM0MsdUJBQXVCLGVBQWU7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHFCQUFxQjtBQUNyRCw2QkFBNkIscUJBQXFCO0FBQ2xELDJCQUEyQixxQkFBcUI7QUFDaEQsb0NBQW9DLHFCQUFxQjtBQUN6RCxvQ0FBb0MscUJBQXFCO0FBQ3pELHlDQUF5QyxxQkFBcUI7QUFDOUQsa0NBQWtDLHFCQUFxQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw4QkFBOEI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJHO0FBQ0EsdUNBQXVDLGdDQUFnQztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLG9CQUFvQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDhDQUE4QztBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrRUFBK0Usa0NBQWtDLHNCQUFzQixrQ0FBa0MscUJBQXFCO0FBQzVOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsd0hBQXdIO0FBQ3RKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNELDREQUE0RDtBQUM1RCwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xELGtDQUFrQywyQkFBMkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RCw4REFBOEQ7QUFDOUQsOERBQThEO0FBQzlELHNEQUFzRDs7QUFFdEQ7QUFDQSw0Q0FBNEM7O0FBRTVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3RUFBd0Usb0NBQW9DLEVBQUU7QUFDOUc7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UscUJBQXFCLEVBQUU7QUFDekY7QUFDQSxnRUFBZ0UsMEJBQTBCLEVBQUU7O0FBRTVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDs7QUFFcEQ7QUFDQSwwRUFBMEU7QUFDMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLFFBQVE7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsd0NBQXdDO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLDhCQUE4QixtQ0FBbUM7QUFDakU7QUFDQTtBQUNBLG9FQUFvRTtBQUNwRTtBQUNBLG9FQUFvRSx5QkFBeUI7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixFQUFFO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELG1DQUFtQyxFQUFFO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIxMDkwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohXHJcbiAqIE92ZXJsYXlTY3JvbGxiYXJzXHJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9LaW5nU29yYS9PdmVybGF5U2Nyb2xsYmFyc1xyXG4gKlxyXG4gKiBWZXJzaW9uOiAxLjEzLjBcclxuICpcclxuICogQ29weXJpZ2h0IEtpbmdTb3JhIHwgUmVuZSBIYWFzLlxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmFcclxuICpcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxyXG4gKiBEYXRlOiAwMi4wOC4yMDIwXHJcbiAqL1xyXG5cclxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXHJcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7IH0pO1xyXG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSAnb2JqZWN0JylcclxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7XHJcbiAgICBlbHNlXHJcbiAgICAgICAgZmFjdG9yeShnbG9iYWwsIGdsb2JhbC5kb2N1bWVudCwgdW5kZWZpbmVkKTtcclxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsXHJcbiAgICBmdW5jdGlvbiAod2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xyXG4gICAgICAgIHZhciBQTFVHSU5OQU1FID0gJ092ZXJsYXlTY3JvbGxiYXJzJztcclxuICAgICAgICB2YXIgVFlQRVMgPSB7XHJcbiAgICAgICAgICAgIG86ICdvYmplY3QnLFxyXG4gICAgICAgICAgICBmOiAnZnVuY3Rpb24nLFxyXG4gICAgICAgICAgICBhOiAnYXJyYXknLFxyXG4gICAgICAgICAgICBzOiAnc3RyaW5nJyxcclxuICAgICAgICAgICAgYjogJ2Jvb2xlYW4nLFxyXG4gICAgICAgICAgICBuOiAnbnVtYmVyJyxcclxuICAgICAgICAgICAgdTogJ3VuZGVmaW5lZCcsXHJcbiAgICAgICAgICAgIHo6ICdudWxsJ1xyXG4gICAgICAgICAgICAvL2QgOiAnZGF0ZScsXHJcbiAgICAgICAgICAgIC8vZSA6ICdlcnJvcicsXHJcbiAgICAgICAgICAgIC8vciA6ICdyZWdleHAnLFxyXG4gICAgICAgICAgICAvL3kgOiAnc3ltYm9sJ1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIExFWElDT04gPSB7XHJcbiAgICAgICAgICAgIGM6ICdjbGFzcycsXHJcbiAgICAgICAgICAgIHM6ICdzdHlsZScsXHJcbiAgICAgICAgICAgIGk6ICdpZCcsXHJcbiAgICAgICAgICAgIGw6ICdsZW5ndGgnLFxyXG4gICAgICAgICAgICBwOiAncHJvdG90eXBlJyxcclxuICAgICAgICAgICAgdGk6ICd0YWJpbmRleCcsXHJcbiAgICAgICAgICAgIG9IOiAnb2Zmc2V0SGVpZ2h0JyxcclxuICAgICAgICAgICAgY0g6ICdjbGllbnRIZWlnaHQnLFxyXG4gICAgICAgICAgICBzSDogJ3Njcm9sbEhlaWdodCcsXHJcbiAgICAgICAgICAgIG9XOiAnb2Zmc2V0V2lkdGgnLFxyXG4gICAgICAgICAgICBjVzogJ2NsaWVudFdpZHRoJyxcclxuICAgICAgICAgICAgc1c6ICdzY3JvbGxXaWR0aCcsXHJcbiAgICAgICAgICAgIGhPUDogJ2hhc093blByb3BlcnR5JyxcclxuICAgICAgICAgICAgYkNSOiAnZ2V0Qm91bmRpbmdDbGllbnRSZWN0J1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIFZFTkRPUlMgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvL2h0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvR2xvc3NhcnkvVmVuZG9yX1ByZWZpeFxyXG4gICAgICAgICAgICB2YXIganNDYWNoZSA9IHt9O1xyXG4gICAgICAgICAgICB2YXIgY3NzQ2FjaGUgPSB7fTtcclxuICAgICAgICAgICAgdmFyIGNzc1ByZWZpeGVzID0gWyctd2Via2l0LScsICctbW96LScsICctby0nLCAnLW1zLSddO1xyXG4gICAgICAgICAgICB2YXIganNQcmVmaXhlcyA9IFsnV2ViS2l0JywgJ01veicsICdPJywgJ01TJ107XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZpcnN0TGV0dGVyVG9VcHBlcihzdHIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoMSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBfY3NzUHJlZml4ZXM6IGNzc1ByZWZpeGVzLFxyXG4gICAgICAgICAgICAgICAgX2pzUHJlZml4ZXM6IGpzUHJlZml4ZXMsXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHk6IGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBwZXJjYXNlZE5hbWUgPSBmaXJzdExldHRlclRvVXBwZXIobmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbVN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylbTEVYSUNPTi5zXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0UG9zc2liaWxpdGllcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHY7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGNzc1ByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzID0gY3NzUHJlZml4ZXNbaV0ucmVwbGFjZSgvLS9nLCAnJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFBvc3NpYmlsaXRpZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAvL3RyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1ByZWZpeGVzW2ldICsgbmFtZSwgLy8td2Via2l0LXRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzICsgdXBwZXJjYXNlZE5hbWUsIC8vd2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RMZXR0ZXJUb1VwcGVyKGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzKSArIHVwcGVyY2FzZWROYW1lIC8vV2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdWx0UG9zc2liaWxpdGllc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbG1TdHlsZVtyZXN1bHRQb3NzaWJpbGl0aWVzW3ZdXSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0UG9zc2liaWxpdGllc1t2XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHlWYWx1ZTogZnVuY3Rpb24gKHByb3BlcnR5LCB2YWx1ZXMsIHN1ZmZpeCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gcHJvcGVydHkgKyAnICcgKyB2YWx1ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlTdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpW0xFWElDT04uc107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NibGVWYWx1ZXMgPSB2YWx1ZXMuc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJlcGFyZWRTdWZmaXggPSBzdWZmaXggfHwgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3A7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcG9zc2JsZVZhbHVlc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IHYgPCBWRU5ET1JTLl9jc3NQcmVmaXhlc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3AgPSB2IDwgMCA/IHBvc3NibGVWYWx1ZXNbaV0gOiBWRU5ET1JTLl9jc3NQcmVmaXhlc1t2XSArIHBvc3NibGVWYWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdW1teVN0eWxlLmNzc1RleHQgPSBwcm9wZXJ0eSArICc6JyArIHByb3AgKyBwcmVwYXJlZFN1ZmZpeDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdW1teVN0eWxlW0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwcm9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjc3NDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIF9qc0FQSTogZnVuY3Rpb24gKG5hbWUsIGlzSW50ZXJmYWNlLCBmYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ganNDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB3aW5kb3dbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwganNQcmVmaXhlc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwgd2luZG93Wyhpc0ludGVyZmFjZSA/IGpzUHJlZml4ZXNbaV0gOiBqc1ByZWZpeGVzW2ldLnRvTG93ZXJDYXNlKCkpICsgZmlyc3RMZXR0ZXJUb1VwcGVyKG5hbWUpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAganNDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBmYWxsYmFjaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIENPTVBBVElCSUxJVFkgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiB3aW5kb3dTaXplKHgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB4ID8gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY1ddIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jV10gOiB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY0hdIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gYmluZChmdW5jLCB0aGlzT2JqKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwiQ2FuJ3QgYmluZCBmdW5jdGlvbiFcIjtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy90aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGFBcmdzID0gQXJyYXlbcHJvdG9dLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcclxuICAgICAgICAgICAgICAgIHZhciBmTk9QID0gZnVuY3Rpb24gKCkgeyB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGZCb3VuZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgPyB0aGlzIDogdGhpc09iaiwgYUFyZ3MuY29uY2F0KEFycmF5W3Byb3RvXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTsgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZnVuY1twcm90b10pXHJcbiAgICAgICAgICAgICAgICAgICAgZk5PUFtwcm90b10gPSBmdW5jW3Byb3RvXTsgLy8gRnVuY3Rpb24ucHJvdG90eXBlIGRvZXNuJ3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eVxyXG4gICAgICAgICAgICAgICAgZkJvdW5kW3Byb3RvXSA9IG5ldyBmTk9QKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZCb3VuZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY3VycmVudCB3aW5kb3cgd2lkdGguXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfG51bWJlcn0gVGhlIGN1cnJlbnQgd2luZG93IHdpZHRoIGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3VzogYmluZCh3aW5kb3dTaXplLCAwLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGN1cnJlbnQgd2luZG93IGhlaWdodC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtOdW1iZXJ8bnVtYmVyfSBUaGUgY3VycmVudCB3aW5kb3cgaGVpZ2h0IGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3SDogYmluZCh3aW5kb3dTaXplLCAwKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZCBpZiBub3Qgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge011dGF0aW9uT2JzZXJ2ZXJ8Knx1bmRlZmluZWR9IFRoZSBNdXRhdGlvbnNPYnNlcnZlciBPYmplY3Qgb3IgdW5kZWZpbmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtTzogYmluZChWRU5ET1JTLl9qc0FQSSwgMCwgJ011dGF0aW9uT2JzZXJ2ZXInLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFJlc2l6ZU9ic2VydmVyIE9iamVjdCBvciB1bmRlZmluZWQgaWYgbm90IHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtNdXRhdGlvbk9ic2VydmVyfCp8dW5kZWZpbmVkfSBUaGUgUmVzaXplT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgck86IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdSZXNpemVPYnNlcnZlcicsIHRydWUpLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgUmVxdWVzdEFuaW1hdGlvbkZyYW1lIG1ldGhvZCBvciBpdCdzIGNvcnJlc3BvbmRpbmcgcG9seWZpbGwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7KnxGdW5jdGlvbn0gVGhlIFJlcXVlc3RBbmltYXRpb25GcmFtZSBtZXRob2Qgb3IgaXQncyBjb3JyZXNwb25kaW5nIHBvbHlmaWxsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICByQUY6IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdyZXF1ZXN0QW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGZ1bmMpIHsgcmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmMsIDEwMDAgLyA2MCk7IH0pLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfEZ1bmN0aW9ufSBUaGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY0FGOiBiaW5kKFZFTkRPUlMuX2pzQVBJLCAwLCAnY2FuY2VsQW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGlkKSB7IHJldHVybiB3aW5kb3cuY2xlYXJUaW1lb3V0KGlkKTsgfSksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHRpbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgY3VycmVudCB0aW1lLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBub3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGF0ZS5ub3cgJiYgRGF0ZS5ub3coKSB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyB0aGUgcHJvcGFnYXRpb24gb2YgdGhlIGdpdmVuIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCBvZiB3aGljaCB0aGUgcHJvcGFnYXRpb24gc2hhbGwgYmUgc3RvcGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBzdHBQOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RvcFByb3BhZ2F0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYWN0aW9uIG9mIHRoZSBnaXZlbiBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgb2Ygd2hpY2ggdGhlIGRlZmF1bHQgYWN0aW9uIHNoYWxsIGJlIHByZXZlbnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcHJ2RDogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0ICYmIGV2ZW50LmNhbmNlbGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHBhZ2VYIGFuZCBwYWdlWSB2YWx1ZXMgb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgcGFnZVggYW5kIHBhZ2VYIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7eDogbnVtYmVyLCB5OiBudW1iZXJ9fSB4ID0gcGFnZVggdmFsdWUsIHkgPSBwYWdlWSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcGFnZTogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUGFnZSA9ICdwYWdlJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2xpZW50ID0gJ2NsaWVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clggPSAnWCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clkgPSAnWSc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldCB8fCBldmVudC5zcmNFbGVtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudERvYyA9IHRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb2MgPSBldmVudERvYy5kb2N1bWVudEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHkgPSBldmVudERvYy5ib2R5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIHRvdWNoIGV2ZW50IHJldHVybiByZXR1cm4gcGFnZVgvWSBvZiBpdFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHRvdWNoW3N0clBhZ2UgKyBzdHJYXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHRvdWNoW3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgcGFnZVgvWSBpZiBub3QgbmF0aXZlIHN1cHBvcnRlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnRbc3RyUGFnZSArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICE9IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJDbGllbnQgKyBzdHJYXSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2Muc2Nyb2xsTGVmdCB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsTGVmdCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0ckNsaWVudCArIHN0clldICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZG9jICYmIGRvYy5zY3JvbGxUb3AgfHwgYm9keSAmJiBib2R5LnNjcm9sbFRvcCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50VG9wIHx8IGJvZHkgJiYgYm9keS5jbGllbnRUb3AgfHwgMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJQYWdlICsgc3RyWF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY2xpY2tlZCBtb3VzZSBidXR0b24gb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgY2xpY2tlZCBidXR0b24gc2hhbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIHRoZSBjbGlja2VkIG1vdXNlIGJ1dHRvbi4gKDAgOiBub25lIHwgMSA6IGxlZnRCdXR0b24gfCAyIDogbWlkZGxlQnV0dG9uIHwgMyA6IHJpZ2h0QnV0dG9uKVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtQnRuOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoYnV0dG9uICYgMSA/IDEgOiAoYnV0dG9uICYgMiA/IDMgOiAoYnV0dG9uICYgNCA/IDIgOiAwKSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LndoaWNoO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGEgaXRlbSBpcyBpbiB0aGUgZ2l2ZW4gYXJyYXkgYW5kIHJldHVybnMgaXRzIGluZGV4LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGl0ZW0gVGhlIGl0ZW0gb2Ygd2hpY2ggdGhlIHBvc2l0aW9uIGluIHRoZSBhcnJheSBzaGFsbCBiZSBkZXRlcm1pbmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgemVybyBiYXNlZCBpbmRleCBvZiB0aGUgaXRlbSBvciAtMSBpZiB0aGUgaXRlbSBpc24ndCBpbiB0aGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGluQTogZnVuY3Rpb24gKGl0ZW0sIGFycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9Tb21ldGllbXMgaW4gSUUgYSBcIlNDUklQVDcwXCIgUGVybWlzc2lvbiBkZW5pZWQgZXJyb3Igb2NjdXJzIGlmIEhUTUwgZWxlbWVudHMgaW4gYSBpRnJhbWUgYXJlIGNvbXBhcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgcG90ZW50aWFsIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGEgYXJyYXksIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaXNBOiBmdW5jdGlvbiAoYXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlZiA9IEFycmF5LmlzQXJyYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZiA/IGRlZihhcnIpIDogdGhpcy50eXBlKGFycikgPT0gVFlQRVMuYTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBEZXRlcm1pbmUgdGhlIGludGVybmFsIEphdmFTY3JpcHQgW1tDbGFzc11dIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3Qgb2Ygd2hpY2ggdGhlIHR5cGUgc2hhbGwgYmUgZGV0ZXJtaW5lZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0eXBlIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHR5cGU6IGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmogKyAnJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqICsgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdFtMRVhJQ09OLnBdLnRvU3RyaW5nLmNhbGwob2JqKS5yZXBsYWNlKC9eXFxbb2JqZWN0ICguKylcXF0kLywgJyQxJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIGJpbmQ6IGJpbmRcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgYnkgdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBGb3IgZXhhbXBsZSB0aGUgZ2l2ZW4gbmFtZSBpcyBcInRyYW5zZm9ybVwiIGFuZCB5b3UncmUgdXNpbmcgYSBvbGQgRmlyZWZveCBicm93c2VyIHRoZW4gdGhlIHJldHVybmVkIHZhbHVlIHdvdWxkIGJlIFwiLW1vei10cmFuc2Zvcm1cIi5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3QgbmVlZCBhIHZlbmRvci1wcmVmaXgsIHRoZW4gdGhlIHJldHVybmVkIHN0cmluZyBpcyB0aGUgZ2l2ZW4gbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZSBhdCBhbGwgKG5vdCBldmVuIHdpdGggYSB2ZW5kb3ItcHJlZml4KSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgbnVsbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcm9wTmFtZSBUaGUgdW5wcmVmaXhlZCBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gVGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgb3IgbnVsbCBpZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgdGhlIGdpdmVuIENTUyBwcm9wZXJ0eS5cclxuXHJcbiAgICAgICAgICAgICAgICBjc3NQcm9wOiBmdW5jdGlvbihwcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBWRU5ET1JTLl9jc3NQcm9wZXJ0eShwcm9wTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkoKTtcclxuXHJcblxyXG4gICAgICAgIHZhciBNQVRIID0gTWF0aDtcclxuICAgICAgICB2YXIgSlFVRVJZID0gd2luZG93LmpRdWVyeTtcclxuICAgICAgICB2YXIgRUFTSU5HID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF9lYXNpbmdzTWF0aCA9IHtcclxuICAgICAgICAgICAgICAgIHA6IE1BVEguUEksXHJcbiAgICAgICAgICAgICAgICBjOiBNQVRILmNvcyxcclxuICAgICAgICAgICAgICAgIHM6IE1BVEguc2luLFxyXG4gICAgICAgICAgICAgICAgdzogTUFUSC5wb3csXHJcbiAgICAgICAgICAgICAgICB0OiBNQVRILnNxcnQsXHJcbiAgICAgICAgICAgICAgICBuOiBNQVRILmFzaW4sXHJcbiAgICAgICAgICAgICAgICBhOiBNQVRILmFicyxcclxuICAgICAgICAgICAgICAgIG86IDEuNzAxNThcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICB4IDogY3VycmVudCBwZXJjZW50ICgwIC0gMSksXHJcbiAgICAgICAgICAgICB0IDogY3VycmVudCB0aW1lIChkdXJhdGlvbiAqIHBlcmNlbnQpLFxyXG4gICAgICAgICAgICAgYiA6IHN0YXJ0IHZhbHVlIChmcm9tKSxcclxuICAgICAgICAgICAgIGMgOiBlbmQgdmFsdWUgKHRvKSxcclxuICAgICAgICAgICAgIGQgOiBkdXJhdGlvblxyXG5cclxuICAgICAgICAgICAgIGVhc2luZ05hbWUgOiBmdW5jdGlvbih4LCB0LCBiLCBjLCBkKSB7IHJldHVybiBlYXNlZFZhbHVlOyB9XHJcbiAgICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHN3aW5nOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwLjUgLSBfZWFzaW5nc01hdGguYyh4ICogX2Vhc2luZ3NNYXRoLnApIC8gMjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBsaW5lYXI6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhZDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICh0IC89IGQpICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YWQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1jICogKHQgLz0gZCkgKiAodCAtIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRRdWFkOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICsgYiA6IC1jIC8gMiAqICgoLS10KSAqICh0IC0gMikgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluQ3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAoKHQgPSB0IC8gZCAtIDEpICogdCAqIHQgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKyAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YXJ0OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0UXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICogdCArIGIgOiAtYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgLSAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVpbnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCAqIHQgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRRdWludDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgKiB0ICsgMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dFF1aW50OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKiB0ICogdCArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5TaW5lOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIF9lYXNpbmdzTWF0aC5jKHQgLyBkICogKF9lYXNpbmdzTWF0aC5wIC8gMikpICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFNpbmU6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiBfZWFzaW5nc01hdGgucyh0IC8gZCAqIChfZWFzaW5nc01hdGgucCAvIDIpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0U2luZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgLyAyICogKF9lYXNpbmdzTWF0aC5jKF9lYXNpbmdzTWF0aC5wICogdCAvIGQpIC0gMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IDApID8gYiA6IGMgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC8gZCAtIDEpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dEV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IGQpID8gYiArIGMgOiBjICogKC1fZWFzaW5nc01hdGgudygyLCAtMTAgKiB0IC8gZCkgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RXhwbzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSBkKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQgLyAyKSA8IDEpIHJldHVybiBjIC8gMiAqIF9lYXNpbmdzTWF0aC53KDIsIDEwICogKHQgLSAxKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjIC8gMiAqICgtX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogLS10KSArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5DaXJjOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLz0gZCkgKiB0KSAtIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIF9lYXNpbmdzTWF0aC50KDEgLSAodCA9IHQgLyBkIC0gMSkgKiB0KSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gLWMgLyAyICogKF9lYXNpbmdzTWF0aC50KDEgLSB0ICogdCkgLSAxKSArIGIgOiBjIC8gMiAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLT0gMikgKiB0KSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5FbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiOyBpZiAoKHQgLz0gZCkgPT0gMSkgcmV0dXJuIGIgKyBjOyBpZiAoIXApIHAgPSBkICogLjM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGEgPCBfZWFzaW5nc01hdGguYShjKSkgeyBhID0gYzsgcyA9IHAgLyA0OyB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBzID0gcCAvICgyICogX2Vhc2luZ3NNYXRoLnApICogX2Vhc2luZ3NNYXRoLm4oYyAvIGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRFbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodCAvPSBkKSA9PSAxKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwKSBwID0gZCAqIC4zO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhIDwgX2Vhc2luZ3NNYXRoLmEoYykpIHsgYSA9IGM7IHMgPSBwIC8gNDsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcyA9IHAgLyAoMiAqIF9lYXNpbmdzTWF0aC5wKSAqIF9lYXNpbmdzTWF0aC5uKGMgLyBhKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSAqIF9lYXNpbmdzTWF0aC53KDIsIC0xMCAqIHQpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RWxhc3RpYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IF9lYXNpbmdzTWF0aC5vOyB2YXIgcCA9IDA7IHZhciBhID0gYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHQgLz0gZCAvIDIpID09IDIpIHJldHVybiBiICsgYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXApIHAgPSBkICogKC4zICogMS41KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYSA8IF9lYXNpbmdzTWF0aC5hKGMpKSB7IGEgPSBjOyBzID0gcCAvIDQ7IH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHMgPSBwIC8gKDIgKiBfZWFzaW5nc01hdGgucCkgKiBfZWFzaW5nc01hdGgubihjIC8gYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPCAxKSByZXR1cm4gLS41ICogKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhICogX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogKHQgLT0gMSkpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICogLjUgKyBjICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5CYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogKChzICsgMSkgKiB0IC0gcykgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKCh0ID0gdCAvIGQgLSAxKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqICh0ICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgLSBzKSkgKyBiIDogYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCArIHMpICsgMikgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkJvdW5jZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAtIHRoaXMuZWFzZU91dEJvdW5jZSh4LCBkIC0gdCwgMCwgYywgZCkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCb3VuY2U6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG8gPSA3LjU2MjU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQpIDwgKDEgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogdCAqIHQpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQgPCAoMiAvIDIuNzUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKG8gKiAodCAtPSAoMS41IC8gMi43NSkpICogdCArIC43NSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodCA8ICgyLjUgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuMjUgLyAyLjc1KSkgKiB0ICsgLjkzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuNjI1IC8gMi43NSkpICogdCArIC45ODQzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Qm91bmNlOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCA8IGQgLyAyKSA/IHRoaXMuZWFzZUluQm91bmNlKHgsIHQgKiAyLCAwLCBjLCBkKSAqIC41ICsgYiA6IHRoaXMuZWFzZU91dEJvdW5jZSh4LCB0ICogMiAtIGQsIDAsIGMsIGQpICogLjUgKyBjICogLjUgKyBiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBURVJNUyBPRiBVU0UgLSBFQVNJTkcgRVFVQVRJT05TXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgQlNEIExpY2Vuc2UuIFxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogQ29weXJpZ2h0IMOCwqkgMjAwMSBSb2JlcnQgUGVubmVyXHJcbiAgICAgICAgICAgICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBcclxuICAgICAgICAgICAgICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgXHJcbiAgICAgICAgICAgICAqIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3QgXHJcbiAgICAgICAgICAgICAqIG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIFxyXG4gICAgICAgICAgICAgKiBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBhdXRob3Igbm9yIHRoZSBuYW1lcyBvZiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBcclxuICAgICAgICAgICAgICogb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgXHJcbiAgICAgICAgICAgICAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRlxyXG4gICAgICAgICAgICAgKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICAgICAgICAgICAgICogIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCxcclxuICAgICAgICAgICAgICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURVxyXG4gICAgICAgICAgICAgKiAgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIFxyXG4gICAgICAgICAgICAgKiBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElOR1xyXG4gICAgICAgICAgICAgKiAgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgXHJcbiAgICAgICAgICAgICAqIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4gXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIEZSQU1FV09SSyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfcm5vdGh0bWx3aGl0ZSA9ICgvW15cXHgyMFxcdFxcclxcblxcZl0rL2cpO1xyXG4gICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICB2YXIgX3N0ckVtcHR5ID0gJyc7XHJcbiAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsTGVmdCA9ICdzY3JvbGxMZWZ0JztcclxuICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxUb3AgPSAnc2Nyb2xsVG9wJztcclxuICAgICAgICAgICAgdmFyIF9hbmltYXRpb25zID0gW107XHJcbiAgICAgICAgICAgIHZhciBfdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgdmFyIF9jc3NOdW1iZXIgPSB7XHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbHVtbkNvdW50OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmbGV4R3JvdzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGZsZXhTaHJpbms6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcmRlcjogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB3aWRvd3M6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6b29tOiB0cnVlXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBleHRlbmQoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3JjLCBjb3B5SXNBcnJheSwgY29weSwgbmFtZSwgb3B0aW9ucywgY2xvbmUsIHRhcmdldCA9IGFyZ3VtZW50c1swXSB8fCB7fSxcclxuICAgICAgICAgICAgICAgICAgICBpID0gMSxcclxuICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBhcmd1bWVudHNbTEVYSUNPTi5sXSxcclxuICAgICAgICAgICAgICAgICAgICBkZWVwID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHRhcmdldCkgPT0gVFlQRVMuYikge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZXAgPSB0YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gYXJndW1lbnRzWzFdIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcclxuICAgICAgICAgICAgICAgICAgICBpID0gMjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcclxuICAgICAgICAgICAgICAgIGlmIChfdHlwZSh0YXJnZXQpICE9IFRZUEVTLm8gJiYgIV90eXBlKHRhcmdldCkgPT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIGV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxyXG4gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IEZha2VqUXVlcnk7XHJcbiAgICAgICAgICAgICAgICAgICAgLS1pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChvcHRpb25zID0gYXJndW1lbnRzW2ldKSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChuYW1lIGluIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYyA9IHRhcmdldFtuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkgPSBvcHRpb25zW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IGNvcHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWVwICYmIGNvcHkgJiYgKGlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0gQ09NUEFUSUJJTElUWS5pc0EoY29weSkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3B5SXNBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5SXNBcnJheSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHNyYyAmJiBDT01QQVRJQklMSVRZLmlzQShzcmMpID8gc3JjIDogW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lID0gc3JjICYmIGlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmV2ZXIgbW92ZSBvcmlnaW5hbCBvYmplY3RzLCBjbG9uZSB0aGVtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W25hbWVdID0gZXh0ZW5kKGRlZXAsIGNsb25lLCBjb3B5KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3B5ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbbmFtZV0gPSBjb3B5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaW5BcnJheShpdGVtLCBhcnIsIGZyb21JbmRleCkge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGZyb21JbmRleCB8fCAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaXNGdW5jdGlvbihvYmopIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBfdHlwZShvYmopID09IFRZUEVTLmY7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc0VtcHR5T2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFvYmogfHwgX3R5cGUob2JqKSAhPSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0W3Byb3RvXS5oYXNPd25Qcm9wZXJ0eTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNPd25Db25zdHJ1Y3RvciA9IGhhc093blByb3BlcnR5LmNhbGwob2JqLCAnY29uc3RydWN0b3InKTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNJc1Byb3RvdHlwZU9mID0gb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvcltwcm90b10gJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmouY29uc3RydWN0b3JbcHJvdG9dLCAnaXNQcm90b3R5cGVPZicpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvYmouY29uc3RydWN0b3IgJiYgIWhhc093bkNvbnN0cnVjdG9yICYmICFoYXNJc1Byb3RvdHlwZU9mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHsgLyoqLyB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90eXBlKGtleSkgPT0gVFlQRVMudSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGVhY2gob2JqLCBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5TGlrZShvYmopKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBvYmpbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9ICEhb2JqICYmIFtMRVhJQ09OLmxdIGluIG9iaiAmJiBvYmpbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciB0ID0gX3R5cGUob2JqKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKHQpID8gZmFsc2UgOiAodCA9PSBUWVBFUy5hIHx8IGxlbmd0aCA9PT0gMCB8fCBfdHlwZShsZW5ndGgpID09IFRZUEVTLm4gJiYgbGVuZ3RoID4gMCAmJiAobGVuZ3RoIC0gMSkgaW4gb2JqKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbnMuam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBtYXRjaGVzKGVsZW0sIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm9kZUxpc3QgPSAoZWxlbS5wYXJlbnROb2RlIHx8IGRvY3VtZW50KS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gbm9kZUxpc3RbTEVYSUNPTi5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlTGlzdFtpXSA9PSBlbGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZFtMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKF90eXBlKGNoaWxkKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50SFRNTChzdHJhdGVneSwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50RWxlbWVudChzdHJhdGVneSwgY2hpbGQubm9kZVR5cGUgPyBjaGlsZCA6IGNoaWxkWzBdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsW0xFWElDT04uc11bcHJvcF0gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbTEVYSUNPTi5zXVtwcm9wXSA9IHBhcnNlQ1NTVmFsKHByb3AsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VDU1NWYWwocHJvcCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9jc3NOdW1iZXJbcHJvcC50b0xvd2VyQ2FzZSgpXSAmJiBfdHlwZSh2YWwpID09IFRZUEVTLm4pXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsICs9ICdweCc7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaiwgcmVtb3ZlRnJvbVEpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbmRleDtcclxuICAgICAgICAgICAgICAgIHZhciBuZXh0QW5pbTtcclxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmVGcm9tUSAhPT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iai5xLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLnFbTEVYSUNPTi5sXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0QW5pbSA9IGFuaW1PYmoucVswXTtcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlKGFuaW1PYmouZWwsIG5leHRBbmltLnByb3BzLCBuZXh0QW5pbS5kdXJhdGlvbiwgbmV4dEFuaW0uZWFzaW5nLCBuZXh0QW5pbS5jb21wbGV0ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluQXJyYXkoYW5pbU9iaiwgX2FuaW1hdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzZXRBbmltYXRpb25WYWx1ZShlbCwgcHJvcCwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwcm9wID09PSBfc3RyU2Nyb2xsTGVmdCB8fCBwcm9wID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsW3Byb3BdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGFuaW1hdGUoZWwsIHByb3BzLCBvcHRpb25zLCBlYXNpbmcsIGNvbXBsZXRlLCBndWFyYW50ZWVkTmV4dCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc09wdGlvbnMgPSBpc1BsYWluT2JqZWN0KG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZyb20gPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciB0byA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBhbmltT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb2dyZXNzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ZXA7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGlmIChoYXNPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWFzaW5nID0gb3B0aW9ucy5lYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBvcHRpb25zLnN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2dyZXNzID0gb3B0aW9ucy5wcm9ncmVzcztcclxuICAgICAgICAgICAgICAgICAgICBzdGVwID0gb3B0aW9ucy5zdGVwO1xyXG4gICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmcgPSBvcHRpb25zLnNwZWNpYWxFYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUgPSBvcHRpb25zLmNvbXBsZXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gb3B0aW9ucy5kdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gZHVyYXRpb24gfHwgNDAwO1xyXG4gICAgICAgICAgICAgICAgZWFzaW5nID0gZWFzaW5nIHx8ICdzd2luZyc7XHJcbiAgICAgICAgICAgICAgICBndWFyYW50ZWVkTmV4dCA9IGd1YXJhbnRlZWROZXh0IHx8IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9hbmltYXRpb25zW2ldLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0gX2FuaW1hdGlvbnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFuaW1PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbDogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHE6IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5wdXNoKGFuaW1PYmopO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIHByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gX3N0clNjcm9sbExlZnQgfHwga2V5ID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2tleV0gPSBlbFtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVtrZXldID0gRmFrZWpRdWVyeShlbCkuY3NzKGtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gZnJvbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmcm9tW2tleV0gIT09IHByb3BzW2tleV0gJiYgcHJvcHNba2V5XSAhPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b1trZXldID0gcHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmplY3QodG8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVOb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZnJvbVZhbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdG9WYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVhc2VkVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0aW1lU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZyYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGFwc2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxUG9zID0gZ3VhcmFudGVlZE5leHQgPyAwIDogaW5BcnJheShxT2JqLCBhbmltT2JqLnEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wczogdG8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBoYXNPcHRpb25zID8gb3B0aW9ucyA6IGR1cmF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocVBvcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcVBvcyA9IGFuaW1PYmoucVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEucHVzaChxT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChxUG9zID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTdGFydCA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lTm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGFwc2VkID0gKHRpbWVOb3cgLSB0aW1lU3RhcnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCA9IHFPYmouc3RvcCB8fCBlbGFwc2VkID49IGR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQgPSAxIC0gKChNQVRILm1heCgwLCB0aW1lU3RhcnQgKyBkdXJhdGlvbiAtIHRpbWVOb3cpIC8gZHVyYXRpb24pIHx8IDApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiB0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tVmFsID0gcGFyc2VGbG9hdChmcm9tW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1ZhbCA9IHBhcnNlRmxvYXQodG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2VkVmFsID0gKHRvVmFsIC0gZnJvbVZhbCkgKiBFQVNJTkdbc3BlY2lhbEVhc2luZ1trZXldIHx8IGVhc2luZ10ocGVyY2VudCwgcGVyY2VudCAqIGR1cmF0aW9uLCAwLCAxLCBkdXJhdGlvbikgKyBmcm9tVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRBbmltYXRpb25WYWx1ZShlbCwga2V5LCBlYXNlZFZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHN0ZXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKGVhc2VkVmFsLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbTogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcDoga2V5LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBmcm9tVmFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdzogZWFzZWRWYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiB0b1ZhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3M6IHBlcmNlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlYWNpYWxFYXNpbmc6IHNwZWNpYWxFYXNpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwOiBzdGVwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWU6IHRpbWVTdGFydFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb2dyZXNzKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3Moe30sIHBlcmNlbnQsIE1BVEgubWF4KDAsIGR1cmF0aW9uIC0gZWxhcHNlZCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oY29tcGxldGUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqLmZyYW1lID0gQ09NUEFUSUJJTElUWS5yQUYoKShmcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5mcmFtZSA9IENPTVBBVElCSUxJVFkuckFGKCkoZnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gdG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgdG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChndWFyYW50ZWVkTmV4dClcclxuICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0b3AoZWwsIGNsZWFyUSwganVtcFRvRW5kKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW5pbU9iajtcclxuICAgICAgICAgICAgICAgIHZhciBxT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iaiA9IF9hbmltYXRpb25zW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbU9iai5xW0xFWElDT04ubF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqID0gYW5pbU9iai5xWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5zdG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkocU9iai5mcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEuc3BsaWNlKDAsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqdW1wVG9FbmQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gcU9iai5wcm9wcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgcU9iai5wcm9wc1trZXldKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xlYXJRKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1PYmoucSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBlbGVtZW50SXNWaXNpYmxlKGVsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gISEoZWxbTEVYSUNPTi5vV10gfHwgZWxbTEVYSUNPTi5vSF0gfHwgZWwuZ2V0Q2xpZW50UmVjdHMoKVtMRVhJQ09OLmxdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gRmFrZWpRdWVyeShzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tMRVhJQ09OLmxdID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBiYXNlID0gbmV3IEZha2VqUXVlcnkoKTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IHNlbGVjdG9yO1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsbXM7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWw7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHNlbGVjdG9yKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IuY2hhckF0KDApID09PSAnPCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gc2VsZWN0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBlbC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZWxtc1tpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKGVsZW1lbnRzKSAhPSBUWVBFUy5zICYmICghaXNBcnJheUxpa2UoZWxlbWVudHMpIHx8IGVsZW1lbnRzID09PSB3aW5kb3cgfHwgZWxlbWVudHMgPT09IGVsZW1lbnRzLnNlbGYpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlbGVtZW50c1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VbaV0gPSBlbGVtZW50c1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZVtMRVhJQ09OLmxdID0gZWxlbWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIEZha2VqUXVlcnlbTEVYSUNPTi5wXSA9IHtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0VWRU5UUzpcclxuXHJcbiAgICAgICAgICAgICAgICBvbjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TmFtZSA9IChldmVudE5hbWUgfHwgX3N0ckVtcHR5KS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW19zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWVMZW5ndGggPSBldmVudE5hbWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwuYWRkRXZlbnRMaXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lW2ldLCBoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsLmRldGFjaEV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBvZmY6IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudE5hbWUgPSAoZXZlbnROYW1lIHx8IF9zdHJFbXB0eSkubWF0Y2goX3Jub3RodG1sd2hpdGUpIHx8IFtfc3RyRW1wdHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnROYW1lTGVuZ3RoID0gZXZlbnROYW1lW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50TmFtZUxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWVbaV0sIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgb25lOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnROYW1lID0gKGV2ZW50TmFtZSB8fCBfc3RyRW1wdHkpLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbX3N0ckVtcHR5XTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgRmFrZWpRdWVyeS5lYWNoKGV2ZW50TmFtZSwgZnVuY3Rpb24gKGksIG9uZUV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uZUhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vZmYob25lRXZlbnROYW1lLCBvbmVIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vbihvbmVFdmVudE5hbWUsIG9uZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5pbml0RXZlbnQoZXZlbnROYW1lLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmZpcmVFdmVudCgnb24nICsgZXZlbnROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvL0RPTSBOT0RFIElOU0VSVElORyAvIFJFTU9WSU5HOlxyXG5cclxuICAgICAgICAgICAgICAgIGFwcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlZW5kJywgY2hpbGQpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcHJlcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJiZWdpbicsIGNoaWxkKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGJlZm9yZTogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlYmVnaW4nLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBhZnRlcjogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJlbmQnLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBlbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHVud3JhcDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkocGFyZW50LCBwYXJlbnRzKSA9PT0gLSAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKHBhcmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJlbnRzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHBhcmVudHNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShlbC5maXJzdENoaWxkLCBlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcEFsbDogZnVuY3Rpb24gKHdyYXBwZXJIVE1MKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd3JhcHBlciA9IEZha2VqUXVlcnkod3JhcHBlckhUTUwpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkZWVwZXN0ID0gd3JhcHBlcjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbm9kZXNbMF0ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gbm9kZXNbMF0ucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChkZWVwZXN0LmNoaWxkTm9kZXNbTEVYSUNPTi5sXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZXBlc3QgPSBkZWVwZXN0LmNoaWxkTm9kZXNbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IG5vZGVzW0xFWElDT04ubF0gLSBpOyBkZWVwZXN0LmZpcnN0Q2hpbGQgPT09IG5vZGVzWzBdICYmIGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVlcGVzdC5hcHBlbmRDaGlsZChub2Rlc1tpXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXh0U2libGluZyA9IHByZXZpb3VzU2libGluZyA/IHByZXZpb3VzU2libGluZy5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod3JhcHBlciwgbmV4dFNpYmxpbmcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcElubmVyOiBmdW5jdGlvbiAod3JhcHBlckhUTUwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRzID0gZWwuY29udGVudHMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50c1tMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudHMud3JhcEFsbCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFwcGVuZCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHdyYXA6IGZ1bmN0aW9uICh3cmFwcGVySFRNTCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBGYWtlalF1ZXJ5KHRoaXMpLndyYXBBbGwod3JhcHBlckhUTUwpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIE5PREUgTUFOSVBVTEFUSU9OIC8gSU5GT1JNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgY3NzOiBmdW5jdGlvbiAoc3R5bGVzLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3B0U3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldENwdFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKHN0eWxlcykgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwdFN0eWxlID0gZ2V0Q3B0U3R5bGUgPyBnZXRDcHRTdHlsZShlbCwgbnVsbCkgOiBlbC5jdXJyZW50U3R5bGVbc3R5bGVzXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2h0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTU0ODM5NyBjYW4gYmUgbnVsbCBzb21ldGltZXMgaWYgaWZyYW1lIHdpdGggZGlzcGxheTogbm9uZSAoZmlyZWZveCBvbmx5ISlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRDcHRTdHlsZSA/IGNwdFN0eWxlICE9IG51bGwgPyBjcHRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlcykgOiBlbFtMRVhJQ09OLnNdW3N0eWxlc10gOiBjcHRTdHlsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENTU1ZhbCh0aGlzLCBzdHlsZXMsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBzdHlsZXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKHRoaXMsIGtleSwgc3R5bGVzW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGhhc0NsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW0sIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVQcmVwYXJlZCA9IF9zdHJTcGFjZSArIGNsYXNzTmFtZSArIF9zdHJTcGFjZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NMaXN0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NMaXN0ICYmIGNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoZWxlbS5jbGFzc05hbWUgKyBfc3RyRW1wdHkpICsgX3N0clNwYWNlKS5pbmRleE9mKGNsYXNzTmFtZVByZXBhcmVkKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGFkZENsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXp6O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdXBwb3J0Q2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG1DbGFzc0xpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoZWxlbSA9IHRoaXNbaSsrXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0Q2xhc3NMaXN0ID0gZWxtQ2xhc3NMaXN0ICE9PSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxtQ2xhc3NMaXN0LmFkZChjbGF6eik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJWYWx1ZSA9IGVsZW0uY2xhc3NOYW1lICsgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoY3VyVmFsdWUpICsgX3N0clNwYWNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIuaW5kZXhPZihfc3RyU3BhY2UgKyBjbGF6eiArIF9zdHJTcGFjZSkgPCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciArPSBjbGF6eiArIF9zdHJTcGFjZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKGN1cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NOYW1lID0gZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmVDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc2VzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1clZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGF6ejtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydENsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxtQ2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbG1DbGFzc0xpc3QgPSBlbGVtLmNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydENsYXNzTGlzdCA9IGVsbUNsYXNzTGlzdCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdC5yZW1vdmUoY2xhenopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyVmFsdWUgPSBlbGVtLmNsYXNzTmFtZSArIF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmIChfc3RyU3BhY2UgKyBzdHJpcEFuZENvbGxhcHNlKGN1clZhbHVlKSArIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY3VyLmluZGV4T2YoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UpID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyID0gY3VyLnJlcGxhY2UoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UsIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gc3RyaXBBbmRDb2xsYXBzZShjdXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgaGlkZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyB0aGlzW0xFWElDT04uc10uZGlzcGxheSA9ICdub25lJzsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHNob3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgdGhpc1tMRVhJQ09OLnNdLmRpc3BsYXkgPSAnYmxvY2snOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgYXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGVsID0gdGhpc1tpKytdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZShhdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlQXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHRoaXMucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIG9mZnNldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBlbFtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTGVmdCA9IHdpbmRvdy5wYWdlWE9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbX3N0clNjcm9sbExlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxUb3AgPSB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W19zdHJTY3JvbGxUb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyBzY3JvbGxUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHNjcm9sbExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBlbC5vZmZzZXRUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IGVsLm9mZnNldExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzY3JvbGxMZWZ0OiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsTGVmdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsW19zdHJTY3JvbGxMZWZ0XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsVG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbX3N0clNjcm9sbFRvcF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHZhbDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWwudmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIFRSQVZFUlNBTCAvIEZJTFRFUklORzpcclxuXHJcbiAgICAgICAgICAgICAgICBmaXJzdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKDApO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBsYXN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXEoLTEpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBlcTogZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnkodGhpc1tpbmRleCA+PSAwID8gaW5kZXggOiB0aGlzW0xFWElDT04ubF0gKyBpbmRleF0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBmaW5kOiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ggPSBlbC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gdGhpcy5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBjaFtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZWwubWF0Y2hlcyAmJiBlbC5tYXRjaGVzKHNlbGVjdG9yKSkgfHwgbWF0Y2hlcyhlbCwgc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcGFyZW50OiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPyBGYWtlalF1ZXJ5KHBhcmVudCkuaXMoc2VsZWN0b3IpIDogdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMucHVzaChwYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KHBhcmVudHMpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBpczogZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPT09ICc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudElzVmlzaWJsZShlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvciA9PT0gJzpoaWRkZW4nKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFlbGVtZW50SXNWaXNpYmxlKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChlbC5tYXRjaGVzICYmIGVsLm1hdGNoZXMoc2VsZWN0b3IpKSB8fCBtYXRjaGVzKGVsLCBzZWxlY3RvcikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBjb250ZW50czogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcyA9IHRoaXMuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoaWxkc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cy5wdXNoKGNoaWxkc1tpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNvbnRlbnRzKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgZWFjaDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVhY2godGhpcywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy9BTklNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgYW5pbWF0ZTogZnVuY3Rpb24gKHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBhbmltYXRlKHRoaXMsIHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzdG9wOiBmdW5jdGlvbiAoY2xlYXJRLCBqdW1wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHN0b3AodGhpcywgY2xlYXJRLCBqdW1wKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBleHRlbmQoRmFrZWpRdWVyeSwge1xyXG4gICAgICAgICAgICAgICAgZXh0ZW5kOiBleHRlbmQsXHJcbiAgICAgICAgICAgICAgICBpbkFycmF5OiBpbkFycmF5LFxyXG4gICAgICAgICAgICAgICAgaXNFbXB0eU9iamVjdDogaXNFbXB0eU9iamVjdCxcclxuICAgICAgICAgICAgICAgIGlzUGxhaW5PYmplY3Q6IGlzUGxhaW5PYmplY3QsXHJcbiAgICAgICAgICAgICAgICBlYWNoOiBlYWNoXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgICAgICB2YXIgSU5TVEFOQ0VTID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF90YXJnZXRzID0gW107XHJcbiAgICAgICAgICAgIHZhciBfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZyA9ICdfX292ZXJsYXlTY3JvbGxiYXJzX18nO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZ2lzdGVyLCB1bnJlZ2lzdGVyIG9yIGdldCBhIGNlcnRhaW4gKG9yIGFsbCkgaW5zdGFuY2VzLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgdGFyZ2V0IGFuZCB0aGUgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIFVucmVnaXN0ZXI6IFBhc3MgdGhlIHRhcmdldCBhbmQgbnVsbC5cclxuICAgICAgICAgICAgICogR2V0IEluc3RhbmNlOiBQYXNzIHRoZSB0YXJnZXQgZnJvbSB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgVGFyZ2V0czogUGFzcyBubyBhcmd1bWVudHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCB0byB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgcmVnaXN0ZXJlZCAvIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIHVucmVnaXN0ZXJlZCAvIHRoZSBpbnN0YW5jZSBzaGFsbCBiZSBnb3RcclxuICAgICAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIFRoZSBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp8dm9pZH0gUmV0dXJucyB0aGUgaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gdGFyZ2V0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXJnTGVuID0gYXJndW1lbnRzW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJnTGVuIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGFsbCB0YXJnZXRzXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgaW5zdGFuY2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W19pbnN0YW5jZVByb3BlcnR5U3RyaW5nXSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0cy5wdXNoKHRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBDT01QQVRJQklMSVRZLmluQSh0YXJnZXQsIF90YXJnZXRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPiAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91bnJlZ2lzdGVyIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRhcmdldFtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IGluc3RhbmNlIGZyb20gdGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzW2luZGV4XVtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBQTFVHSU4gPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX3BsdWdpbjtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zR2xvYmFscztcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3A7XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc0V4dGVuc2lvbnMgPSBbXTtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zT3B0aW9ucyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZVRlbXBsYXRlVHlwZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMuYiwgLy9ib29sZWFuXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMubiwgLy9udW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5zLCAvL3N0cmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmEsIC8vYXJyYXlcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5vLCAvL29iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmYsIC8vZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy56ICAvL251bGxcclxuICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ3NTcGxpdCA9ICcgJztcclxuICAgICAgICAgICAgICAgIHZhciByZXN0cmljdGVkU3RyaW5nc1Bvc3NpYmlsaXRpZXNTcGxpdCA9ICc6JztcclxuICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVBbGxvd2VkVmFsdWVzID0gW1RZUEVTLnosIFRZUEVTLnNdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG51bWJlckFsbG93ZWRWYWx1ZXMgPSBUWVBFUy5uO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlcyA9IFtUWVBFUy56LCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBib29sZWFuVHJ1ZVRlbXBsYXRlID0gW3RydWUsIFRZUEVTLmJdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5GYWxzZVRlbXBsYXRlID0gW2ZhbHNlLCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBjYWxsYmFja1RlbXBsYXRlID0gW251bGwsIFtUWVBFUy56LCBUWVBFUy5mXV07XHJcbiAgICAgICAgICAgICAgICB2YXIgdXBkYXRlT25Mb2FkVGVtcGxhdGUgPSBbWydpbWcnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciBpbmhlcml0ZWRBdHRyc1RlbXBsYXRlID0gW1snc3R5bGUnLCAnY2xhc3MnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciByZXNpemVBbGxvd2VkVmFsdWVzID0gJ246bm9uZSBiOmJvdGggaDpob3Jpem9udGFsIHY6dmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JBbGxvd2VkVmFsdWVzID0gJ3YtaDp2aXNpYmxlLWhpZGRlbiB2LXM6dmlzaWJsZS1zY3JvbGwgczpzY3JvbGwgaDpoaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5QWxsb3dlZFZhbHVlcyA9ICd2OnZpc2libGUgaDpoaWRkZW4gYTphdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVBbGxvd2VkVmFsdWVzID0gJ246bmV2ZXIgczpzY3JvbGwgbDpsZWF2ZSBtOm1vdmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogWydvcy10aGVtZS1kYXJrJywgY2xhc3NOYW1lQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBzdHJpbmdcclxuICAgICAgICAgICAgICAgICAgICByZXNpemU6IFsnbm9uZScsIHJlc2l6ZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vbmUgfHwgYm90aCAgfHwgaG9yaXpvbnRhbCB8fCB2ZXJ0aWNhbCB8fCBuIHx8IGIgfHwgaCB8fCB2XHJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZUF1dG9DYXBhYmxlOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgY2xpcEFsd2F5czogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplUlRMOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0Fic29sdXRlOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZTogW251bGwsIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlIHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlSW50ZXJ2YWw6IFszMywgbnVtYmVyQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAvL251bWJlclxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZU9uTG9hZDogdXBkYXRlT25Mb2FkVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvd05hdGl2ZVNjcm9sbGJhcnM6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbGl6ZTogYm9vbGVhblRydWVUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QmVoYXZpb3I6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogWydzY3JvbGwnLCBvdmVyZmxvd0JlaGF2aW9yQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAvL3Zpc2libGUtaGlkZGVuICB8fCB2aXNpYmxlLXNjcm9sbCB8fCBoaWRkZW4gfHwgc2Nyb2xsIHx8IHYtaCB8fCB2LXMgfHwgaCB8fCBzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IFsnc2Nyb2xsJywgb3ZlcmZsb3dCZWhhdmlvckFsbG93ZWRWYWx1ZXNdICAgICAgICAgICAgICAgICAgICAgLy92aXNpYmxlLWhpZGRlbiAgfHwgdmlzaWJsZS1zY3JvbGwgfHwgaGlkZGVuIHx8IHNjcm9sbCB8fCB2LWggfHwgdi1zIHx8IGggfHwgc1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBbJ2F1dG8nLCBzY3JvbGxiYXJzVmlzaWJpbGl0eUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgIC8vdmlzaWJsZSB8fCBoaWRkZW4gfHwgYXV0byB8fCB2IHx8IGggfHwgYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogWyduZXZlcicsIHNjcm9sbGJhcnNBdXRvSGlkZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgIC8vbmV2ZXIgfHwgc2Nyb2xsIHx8IGxlYXZlIHx8IG1vdmUgfHwgbiB8fCBzIHx8IGwgfHwgbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZURlbGF5OiBbODAwLCBudW1iZXJBbGxvd2VkVmFsdWVzXSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdTY3JvbGxpbmc6IGJvb2xlYW5UcnVlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrU2Nyb2xsaW5nOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdWNoU3VwcG9ydDogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBIYW5kbGU6IGJvb2xlYW5GYWxzZVRlbXBsYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5XaWR0aDogYm9vbGVhbkZhbHNlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5IZWlnaHQ6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRBdHRyczogaW5oZXJpdGVkQXR0cnNUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemVkOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemF0aW9uV2l0aGRyYXduOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRlc3Ryb3llZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0YXJ0OiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0b3A6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93QW1vdW50Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRpcmVjdGlvbkNoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNvbnRlbnRTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkhvc3RTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblVwZGF0ZWQ6IGNhbGxiYWNrVGVtcGxhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB2YXIgY29udmVydCA9IGZ1bmN0aW9uICh0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWN1cnNpdmUgPSBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWxUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb2JqW0xFWElDT04uaE9QXShrZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxUeXBlID0gdHlwZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbFR5cGUgPT0gVFlQRVMuYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbFt0ZW1wbGF0ZSA/IDEgOiAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbFR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHJlY3Vyc2l2ZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVjdXJzaXZlKEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlKSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RlZmF1bHRzOiBjb252ZXJ0KCksXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF90ZW1wbGF0ZTogY29udmVydCh0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogVmFsaWRhdGVzIHRoZSBwYXNzZWQgb2JqZWN0IGJ5IHRoZSBwYXNzZWQgdGVtcGxhdGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IHdoaWNoIHNoYWxsIGJlIHZhbGlkYXRlZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHdoaWNoIGRlZmluZXMgdGhlIGFsbG93ZWQgdmFsdWVzIGFuZCB0eXBlcy5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gd3JpdGVFcnJvcnMgVHJ1ZSBpZiBlcnJvcnMgc2hhbGwgYmUgbG9nZ2VkIHRvIHRoZSBjb25zb2xlLlxyXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkaWZmT2JqIElmIGEgb2JqZWN0IGlzIHBhc3NlZCB0aGVuIG9ubHkgdmFsaWQgZGlmZmVyZW5jZXMgdG8gdGhpcyBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e319IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHR3byBvYmplY3RzIGNhbGxlZCBcImRlZmF1bHRcIiBhbmQgXCJwcmVwYXJlZFwiIHdoaWNoIGNvbnRhaW5zIG9ubHkgdGhlIHZhbGlkIHByb3BlcnRpZXMgb2YgdGhlIHBhc3NlZCBvcmlnaW5hbCBvYmplY3QgYW5kIGRpc2NhcmRzIG5vdCBkaWZmZXJlbnQgdmFsdWVzIGNvbXBhcmVkIHRvIHRoZSBwYXNzZWQgZGlmZk9iai5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfdmFsaWRhdGU6IGZ1bmN0aW9uIChvYmosIHRlbXBsYXRlLCB3cml0ZUVycm9ycywgZGlmZk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9ucyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3RDb3B5ID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluQXJyYXkgPSBGUkFNRVdPUksuaW5BcnJheTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRW1wdHlPYmogPSBGUkFNRVdPUksuaXNFbXB0eU9iamVjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrT2JqZWN0UHJvcHMgPSBmdW5jdGlvbiAoZGF0YSwgdGVtcGxhdGUsIGRpZmZEYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIHByZXZQcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZVtMRVhJQ09OLmhPUF0ocHJvcCkgJiYgZGF0YVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRGlmZiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZSA9IHRlbXBsYXRlW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZVR5cGUgPSB0eXBlKHRlbXBsYXRlVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVJc0NvbXBsZXggPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5vO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVUeXBlcyA9ICFDT01QQVRJQklMSVRZLmlzQSh0ZW1wbGF0ZVZhbHVlKSA/IFt0ZW1wbGF0ZVZhbHVlXSA6IHRlbXBsYXRlVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhRGlmZlZhbHVlID0gZGlmZkRhdGFbcHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhVmFsdWUgPSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YVZhbHVlVHlwZSA9IHR5cGUoZGF0YVZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BQcmVmaXggPSBwcmV2UHJvcE5hbWUgPyBwcmV2UHJvcE5hbWUgKyAnLicgOiAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gXCJUaGUgb3B0aW9uIFxcXCJcIiArIHByb3BQcmVmaXggKyBwcm9wICsgXCJcXFwiIHdhc24ndCBzZXQsIGJlY2F1c2VcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yUG9zc2libGVUeXBlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3JSZXN0cmljdGVkU3RyaW5ncyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzUmVzdHJpY3RlZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFpblBvc3NpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclR5cGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGo7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRGlmZlZhbHVlID0gZGF0YURpZmZWYWx1ZSA9PT0gdW5kZWZpbmVkID8ge30gOiBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgdGVtcGxhdGUgaGFzIGEgb2JqZWN0IGFzIHZhbHVlLCBpdCBtZWFucyB0aGF0IHRoZSBvcHRpb25zIGFyZSBjb21wbGV4ICh2ZXJzY2hhY2h0ZWx0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVJc0NvbXBsZXggJiYgZGF0YVZhbHVlVHlwZSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrT2JqZWN0UHJvcHMoZGF0YVZhbHVlLCB0ZW1wbGF0ZVZhbHVlLCBkYXRhRGlmZlZhbHVlLCB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0sIHByb3BQcmVmaXggKyBwcm9wKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKFtkYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRdLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHlPYmoodmFsdWVbcHJvcF0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghdGVtcGxhdGVJc0NvbXBsZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZW1wbGF0ZVR5cGVzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJUeXBlID0gdGVtcGxhdGVUeXBlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhbHVlVHlwZSA9IHR5cGUoY3VyclR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgY3VycnR5cGUgaXMgc3RyaW5nIGFuZCBzdGFydHMgd2l0aCByZXN0cmljdGVkU3RyaW5nUHJlZml4IGFuZCBlbmQgd2l0aCByZXN0cmljdGVkU3RyaW5nU3VmZml4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSZXN0cmljdGVkVmFsdWUgPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5zICYmIGluQXJyYXkoY3VyclR5cGUsIHBvc3NpYmxlVGVtcGxhdGVUeXBlcykgPT09IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3RyaWN0ZWRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclBvc3NpYmxlVHlwZXMucHVzaChUWVBFUy5zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgaXQgaW50byBhIGFycmF5IHdoaWNoIGNvbnRhaW5zIGFsbCBwb3NzaWJsZSB2YWx1ZXMgZm9yIGV4YW1wbGU6IFtcInk6eWVzXCIsIFwibjpub1wiLCBcIm06bWF5YmVcIl1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0ID0gY3VyclR5cGUuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NTcGxpdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVzdHJpY3RlZFN0cmluZ3MgPSBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmNvbmNhdChyZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0W0xFWElDT04ubF07IHYrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zcGxpdCB0aGUgcG9zc2libGUgdmFsdWVzIGludG8gdGhlaXIgcG9zc2liaWxpdGVpcyBmb3IgZXhhbXBsZTogW1wieVwiLCBcInllc1wiXSAtPiB0aGUgZmlyc3QgaXMgYWx3YXlzIHRoZSBtYWluUG9zc2liaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQgPSByZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXRbdl0uc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpblBvc3NpYmlsaXR5ID0gcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W0xFWElDT04ubF07IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgYW55IHBvc3NpYmlsaXR5IG1hdGNoZXMgd2l0aCB0aGUgZGF0YVZhbHVlLCBpdHMgdmFsaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVZhbHVlID09PSByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W2pdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNWYWxpZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JQb3NzaWJsZVR5cGVzLnB1c2goY3VyclR5cGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFWYWx1ZVR5cGUgPT09IGN1cnJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNEaWZmID0gZGF0YVZhbHVlICE9PSBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEaWZmKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0gZGF0YVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN0cmljdGVkVmFsdWUgPyBpbkFycmF5KGRhdGFEaWZmVmFsdWUsIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQpIDwgMCA6IGlzRGlmZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkW3Byb3BdID0gaXNSZXN0cmljdGVkVmFsdWUgPyBtYWluUG9zc2liaWxpdHkgOiBkYXRhVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh3cml0ZUVycm9ycykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvciArIFwiIGl0IGRvZXNuJ3QgYWNjZXB0IHRoZSB0eXBlIFsgXCIgKyBkYXRhVmFsdWVUeXBlLnRvVXBwZXJDYXNlKCkgKyBcIiBdIHdpdGggdGhlIHZhbHVlIG9mIFxcXCJcIiArIGRhdGFWYWx1ZSArIFwiXFxcIi5cXHJcXG5cIiArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQWNjZXB0ZWQgdHlwZXMgYXJlOiBbIFwiICsgZXJyb3JQb3NzaWJsZVR5cGVzLmpvaW4oJywgJykudG9VcHBlckNhc2UoKSArIFwiIF0uXCIgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3JSZXN0cmljdGVkU3RyaW5nc1tsZW5ndGhdID4gMCA/IFwiXFxyXFxuVmFsaWQgc3RyaW5ncyBhcmU6IFsgXCIgKyBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmpvaW4oJywgJykuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpLmpvaW4oJywgJykgKyBcIiBdLlwiIDogJycpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja09iamVjdFByb3BzKG9iamVjdENvcHksIHRlbXBsYXRlLCBkaWZmT2JqIHx8IHt9LCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdmFsdWVzIHdoaWNoIGFyZW4ndCBzcGVjaWZpZWQgaW4gdGhlIHRlbXBsYXRlIHRvIHRoZSBmaW5pc2hlZCB2YWxpZGF0ZWQgb2JqZWN0IHRvIHByZXZlbnQgdGhlbSBmcm9tIGJlaW5nIGRpc2NhcmRlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihrZWVwRm9yZWlnblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHZhbGlkYXRlZE9wdGlvbnMsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICovXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmoob2JqZWN0Q29weSkgJiYgd3JpdGVFcnJvcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgZGlzY2FyZGVkIGR1ZSB0byBpbnZhbGlkaXR5OlxcclxcbicgKyB3aW5kb3cuSlNPTi5zdHJpbmdpZnkob2JqZWN0Q29weSwgbnVsbCwgMikpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0OiB2YWxpZGF0ZWRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByZXBhcmVkOiB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0oKSk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgdGhlIG9iamVjdCB3aGljaCBjb250YWlucyBnbG9iYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBsdWdpbiBhbmQgZWFjaCBpbnN0YW5jZSBvZiBpdC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9wbHVnaW5zR2xvYmFscylcclxuICAgICAgICAgICAgICAgICAgICBfcGx1Z2luc0dsb2JhbHMgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKF9wbHVnaW5zT3B0aW9ucy5fZGVmYXVsdHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfcGx1Z2luc0F1dG9VcGRhdGVMb29wKVxyXG4gICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3AgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RzLiBJdCBjb250YWlucyByZXNvdXJjZXMgd2hpY2ggZXZlcnkgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IG5lZWRzLiBUaGlzIG9iamVjdCBpcyBpbml0aWFsaXplZCBvbmx5IG9uY2U6IGlmIHRoZSBmaXJzdCBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3QgZ2V0cyBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGRlZmF1bHRPcHRpb25zXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93ID0gJ292ZXJmbG93JztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJIaWRkZW4gPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJTY3JvbGwgPSAnc2Nyb2xsJztcclxuICAgICAgICAgICAgICAgIHZhciBib2R5RWxlbWVudCA9IEZSQU1FV09SSygnYm9keScpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckR1bW15RWxlbWVudCA9IEZSQU1FV09SSygnPGRpdiBpZD1cIm9zLWR1bW15LXNjcm9sbGJhci1zaXplXCI+PGRpdj48L2Rpdj48L2Rpdj4nKTtcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJEdW1teUVsZW1lbnQwID0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGQgPSBGUkFNRVdPUksoc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmNoaWxkcmVuKCdkaXYnKS5lcSgwKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuaGlkZSgpLnNob3coKTsgLy9maXggSUU4IGJ1ZyAoaW5jb3JyZWN0IG1lYXN1cmluZylcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgbmF0aXZlU2Nyb2xsYmFyU2l6ZSA9IGNhbGNOYXRpdmVTY3JvbGxiYXJTaXplKHNjcm9sbGJhckR1bW15RWxlbWVudDApO1xyXG4gICAgICAgICAgICAgICAgdmFyIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeDogbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ID09PSAwLFxyXG4gICAgICAgICAgICAgICAgICAgIHk6IG5hdGl2ZVNjcm9sbGJhclNpemUueSA9PT0gMFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHZhciBtc2llID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySW5kZXhPZiA9ICdpbmRleE9mJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyU3ViU3RyaW5nID0gJ3N1YnN0cmluZyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1zaWUgPSB1YVtzdHJJbmRleE9mXSgnTVNJRSAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJpZGVudCA9IHVhW3N0ckluZGV4T2ZdKCdUcmlkZW50LycpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlZGdlID0gdWFbc3RySW5kZXhPZl0oJ0VkZ2UvJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJ2ID0gdWFbc3RySW5kZXhPZl0oJ3J2OicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlSW50RnVuYyA9IHBhcnNlSW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAobXNpZSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlSW50RnVuYyh1YVtzdHJTdWJTdHJpbmddKG1zaWUgKyA1LCB1YVtzdHJJbmRleE9mXSgnLicsIG1zaWUpKSwgMTApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0cmlkZW50ID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10ocnYgKyAzLCB1YVtzdHJJbmRleE9mXSgnLicsIHJ2KSksIDEwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlZGdlID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10oZWRnZSArIDUsIHVhW3N0ckluZGV4T2ZdKCcuJywgZWRnZSkpLCAxMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXJcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKF9iYXNlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE9wdGlvbnM6IGRlZmF1bHRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgIG1zaWU6IG1zaWUsXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3A6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGVSZWNvbW1lbmRlZDogIUNPTVBBVElCSUxJVFkubU8oKSxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplOiBuYXRpdmVTY3JvbGxiYXJTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQ6IG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyU3R5bGluZzogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuYWRkQ2xhc3MoJ29zLXZpZXdwb3J0LW5hdGl2ZS1zY3JvbGxiYXJzLWludmlzaWJsZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoJ3Njcm9sbGJhci13aWR0aCcpID09PSAnbm9uZScgJiYgKG1zaWUgPiA5IHx8ICFtc2llKSkgfHwgd2luZG93LmdldENvbXB1dGVkU3R5bGUoc2Nyb2xsYmFyRHVtbXlFbGVtZW50MCwgJzo6LXdlYmtpdC1zY3JvbGxiYXInKS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXNwbGF5JykgPT09ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggb3BlcmEgYnVnOiBzY3JvbGxiYXIgc3R5bGVzIHdpbGwgb25seSBhcHBlYXIgaWYgb3ZlcmZsb3cgdmFsdWUgaXMgc2Nyb2xsIG9yIGF1dG8gZHVyaW5nIHRoZSBhY3RpdmF0aW9uIG9mIHRoZSBzdHlsZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgc2V0IG92ZXJmbG93IHRvIHNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csIHN0ckhpZGRlbikuaGlkZSgpLmNzcyhzdHJPdmVyZmxvdywgc3RyU2Nyb2xsKS5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIChzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04ub0hdIC0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLmNIXSkgPT09IDAgJiYgKHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5vV10gLSBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uY1ddKSA9PT0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplOiB7IHg6IDMwLCB5OiAzMCB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNzc0NhbGM6IFZFTkRPUlMuX2Nzc1Byb3BlcnR5VmFsdWUoJ3dpZHRoJywgJ2NhbGMnLCAnKDFweCknKSB8fCBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRNZWFzdXJpbmc6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQzOTMwNVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NpbmNlIDEuMTEuMCBhbHdheXMgZmFsc2UgLT4gZml4ZWQgdmlhIENTUyAoaG9wZWZ1bGx5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHN0ck92ZXJmbG93LCBzdHJIaWRkZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csICd2aXNpYmxlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxTaXplMiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2Nyb2xsU2l6ZS53IC0gc2Nyb2xsU2l6ZTIudykgIT09IDAgfHwgKHNjcm9sbFNpemUuaCAtIHNjcm9sbFNpemUyLmgpICE9PSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgcnRsU2Nyb2xsQmVoYXZpb3I6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoeyAnb3ZlcmZsb3cteSc6IHN0ckhpZGRlbiwgJ292ZXJmbG93LXgnOiBzdHJTY3JvbGwsICdkaXJlY3Rpb24nOiAncnRsJyB9KS5zY3JvbGxMZWZ0KDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlDb250YWluZXJPZmZzZXQgPSBzY3JvbGxiYXJEdW1teUVsZW1lbnQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0ID0gZHVtbXlDb250YWluZXJDaGlsZC5vZmZzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9odHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmEvT3ZlcmxheVNjcm9sbGJhcnMvaXNzdWVzLzE4N1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuc2Nyb2xsTGVmdCgtOTk5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGRPZmZzZXRBZnRlclNjcm9sbCA9IGR1bW15Q29udGFpbmVyQ2hpbGQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29yaWdpbiBkaXJlY3Rpb24gPSBkZXRlcm1pbmVzIGlmIHRoZSB6ZXJvIHNjcm9sbCBwb3NpdGlvbiBpcyBvbiB0aGUgbGVmdCBvciByaWdodCBzaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLydpJyBtZWFucyAnaW52ZXJ0JyAoaSA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgaW52ZXJ0ZWQgdG8gYmUgY29ycmVjdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSA9IG9uIHRoZSBsZWZ0IHNpZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBvbiB0aGUgcmlnaHQgc2lkZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaTogZHVtbXlDb250YWluZXJPZmZzZXQubGVmdCA9PT0gZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9uZWdhdGl2ZSA9IGRldGVybWluZXMgaWYgdGhlIG1heGltdW0gc2Nyb2xsIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyduJyBtZWFucyAnbmVnYXRlJyAobiA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgbmVnYXRlZCB0byBiZSBjb3JyZWN0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlID0gbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBwb3NpdGl2ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbjogZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0ICE9PSBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0QWZ0ZXJTY3JvbGwubGVmdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zZm9ybTogISFWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zaXRpb246ICEhVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zaXRpb24nKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UGFzc2l2ZUV2ZW50czogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN1cHBvcnRzUGFzc2l2ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBudWxsLCBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c1Bhc3NpdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBwb3J0c1Bhc3NpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UmVzaXplT2JzZXJ2ZXI6ICEhQ09NUEFUSUJJTElUWS5yTygpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRNdXRhdGlvbk9ic2VydmVyOiAhIUNPTVBBVElCSUxJVFkubU8oKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi5zKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0NhdGNoIHpvb20gZXZlbnQ6XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhYnMgPSBNQVRILmFicztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93V2lkdGggPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93RHByID0gZ2V0V2luZG93RFBSKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1cgPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YVcgPSBuZXdXIC0gd2luZG93V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGFIID0gbmV3SCAtIHdpbmRvd0hlaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsdGFXID09PSAwICYmIGRlbHRhSCA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhV1JhdGlvID0gTUFUSC5yb3VuZChuZXdXIC8gKHdpbmRvd1dpZHRoIC8gMTAwLjApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YUhSYXRpbyA9IE1BVEgucm91bmQobmV3SCAvICh3aW5kb3dIZWlnaHQgLyAxMDAuMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhVyA9IGFicyhkZWx0YVcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhSCA9IGFicyhkZWx0YUgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhV1JhdGlvID0gYWJzKGRlbHRhV1JhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YUhSYXRpbyA9IGFicyhkZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3RFBSID0gZ2V0V2luZG93RFBSKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhSXNCaWdnZXIgPSBhYnNEZWx0YVcgPiAyICYmIGFic0RlbHRhSCA+IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZmVyZW5jZSA9ICFkaWZmZXJlbmNlSXNCaWdnZXJUaGFuT25lKGFic0RlbHRhV1JhdGlvLCBhYnNEZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHByQ2hhbmdlZCA9IG5ld0RQUiAhPT0gd2luZG93RHByICYmIHdpbmRvd0RwciA+IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNab29tID0gZGVsdGFJc0JpZ2dlciAmJiBkaWZmZXJlbmNlICYmIGRwckNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2xkU2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2Nyb2xsYmFyU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNab29tKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemUgPSBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShzY3JvbGxiYXJEdW1teUVsZW1lbnRbMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkU2Nyb2xsYmFyU2l6ZS54ICE9PSBuZXdTY3JvbGxiYXJTaXplLnggfHwgb2xkU2Nyb2xsYmFyU2l6ZS55ICE9PSBuZXdTY3JvbGxiYXJTaXplLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmVhY2goSU5TVEFOQ0VTKCksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJTlNUQU5DRVModGhpcykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VTKHRoaXMpLnVwZGF0ZSgnem9vbScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93V2lkdGggPSBuZXdXO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93SGVpZ2h0ID0gbmV3SDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd0RwciA9IG5ld0RQUjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpZmZlcmVuY2VJc0JpZ2dlclRoYW5PbmUodmFsT25lLCB2YWxUd28pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic1ZhbE9uZSA9IGFicyh2YWxPbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWJzVmFsVHdvID0gYWJzKHZhbFR3byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhKGFic1ZhbE9uZSA9PT0gYWJzVmFsVHdvIHx8IGFic1ZhbE9uZSArIDEgPT09IGFic1ZhbFR3byB8fCBhYnNWYWxPbmUgLSAxID09PSBhYnNWYWxUd28pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0V2luZG93RFBSKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZERQSSA9IHdpbmRvdy5zY3JlZW4uZGV2aWNlWERQSSB8fCAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc0RQSSA9IHdpbmRvdy5zY3JlZW4ubG9naWNhbFhEUEkgfHwgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IChkRFBJIC8gc0RQSSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksod2luZG93KS5vbigncmVzaXplJywgb25SZXNpemUpO1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShtZWFzdXJlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub0hdIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub1ddIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIG9iamVjdCB3aGljaCBtYW5hZ2VzIHRoZSBhdXRvIHVwZGF0ZSBsb29wIGZvciBhbGwgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0cy4gVGhpcyBvYmplY3QgaXMgaW5pdGlhbGl6ZWQgb25seSBvbmNlOiBpZiB0aGUgZmlyc3QgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IGdldHMgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChnbG9iYWxzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2dldE5vdyA9IENPTVBBVElCSUxJVFkubm93O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlID0gJ2F1dG9VcGRhdGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlSW50ZXJ2YWwgPSBfc3RyQXV0b1VwZGF0ZSArICdJbnRlcnZhbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckxlbmd0aCA9IExFWElDT04ubDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcGluZ0luc3RhbmNlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcEludGVydmFsRGVmYXVsdCA9IDMzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSW50ZXJ2YWwgPSBfbG9vcEludGVydmFsRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcFRpbWVPbGQgPSBfZ2V0Tm93KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BJRDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgYXV0byB1cGRhdGUgbG9vcCB3aGljaCB3aWxsIHJ1biBldmVyeSA1MCBtaWxsaXNlY29uZHMgb3IgbGVzcyBpZiB0aGUgdXBkYXRlIGludGVydmFsIG9mIGEgaW5zdGFuY2UgaXMgbG93ZXIgdGhhbiA1MCBtaWxsaXNlY29uZHMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHZhciBsb29wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXSA+IDAgJiYgX2xvb3BJc0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElEID0gQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZU5ldyA9IF9nZXROb3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVEZWx0YSA9IHRpbWVOZXcgLSBfbG9vcFRpbWVPbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsb3dlc3RJbnRlcnZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVEZWx0YSA+IF9sb29wSW50ZXJ2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wVGltZU9sZCA9IHRpbWVOZXcgLSAodGltZURlbHRhICUgX2xvb3BJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBfbG9vcGluZ0luc3RhbmNlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZU9wdGlvbnMgPSBpbnN0YW5jZS5vcHRpb25zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQXV0b1VwZGF0ZUFsbG93ZWQgPSBpbnN0YW5jZU9wdGlvbnNbX3N0ckF1dG9VcGRhdGVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCA9IE1BVEgubWF4KDEsIGluc3RhbmNlT3B0aW9uc1tfc3RyQXV0b1VwZGF0ZUludGVydmFsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IF9nZXROb3coKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZCA9PT0gdHJ1ZSB8fCBpbnN0YW5jZUF1dG9VcGRhdGVBbGxvd2VkID09PSBudWxsKSAmJiAobm93IC0gX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlW2ldKSA+IGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS51cGRhdGUoJ2F1dG8nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZVtpXSA9IG5ldyBEYXRlKG5vdyArPSBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VzdEludGVydmFsID0gTUFUSC5tYXgoMSwgTUFUSC5taW4obG93ZXN0SW50ZXJ2YWwsIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IGxvd2VzdEludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgdG8gdGhlIGF1dG8gdXBkYXRlIGxvb3AuIE9ubHkgc3VjY2Vzc2Z1bCBpZiB0aGUgaW5zdGFuY2UgaXNuJ3QgYWxyZWFkeSBhZGRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpbnN0YW5jZSBUaGUgaW5zdGFuY2Ugd2hpY2ggc2hhbGwgYmUgdXBkYXRlZCBpbiBhIGxvb3AgYXV0b21hdGljYWxseS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UuYWRkID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnB1c2goaW5zdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlc0ludGVydmFsQ2FjaGUucHVzaChfZ2V0Tm93KCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2xvb3BpbmdJbnN0YW5jZXNbX3N0ckxlbmd0aF0gPiAwICYmICFfbG9vcElzQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElzQWN0aXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZSBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSBmcm9tIHRoZSBhdXRvIHVwZGF0ZSBsb29wLiBPbmx5IHN1Y2Nlc3NmdWwgaWYgdGhlIGluc3RhbmNlIHdhcyBhZGRlZCBiZWZvcmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaW5zdGFuY2UgVGhlIGluc3RhbmNlIHdoaWNoIHNoYWxsIGJlIHVwZGF0ZWQgaW4gYSBsb29wIGF1dG9tYXRpY2FsbHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnJlbW92ZSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgZnJvbSBsb29waW5nSW5zdGFuY2VzIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnNwbGljZShpbmRleCwgMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3QgdXBkYXRlIGxvb3AgYmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29waW5nSW5zdGFuY2VzW19zdHJMZW5ndGhdID09PSAwICYmIF9sb29wSXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29wSUQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkoX2xvb3BJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJRCA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgb2JqZWN0IHdoaWNoIG1hbmFnZXMgdGhlIHNjcm9sbGJhcnMgdmlzaWJpbGl0eSBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgaGlkZGVuLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgY3VzdG9tIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBjdXN0b20gZXh0ZW5zaW9ucy5cclxuICAgICAgICAgICAgICogQHBhcmFtIGdsb2JhbHNcclxuICAgICAgICAgICAgICogQHBhcmFtIGF1dG9VcGRhdGVMb29wXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2UocGx1Z2luVGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucywgZ2xvYmFscywgYXV0b1VwZGF0ZUxvb3ApIHtcclxuICAgICAgICAgICAgICAgIC8vc2hvcnRjdXRzXHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBpbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWFjaCA9IEZSQU1FV09SSy5lYWNoO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbWFrZSBjb3JyZWN0IGluc3RhbmNlb2ZcclxuICAgICAgICAgICAgICAgIHZhciBfYmFzZSA9IG5ldyBfcGx1Z2luKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2ZyYW1ld29ya1Byb3RvID0gRlJBTUVXT1JLW0xFWElDT04ucF07XHJcblxyXG4gICAgICAgICAgICAgICAgLy9pZiBwYXNzZWQgZWxlbWVudCBpcyBubyBIVE1MIGVsZW1lbnQ6IHNraXAgYW5kIHJldHVyblxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KHBsdWdpblRhcmdldEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2lmIHBhc3NlZCBlbGVtZW50IGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQ6IHNldCBwYXNzZWQgb3B0aW9ucyBpZiB0aGVyZSBhcmUgYW55IGFuZCByZXR1cm4gaXRzIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKHBsdWdpblRhcmdldEVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3QgPSBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5zdC5vcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnN0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2xvYmFsczpcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZDtcclxuICAgICAgICAgICAgICAgIHZhciBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcnRsU2Nyb2xsQmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2F1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXNpZVZlcnNpb247XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cztcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzdHJpY3RlZE1lYXN1cmluZztcclxuXHJcbiAgICAgICAgICAgICAgICAvL2dlbmVyYWwgcmVhZG9ubHk6XHJcbiAgICAgICAgICAgICAgICB2YXIgX2luaXRpYWxpemVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzVGV4dGFyZWE7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzQm9keTtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRNaXhlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9tRXhpc3RzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2VuZXJhbDpcclxuICAgICAgICAgICAgICAgIHZhciBfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ1g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJYO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5YO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5ZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pc1JUTDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2xlZXBpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRCb3JkZXJTaXplID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbEhvcml6b250YWxJbmZvID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbFZlcnRpY2FsSW5mbyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydFNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZSA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbmFtaW5nOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1pbnVzSGlkZGVuID0gJy1oaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNYXJnaW5NaW51cyA9ICdtYXJnaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUGFkZGluZ01pbnVzID0gJ3BhZGRpbmctJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQm9yZGVyTWludXMgPSAnYm9yZGVyLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clRvcCA9ICd0b3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJSaWdodCA9ICdyaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckJvdHRvbSA9ICdib3R0b20nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJMZWZ0ID0gJ2xlZnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNaW5NaW51cyA9ICdtaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWF4TWludXMgPSAnbWF4LSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cldpZHRoID0gJ3dpZHRoJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RySGVpZ2h0ID0gJ2hlaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckZsb2F0ID0gJ2Zsb2F0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyRW1wdHkgPSAnJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQXV0byA9ICdhdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU3luYyA9ICdzeW5jJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsID0gJ3Njcm9sbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckh1bmRyZWRQZXJjZW50ID0gJzEwMCUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJYID0gJ3gnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJZID0gJ3knO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJEb3QgPSAnLic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxiYXIgPSAnc2Nyb2xsYmFyJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNIb3Jpem9udGFsID0gJy1ob3Jpem9udGFsJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNWZXJ0aWNhbCA9ICctdmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxMZWZ0ID0gX3N0clNjcm9sbCArICdMZWZ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsVG9wID0gX3N0clNjcm9sbCArICdUb3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50ID0gJ21vdXNlZG93biB0b3VjaHN0YXJ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTW91c2VUb3VjaFVwRXZlbnQgPSAnbW91c2V1cCB0b3VjaGVuZCB0b3VjaGNhbmNlbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQgPSAnbW91c2Vtb3ZlIHRvdWNobW92ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlRW50ZXIgPSAnbW91c2VlbnRlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlTGVhdmUgPSAnbW91c2VsZWF2ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cktleURvd25FdmVudCA9ICdrZXlkb3duJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyS2V5VXBFdmVudCA9ICdrZXl1cCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNlbGVjdFN0YXJ0RXZlbnQgPSAnc2VsZWN0c3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQgPSAndHJhbnNpdGlvbmVuZCB3ZWJraXRUcmFuc2l0aW9uRW5kIG9UcmFuc2l0aW9uRW5kJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eSA9ICdfX292ZXJsYXlTY3JvbGxiYXJzUk9fXyc7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jbGFzcyBuYW1lczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jYXNzTmFtZXNQcmVmaXggPSAnb3MtJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSFRNTEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnaG9zdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctZm9yZWlnbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXRleHRhcmVhJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhckhvcml6b250YWxIaWRkZW4gPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLScgKyBfc3RyU2Nyb2xsYmFyICsgX3N0ck1pbnVzSG9yaXpvbnRhbCArIF9zdHJNaW51c0hpZGRlbjtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhclZlcnRpY2FsSGlkZGVuID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy0nICsgX3N0clNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsICsgX3N0ck1pbnVzSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctdHJhbnNpdGlvbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSVEwgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXJ0bCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctcmVzaXplLWRpc2FibGVkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctc2Nyb2xsaW5nJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy1vdmVyZmxvdyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dYID0gX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyArICcteCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1kgPSBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ICsgJy15JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICd0ZXh0YXJlYSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVRleHRhcmVhQ292ZXJFbGVtZW50ID0gX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCArICctY292ZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncGFkZGluZyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndmlld3BvcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNJbnZpc2libGUgPSBfY2xhc3NOYW1lVmlld3BvcnRFbGVtZW50ICsgJy1uYXRpdmUtc2Nyb2xsYmFycy1pbnZpc2libGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCA9IF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQgKyAnLW5hdGl2ZS1zY3JvbGxiYXJzLW92ZXJsYWlkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVDb250ZW50QXJyYW5nZUVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQtYXJyYW5nZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNvbnRlbnRHbHVlRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnY29udGVudC1nbHVlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3NpemUtYXV0by1vYnNlcnZlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyLWl0ZW0nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQgPSBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCArICctZmluYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndGV4dC1pbmhlcml0JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyID0gX2Nhc3NOYW1lc1ByZWZpeCArIF9zdHJTY3JvbGxiYXI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctdHJhY2snO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA9IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFjayArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctaGFuZGxlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlT2ZmID0gX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZSArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy11bnVzYWJsZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckF1dG9IaWRkZW4gPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy0nICsgX3N0ckF1dG8gKyBfc3RyTWludXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lciA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyAnLWNvcm5lcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXIgKyAnLXJlc2l6ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplICsgJy1ib3RoJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplSCA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUgKyBfc3RyTWludXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVWID0gX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJIb3Jpem9udGFsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c0hvcml6b250YWw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclZlcnRpY2FsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVEcmFnZ2luZyA9IF9jYXNzTmFtZXNQcmVmaXggKyAnZHJhZ2dpbmcnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUaGVtZU5vbmUgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3RoZW1lLW5vbmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc0ludmlzaWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrT2ZmLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclVudXNhYmxlLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZVYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZURyYWdnaW5nXS5qb2luKF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jYWxsYmFja3M6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfY2FsbGJhY2tzSW5pdFFldWV1ZSA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vYXR0cnMgdmlld3BvcnQgc2hhbGwgaW5oZXJpdCBmcm9tIHRhcmdldFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0ID0gW0xFWElDT04udGldO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vb3B0aW9uczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZWZhdWx0T3B0aW9ucztcclxuICAgICAgICAgICAgICAgIHZhciBfY3VycmVudE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnM7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9leHRlbnNpb25zOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2V4dGVuc2lvbnMgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfZXh0ZW5zaW9uc1ByaXZhdGVNZXRob2RzID0gJ2FkZGVkIHJlbW92ZWQgb24gY29udHJhY3QnO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vdXBkYXRlXHRcclxuICAgICAgICAgICAgICAgIHZhciBfbGFzdFVwZGF0ZVRpbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dVcGRhdGVMYWcgPSA0MjtcclxuICAgICAgICAgICAgICAgIHZhciBfdXBkYXRlT25Mb2FkRXZlbnROYW1lID0gJ2xvYWQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVPbkxvYWRFbG1zID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy9ET00gZWxlbWVudHM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfd2luZG93RWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9odG1sRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9keUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnQ7ICAgICAgICAgICAgICAgICAgICAgLy90aGUgdGFyZ2V0IGVsZW1lbnQgb2YgdGhpcyBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIGhvc3QgZWxlbWVudCBvZiB0aGlzIE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdCAtPiBtYXkgYmUgdGhlIHNhbWUgYXMgdGFyZ2V0RWxlbWVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50OyAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGF1dG8gY2hhbmdlc1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVPYnNlcnZlckVsZW1lbnQ7ICAgICAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGFuZCBwYWRkaW5nIGNoYW5nZXNcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9wYWRkaW5nRWxlbWVudDsgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlcyB0aGUgcGFkZGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgLy9pcyB0aGUgdmlld3BvcnQgb2Ygb3VyIHNjcm9sbGJhciBtb2RlbFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRFbGVtZW50OyAgICAgICAgICAgICAgICAgICAgLy90aGUgZWxlbWVudCB3aGljaCBob2xkcyB0aGUgY29udGVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRBcnJhbmdlRWxlbWVudDsgICAgICAgICAgICAgLy9pcyBuZWVkZWQgZm9yIGNvcnJlY3Qgc2l6aW5nIG9mIHRoZSBjb250ZW50IGVsZW1lbnQgKG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhcnMgYXJlIG92ZXJsYXlzKVx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlRWxlbWVudDsgICAgICAgICAgICAgICAgLy9oYXMgYWx3YXlzIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IGVsZW1lbnRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUNvdmVyRWxlbWVudDsgICAgICAgICAgICAgIC8vb25seSBhcHBsaWVkIGlmIHRhcmdldCBpcyBhIHRleHRhcmVhIGVsZW1lbnQuIFVzZWQgZm9yIGNvcnJlY3Qgc2l6ZSBjYWxjdWxhdGlvbiBhbmQgZm9yIHByZXZlbnRpb24gb2YgdW5jb250cm9sbGVkIHNjcm9sbGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsVHJhY2tFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF93aW5kb3dFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kb2N1bWVudEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hvc3RFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b09ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnROYXRpdmU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9DYWNoZTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0U2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGFzT3ZlcmZsb3dDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGlkZU92ZXJmbG93Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3dpZHRoQXV0b0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9oZWlnaHRBdXRvQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JveFNpemluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NQYWRkaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JvcmRlckNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NNYXJnaW5DYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY3NzRGlyZWN0aW9uQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGlwQWx3YXlzQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfYXV0b1VwZGF0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b0NhcGFibGVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9yZXNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbm9ybWFsaXplUlRMQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vbGRDbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhSW5mb0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYVNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5XaWR0aENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib2R5TWluU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVBdXRvQ2FjaGUgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL011dGF0aW9uT2JzZXJ2ZXI6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckhvc3Q7XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgPSBbJ3dyYXAnLCAnY29scycsICdyb3dzJ107XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QgPSBbTEVYSUNPTi5pLCBMRVhJQ09OLmMsIExFWElDT04ucywgJ29wZW4nXS5jb25jYXQoX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2V2ZW50czpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95RXZlbnRzID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy90ZXh0YXJlYTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUhhc0ZvY3VzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFyczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZURlbGF5O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vcmVzaXplXHRcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplTm9uZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplQm90aDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplSG9yaXpvbnRhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplVmVydGljYWw7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudCBMaXN0ZW5lciA9PT09Ly9cdFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSBldmVudCBsaXN0ZW5lciBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LiBcdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIGV2ZW50IGxpc3RlbmVyIHNoYWxsIGJlIGFwcGxpZWQgb3IgcmVtb3ZlZC5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50TmFtZXMgVGhlIG5hbWUocykgb2YgdGhlIGV2ZW50cy5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBtZXRob2Qgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcmVtb3ZlIFRydWUgaWYgdGhlIGhhbmRsZXIgc2hhbGwgYmUgcmVtb3ZlZCwgZmFsc2Ugb3IgdW5kZWZpbmVkIGlmIHRoZSBoYW5kbGVyIHNoYWxsIGJlIGFkZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcGFzc2l2ZU9yT3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGxpc3RlbmVyLCByZW1vdmUsIHBhc3NpdmVPck9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29sbGVjdGVkID0gQ09NUEFUSUJJTElUWS5pc0EoZXZlbnROYW1lcykgJiYgQ09NUEFUSUJJTElUWS5pc0EobGlzdGVuZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2QgPSByZW1vdmUgPyAncmVtb3ZlRXZlbnRMaXN0ZW5lcicgOiAnYWRkRXZlbnRMaXN0ZW5lcic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uT2ZmID0gcmVtb3ZlID8gJ29mZicgOiAnb24nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudHMgPSBjb2xsZWN0ZWQgPyBmYWxzZSA6IGV2ZW50TmFtZXMuc3BsaXQoX3N0clNwYWNlKVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhc3NpdmVPck9wdGlvbnNJc09iaiA9IEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KHBhc3NpdmVPck9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXNzaXZlID0gKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyAmJiAocGFzc2l2ZU9yT3B0aW9uc0lzT2JqID8gKHBhc3NpdmVPck9wdGlvbnMuX3Bhc3NpdmUpIDogcGFzc2l2ZU9yT3B0aW9ucykpIHx8IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYXB0dXJlID0gcGFzc2l2ZU9yT3B0aW9uc0lzT2JqICYmIChwYXNzaXZlT3JPcHRpb25zLl9jYXB0dXJlIHx8IGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmF0aXZlUGFyYW0gPSBfc3VwcG9ydFBhc3NpdmVFdmVudHMgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IHBhc3NpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmU6IGNhcHR1cmUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IGNhcHR1cmU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2xsZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVzW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lc1tpXSwgbGlzdGVuZXJbaV0sIHJlbW92ZSwgcGFzc2l2ZU9yT3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50c1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbMF1bbWV0aG9kXShldmVudHNbaV0sIGxpc3RlbmVyLCBuYXRpdmVQYXJhbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50W29uT2ZmXShldmVudHNbaV0sIGxpc3RlbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgcGFzc2l2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lcywgbGlzdGVuZXIsIGZhbHNlLCBwYXNzaXZlKTtcclxuICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wdXNoKENPTVBBVElCSUxJVFkuYmluZChzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyLCAwLCBlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgdHJ1ZSwgcGFzc2l2ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBSZXNpemUgT2JzZXJ2ZXIgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSByZXNpemUgb2JzZXJ2ZXIgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSByZXNpemUgb2JzZXJ2ZXIgc2hhbGwgYmUgYWRkZWQgb3IgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2sgVGhlIGNhbGxiYWNrIHdoaWNoIGlzIGZpcmVkIGV2ZXJ5IHRpbWUgdGhlIHJlc2l6ZSBvYnNlcnZlciByZWdpc3RlcnMgYSBzaXplIGNoYW5nZSBvciBmYWxzZSAvIHVuZGVmaW5lZCBpZiB0aGUgcmVzaXplT2JzZXJ2ZXIgc2hhbGwgYmUgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBSZXNpemVPYnNlcnZlcih0YXJnZXRFbGVtZW50LCBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplT2JzZXJ2ZXIgPSBDT01QQVRJQklMSVRZLnJPKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBbmltYXRpb25TdGFydEV2ZW50ID0gJ2FuaW1hdGlvbnN0YXJ0IG1vekFuaW1hdGlvblN0YXJ0IHdlYmtpdEFuaW1hdGlvblN0YXJ0IE1TQW5pbWF0aW9uU3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2hpbGROb2RlcyA9ICdjaGlsZE5vZGVzJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0U2Nyb2xsID0gMzMzMzMzMztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXShjb25zdFNjcm9sbClbX3N0clNjcm9sbExlZnRdKF9pc1JUTCA/IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGwgOiBjb25zdFNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgcmVzaXplIG9ic2VydmVyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25FbGVtZW50UmVzaXplZENhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5hZGRDbGFzcygnb2JzZXJ2ZWQnKS5hcHBlbmQoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkpLmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyID0gZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0gPSBuZXcgcmVzaXplT2JzZXJ2ZXIoY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9ic2VydmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX21zaWVWZXJzaW9uID4gOSB8fCAhX2F1dG9VcGRhdGVSZWNvbW1lbmRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50LnByZXBlbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlRGl2KHsgYzogX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsIGRpcjogJ2x0cicgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRmluYWxFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdih7IGM6IF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQsIHN0eWxlOiAnd2lkdGg6IDIwMCU7IGhlaWdodDogMjAwJScgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYnNlcnZlckVsZW1lbnQgPSB0YXJnZXRFbGVtZW50WzBdW3N0ckNoaWxkTm9kZXNdWzBdW3N0ckNoaWxkTm9kZXNdWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2hyaW5rRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudENoaWxkID0gRlJBTUVXT1JLKGV4cGFuZEVsZW1lbnRbMF1bc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhDYWNoZSA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodENhY2hlID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNEaXJ0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJBRklkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZhY3RvciA9IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGxiYXJTaXplID0gZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTaXplOyAvL2NhcmUgZG9uJ3QgbWFrZSBjaGFuZ2VzIHRvIHRoaXMgb2JqZWN0ISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldFdpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICogZmFjdG9yICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICogZmFjdG9yICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldEhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXSArIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIGZhY3RvciArIG5hdGl2ZVNjcm9sbGJhclNpemUueSAqIGZhY3RvciArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnggKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJXaWR0aF0gPSBzaXplUmVzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RySGVpZ2h0XSA9IHNpemVSZXNldEhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50Q2hpbGQuY3NzKGV4cGFuZENoaWxkQ1NTKTtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNocmlua0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShjb25zdFNjcm9sbClbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY29uc3RTY3JvbGwpW19zdHJTY3JvbGxUb3BdKGNvbnN0U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNEaXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDYWNoZSA9IGN1cnJXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodENhY2hlID0gY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvblNjcm9sbCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycldpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyckhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRGlydHkgPSBjdXJyV2lkdGggIT0gd2lkdGhDYWNoZSB8fCBjdXJySGVpZ2h0ICE9IGhlaWdodENhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBpc0RpcnR5ICYmICFyQUZJZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkockFGSWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gQ09NUEFUSUJJTElUWS5yQUYoKShvblJlc2l6ZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWV2ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVzaXplZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXJFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQob2JzZXJ2ZXJFbGVtZW50Q1NTLCBfc3RyRW1wdHksIFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0oKG5hdGl2ZVNjcm9sbGJhclNpemUueSArIDEpICogZmFjdG9yKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIC1mYWN0b3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplLnkgKiAtZmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSgobmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICsgMSkgKiBmYWN0b3IpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKG9ic2VydmVyRWxlbWVudCkuY3NzKG9ic2VydmVyRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnQub24oX3N0clNjcm9sbCwgb25TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaHJpbmtFbGVtZW50Lm9uKF9zdHJTY3JvbGwsIG9uU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5vbihzdHJBbmltYXRpb25TdGFydEV2ZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xldHMgYXNzdW1lIHRoYXQgdGhlIGRpdnMgd2lsbCBuZXZlciBiZSB0aGF0IGxhcmdlIGFuZCBhIGNvbnN0YW50IHZhbHVlIGlzIGVub3VnaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RyV2lkdGhdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJIZWlnaHRdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRDaGlsZC5jc3MoZXhwYW5kQ2hpbGRDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRhY2hFdmVudCA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuYXR0YWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0lFID0gX21zaWVWZXJzaW9uICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRGaXJzdCh0YXJnZXRFbGVtZW50LCBfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudClbMF0uYXR0YWNoRXZlbnQoJ29ucmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuY3JlYXRlRWxlbWVudChUWVBFUy5vKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zZXRBdHRyaWJ1dGUoTEVYSUNPTi50aSwgJy0xJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc2V0QXR0cmlidXRlKExFWElDT04uYywgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSB0aGlzLmNvbnRlbnREb2N1bWVudC5kZWZhdWx0VmlldztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bmQuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHduZC5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoudHlwZSA9ICd0ZXh0L2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9ICdhYm91dDpibGFuayc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50Lm9uKHN0ckFuaW1hdGlvblN0YXJ0RXZlbnQsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudFswXSA9PT0gX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpciA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxMZWZ0VmFsdWUgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXIgIT09IF9jc3NEaXJlY3Rpb25EZXRlY3RlZENhY2hlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyID09PSAnbHRyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTGVmdF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyUmlnaHRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsTGVmdFZhbHVlID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckxlZnRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJSaWdodF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbExlZnRWYWx1ZSA9IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2V4ZWN1dGlvbiBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIElFISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudC5jaGlsZHJlbigpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNjcm9sbExlZnRWYWx1ZSlbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGUgPSBkaXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb25DaGFuZ2VkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIodGFyZ2V0RWxlbWVudCwgX3N0clNjcm9sbCwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb25DaGFuZ2VkKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHJlc2l6ZSBvYnNlcnZlcjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVPYnNlcnZlck9iaiA9IGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVPYnNlcnZlck9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpemVPYnNlcnZlck9iai5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50W19zdHJSZXNpemVPYnNlcnZlclByb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUodGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkuZXEoMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRnJlZXplcyBvciB1bmZyZWV6ZXMgdGhlIGdpdmVuIHJlc2l6ZSBvYnNlcnZlci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSB0YXJnZXQgcmVzaXplIG9ic2VydmVyIGlzIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZnJlZXplIFRydWUgaWYgdGhlIHJlc2l6ZSBvYnNlcnZlciBzaGFsbCBiZSBmcm96ZW4sIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGZyZWV6ZVJlc2l6ZU9ic2VydmVyKHRhcmdldEVsZW1lbnQsIGZyZWV6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRFbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoZnJlZXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldLnVub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNoaWxkcmVuKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KS5lcSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdyA9IHRhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGggPSB0YXJnZXRFbGVtZW50LmNzcyhfc3RySGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSB3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFJlc2l6ZU9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0ub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjc3MgPSB7IH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJIZWlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuY2hpbGRyZW4oX3N0ckRvdCArIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKi9cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IE11dGF0aW9uIE9ic2VydmVycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENyZWF0ZXMgTXV0YXRpb25PYnNlcnZlcnMgZm9yIHRoZSBob3N0IGFuZCBjb250ZW50IEVsZW1lbnQgaWYgdGhleSBhcmUgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRNdXRhdGlvbk9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyA9IDExO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25PYnNlcnZlciA9IENPTVBBVElCSUxJVFkubU8oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRMYXN0VXBkYXRlID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25BdHRyTmFtZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uSXNDbGFzcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZE11dGF0aW9uVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Q2xhc3NWYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0Q2xhc3NOYW1lUmVnZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50VGltZW91dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2sgPSBmdW5jdGlvbiAobXV0YXRpb25zKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvVXBkYXRlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVGb3JjZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0ZWRBdHRycyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXQgPSBtdXRhdGlvbi50YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uQXR0ck5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbklzQ2xhc3MgPSBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLmM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE11dGF0aW9uVmFsID0gbXV0YXRpb24ub2xkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NsYXNzVmFsID0gbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgbXV0YXRpb25Jc0NsYXNzICYmICFkb1VwZGF0ZUZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbGQgY2xhc3MgdmFsdWUgY29udGFpbnMgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiBhbmQgbmV3IGNsYXNzIHZhbHVlIGRvZXNuJ3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbGRNdXRhdGlvblZhbC5pbmRleE9mKF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pID4gLTEgJiYgbmV3Q2xhc3NWYWwuaW5kZXhPZihfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0Q2xhc3NOYW1lUmVnZXggPSBjcmVhdGVIb3N0Q2xhc3NOYW1lUmVnRXhwKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudE5hdGl2ZS5jbGFzc05hbWUgPSBuZXdDbGFzc1ZhbC5zcGxpdChfc3RyU3BhY2UpLmNvbmNhdChvbGRNdXRhdGlvblZhbC5zcGxpdChfc3RyU3BhY2UpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5tYXRjaChob3N0Q2xhc3NOYW1lUmVnZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKS5qb2luKF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBkb1VwZGF0ZUZvcmNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBtdXRhdGlvbklzQ2xhc3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGhvc3RDbGFzc05hbWVzQ2hhbmdlZChvbGRNdXRhdGlvblZhbCwgbmV3Q2xhc3NWYWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBvbGRNdXRhdGlvblZhbCAhPT0gbXV0YXRpb25UYXJnZXRbTEVYSUNPTi5zXS5jc3NUZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlZEF0dHJzLnB1c2gobXV0YXRpb25BdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KG11dGF0ZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKGRvVXBkYXRlRm9yY2UgfHwgX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvVXBkYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayA9IGZ1bmN0aW9uIChtdXRhdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb1VwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBpc1Vua25vd25NdXRhdGlvbihtdXRhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhZG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBDT01QQVRJQklMSVRZLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0byA9IChfaGVpZ2h0QXV0b0NhY2hlIHx8IF93aWR0aEF1dG9DYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMYXN0VXBkYXRlID0gbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGNvbHMsIHJvd3Mgb3Igd3JhcCBhdHRyIHdhcyBjaGFuZ2VkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNvbnRlbnRUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uT2JzZXJ2ZXJDb250ZW50TGFnIDw9IDAgfHwgbm93IC0gY29udGVudExhc3RVcGRhdGUgPiBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyB8fCAhc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFRpbWVvdXQgPSBzZXRUaW1lb3V0KGFjdGlvbiwgbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0ID0gbmV3IG11dGF0aW9uT2JzZXJ2ZXIoX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQgPSBuZXcgbXV0YXRpb25PYnNlcnZlcihfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgIV9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckhvc3Qub2JzZXJ2ZShfaG9zdEVsZW1lbnROYXRpdmUsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQub2JzZXJ2ZShfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50TmF0aXZlIDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlT2xkVmFsdWU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlOiAhX2lzVGV4dGFyZWEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZExpc3Q6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGE6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX2lzVGV4dGFyZWEgPyBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzSG9zdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRGlzY29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVySG9zdC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudHMgb2YgZWxlbWVudHMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBob3N0IGVsZW1lbnQgZ2V0cyByZXNpemVkLiBJTVBPUlRBTlQ6IFBhZGRpbmcgY2hhbmdlcyBhcmUgZGV0ZWN0ZWQgdG9vISFcclxuICAgICAgICAgICAgICAgICAqIEl0IHJlZnJlc2hlcyB0aGUgaG9zdFJlc2l6ZWRFdmVudEFyZ3MgYW5kIHRoZSBob3N0U2l6ZVJlc2l6ZUNhY2hlLlxyXG4gICAgICAgICAgICAgICAgICogSWYgdGhlcmUgYXJlIGFueSBzaXplIGNoYW5nZXMsIHRoZSB1cGRhdGUgbWV0aG9kIGdldHMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25SZXNpemVkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IF9zaXplT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gY2hlY2tDYWNoZShob3N0U2l6ZSwgX2hvc3RFbGVtZW50U2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGhvc3RTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIGVudGVyIGV2ZW50IG9mIHRoZSBob3N0IGVsZW1lbnQuIFRoaXMgZXZlbnQgaXMgb25seSBuZWVkZWQgZm9yIHRoZSBhdXRvSGlkZSBmZWF0dXJlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25Nb3VzZUVudGVyKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgbW91c2UgbGVhdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTGVhdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX2JvZHlFbGVtZW50Lmhhc0NsYXNzKF9jbGFzc05hbWVEcmFnZ2luZykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIG1vdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIFwibW92ZVwiIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTW92ZSgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSAmJiAhX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQcmV2ZW50cyB0ZXh0IGZyb20gZGVzZWxlY3Rpb24gaWYgYXR0YWNoZWQgdG8gdGhlIGRvY3VtZW50IGVsZW1lbnQgb24gdGhlIG1vdXNlZG93biBldmVudCBvZiBhIERPTSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBzZWxlY3Qgc3RhcnQgZXZlbnQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRvY3VtZW50T25TZWxlY3RTdGFydChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGEgZWxlbWVudCBoYXMgbG9hZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZU9uTG9hZENhbGxiYWNrKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbSA9IEZSQU1FV09SSyhldmVudC50YXJnZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlYWNoVXBkYXRlT25Mb2FkKGZ1bmN0aW9uIChpLCB1cGRhdGVPbkxvYWRTZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxtLmlzKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgbW91c2UgJiB0b3VjaCBldmVudHMgb2YgdGhlIGhvc3QgZWxlbWVudC4gKGZvciBoYW5kbGluZyBhdXRvLWhpZGluZyBvZiB0aGUgc2Nyb2xsYmFycylcclxuICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LnNwbGl0KF9zdHJTcGFjZSlbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTW92ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKCFfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBkZXN0cm95KSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyTW91c2VFbnRlciwgX3N0ck1vdXNlTGVhdmVdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbaG9zdE9uTW91c2VFbnRlciwgaG9zdE9uTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICghX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlIHx8IGRlc3Ryb3kpLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgcGx1Z2luIGlzIGluaXRpYWxpemVkIGFuZCB0aGUgbW91c2UgaXMgb3ZlciB0aGUgaG9zdCBlbGVtZW50LCBtYWtlIHRoZSBzY3JvbGxiYXJzIHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9pbml0aWFsaXplZCAmJiAhZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50Lm9uZSgnbW91c2VvdmVyJywgaG9zdE9uTW91c2VFbnRlcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBVcGRhdGUgRGV0ZWN0aW9uID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogTWVhc3VyZXMgdGhlIG1pbiB3aWR0aCBhbmQgbWluIGhlaWdodCBvZiB0aGUgYm9keSBlbGVtZW50IGFuZCByZWZyZXNoZXMgdGhlIHJlbGF0ZWQgY2FjaGUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWluIHdpZHRoIG9yIG1pbiBoZWlnaHQgaGFzIGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gYm9keU1pblNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5ICYmIF9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUudyA9IHBhcnNlVG9aZXJvT3JOdW1iZXIoX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLmggPSBwYXJzZVRvWmVyb09yTnVtYmVyKF9jb250ZW50QXJyYW5nZUVsZW1lbnQuY3NzKF9zdHJNaW5NaW51cyArIF9zdHJIZWlnaHQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuYyA9IGNoZWNrQ2FjaGUoYm9keU1pblNpemUsIF9ib2R5TWluU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuZiA9IHRydWU7IC8vZmxhZyBmb3IgXCJtZWFzdXJlZCBhdCBsZWFzdCBvbmNlXCJcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlNaW5TaXplQ2FjaGUgPSBib2R5TWluU2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gISFib2R5TWluU2l6ZS5jO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjbGFzcyBuYW1lcyByZWFsbHkgY2hhbmdlZCAobmV3IGNsYXNzIHdpdGhvdXQgcGx1Z2luIGhvc3QgcHJlZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9sZENsYXNzTmFtZXMgVGhlIG9sZCBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG5ld0NsYXNzTmFtZXMgVGhlIG5ldyBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNsYXNzIG5hbWVzIGhhcyByZWFsbHkgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0Q2xhc3NOYW1lc0NoYW5nZWQob2xkQ2xhc3NOYW1lcywgbmV3Q2xhc3NOYW1lcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyQ2xhc3NlcyA9IHR5cGVvZiBuZXdDbGFzc05hbWVzID09IFRZUEVTLnMgPyBuZXdDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2xkQ2xhc3NlcyA9IHR5cGVvZiBvbGRDbGFzc05hbWVzID09IFRZUEVTLnMgPyBvbGRDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZiA9IGdldEFycmF5RGlmZmVyZW5jZXMob2xkQ2xhc3NlcywgY3VyckNsYXNzZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9uZSB0aGVtZSBmcm9tIGRpZmYgbGlzdCB0byBwcmV2ZW50IHVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBpbkFycmF5KF9jbGFzc05hbWVUaGVtZU5vbmUsIGRpZmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdleDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnNwbGljZShpZHgsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZltMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWdleCA9IGNyZWF0ZUhvc3RDbGFzc05hbWVSZWdFeHAodHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRpZmZbaV0ubWF0Y2gocmVnZXgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtdXRhdGlvbiBpcyBub3QgZnJvbSBhIGZyb20gdGhlIHBsdWdpbiBnZW5lcmF0ZWQgZWxlbWVudC4gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGEgdGV4dGFyZWEgdGhlIG11dGF0aW9uIGlzIGFsd2F5cyB1bmtub3duLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG11dGF0aW9uIFRoZSBtdXRhdGlvbiB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG11dGF0aW9uIGlzIGZyb20gYSB1bmtub3duIGVsZW1lbnQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNVbmtub3duTXV0YXRpb24obXV0YXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0ID0gbXV0YXRpb24udGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvblR5cGUgPSBtdXRhdGlvbi50eXBlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbG9zZXN0ID0gJ2Nsb3Nlc3QnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25UYXJnZXQgPT09IF9jb250ZW50RWxlbWVudE5hdGl2ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgPT09IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVHlwZSA9PT0gJ2F0dHJpYnV0ZXMnICYmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgfHwgYXR0cmlidXRlTmFtZSA9PT0gTEVYSUNPTi5zKSAmJiAhX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUgY2xhc3NOYW1lIGNoYW5nZXMgYnkgdGhlIHBsdWdpblx0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgJiYgRlJBTUVXT1JLKG11dGF0aW9uVGFyZ2V0KS5oYXNDbGFzcyhfY2xhc3NOYW1lSG9zdEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RDbGFzc05hbWVzQ2hhbmdlZChtdXRhdGlvbi5vbGRWYWx1ZSwgbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSBkbyBpdCBvZiBicm93c2VyIHN1cHBvcnQgaXQgbmF0aXZlbHlcdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdICE9IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KSAhPT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXRbc3RyQ2xvc2VzdF0oX3N0ckRvdCArIF9jbGFzc05hbWVTY3JvbGxiYXIpICE9PSBudWxsIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvblRhcmdldFtzdHJDbG9zZXN0XShfc3RyRG90ICsgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lcikgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb250ZW50IHNpemUgd2FzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGlzIG1ldGhvZCB3YXMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNvbnRlbnQgc2l6ZSB3YXMgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVBdXRvQ29udGVudFNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRNZWFzdXJlRWxlbWVudCA9IGdldENvbnRlbnRNZWFzdXJlRWxlbWVudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVZhbHVlTGVuZ3RoID0gX2lzVGV4dGFyZWEgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZSA/IF90YXJnZXRFbGVtZW50LnZhbCgpLmxlbmd0aCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldENTUyA9ICFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfaXNUZXh0YXJlYTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldENTUykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCA9IF9jb250ZW50RWxlbWVudC5jc3MoX3N0ckZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudFNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSArIHRleHRhcmVhVmFsdWVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSArIHRleHRhcmVhVmFsdWVMZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXRDU1MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBmbG9hdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQyA9IGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWQgPSBjaGVja0NhY2hlKGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZSwgX2NvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQgfHwgYm9keU1pblNpemVDO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIHdoZW4gYSBhdHRyaWJ1dGUgd2hpY2ggdGhlIE11dGF0aW9uT2JzZXJ2ZXIgd291bGQgb2JzZXJ2ZSBoYXMgY2hhbmdlZC4gIFxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb25lIG9mIHRoZSBhdHRyaWJ1dGVzIHdoaWNoIGEgTXV0YXRpb25PYnNlcnZlciB3b3VsZCBvYnNlcnZlIGhhcyBjaGFuZ2VkLCBmYWxzZSBvciB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBtZWFuaW5nZnVsQXR0cnNDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcgfHwgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlZEF0dHJzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VsZW06IF9ob3N0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hdHRyczogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QuY29uY2F0KCc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbGVtOiBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50IDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2F0dHJzOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2tzLCBmdW5jdGlvbiAoaW5kZXgsIGNoZWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0gPSBjaGVjay5fZWxlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2suX2F0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gYXR0ci5jaGFyQXQoMCkgPT09ICc6JyA/IGVsZW0uaXMoYXR0cikgOiBlbGVtLmF0dHIoYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tDYWNoZShjdXJyLCBjYWNoZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZEF0dHJzLnB1c2goYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdID0gY3VycjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KGNoYW5nZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkQXR0cnNbTEVYSUNPTi5sXSA+IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDaGVja3MgaXMgYSBDU1MgUHJvcGVydHkgb2YgYSBjaGlsZCBlbGVtZW50IGlzIGFmZmVjdGluZyB0aGUgc2Nyb2xsIHNpemUgb2YgdGhlIGNvbnRlbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIFRoZSBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBhZmZlY3RpbmcgdGhlIGNvbnRlbnQgc2Nyb2xsIHNpemUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNTaXplQWZmZWN0aW5nQ1NTUHJvcGVydHkocHJvcGVydHlOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaW5pdGlhbGl6ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4R3JvdyA9ICdmbGV4LWdyb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4U2hyaW5rID0gJ2ZsZXgtc2hyaW5rJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxleEJhc2lzID0gJ2ZsZXgtYmFzaXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZmZlY3RpbmdQcm9wc1ggPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RyV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNYXJnaW5NaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdmb250LXdlaWdodCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3b3JkLXNwYWNpbmcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNYQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUGFkZGluZ01pbnVzICsgX3N0clJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyTGVmdCArIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0clJpZ2h0ICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWluTWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnbGluZS1oZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJQYWRkaW5nTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyVG9wICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyQm90dG9tICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgX3N0clMgPSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9zdHJWUyA9ICd2LXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1ggPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnggPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueCA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1kgPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnkgPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueSA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplSXNBZmZlY3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1Byb3BlcnR5TmFtZSA9IGZ1bmN0aW9uIChhcnIsIG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNZLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWUNvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1ggJiYgIXNpemVJc0FmZmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNYLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWENvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzaXplSXNBZmZlY3RlZDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFVwZGF0ZSA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSB2YWx1ZXMgb2YgdGhlIHZpZXdwb3J0IGVsZW1lbnQgdG8gdGhlIHZhbHVlcyBmcm9tIHRoZSB0YXJnZXQgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIFRoZSB2YWx1ZSBvZiBhIGF0dHJpYnV0ZSBpcyBvbmx5IHNldCBpZiB0aGUgYXR0cmlidXRlIGlzIHdoaXRlbGlzdGVkLlxyXG4gICAgICAgICAgICAgICAgICogQGF0dHJzIGF0dHJzIFRoZSBhcnJheSBvZiBhdHRyaWJ1dGVzIHdoaWNoIHNoYWxsIGJlIHNldCBvciB1bmRlZmluZWQgaWYgYWxsIHdoaXRlbGlzdGVkIHNoYWxsIGJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlVmlld3BvcnRBdHRyc0Zyb21UYXJnZXQoYXR0cnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBhdHRycyA9IGF0dHJzIHx8IF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKGF0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaW5BKGF0dHIsIF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldCkgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldEF0dHIgPSBfdGFyZ2V0RWxlbWVudC5hdHRyKGF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUodGFyZ2V0QXR0cikgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihhdHRyLCB0YXJnZXRBdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucmVtb3ZlQXR0cihhdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVXBkYXRlcyB0aGUgdmFyaWFibGVzIGFuZCBzaXplIG9mIHRoZSB0ZXh0YXJlYSBlbGVtZW50LCBhbmQgbWFuYWdlcyB0aGUgc2Nyb2xsIG9uIG5ldyBsaW5lIG9yIG5ldyBjaGFyYWN0ZXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhVXBkYXRlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3cmFwQXR0ck9mZiA9ICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1pbldpZHRoID0gX3ZpZXdwb3J0U2l6ZS53O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWluSGVpZ2h0ID0gX3ZpZXdwb3J0U2l6ZS5oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb01lYXN1cmUgPSBfd2lkdGhBdXRvQ2FjaGUgfHwgd3JhcEF0dHJPZmY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc2V0IG1pbiBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTWluTWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB3aWR0aCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdXaWR0aCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IGRvTWVhc3VyZSA/IE1BVEgubWF4KG9yaWdXaWR0aCwgX3RhcmdldEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10gLSAxKSA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qd2lkdGggKz0gKF93aWR0aEF1dG9DYWNoZSA/IF9tYXJnaW5YICsgKCFfaXNCb3JkZXJCb3ggPyB3cmFwQXR0ck9mZiA/IDAgOiBfcGFkZGluZ1ggKyBfYm9yZGVyWCA6IDApIDogMCk7Ki9cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IG1lYXN1cmVkIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3dpZHRoQXV0b0NhY2hlID8gX3N0ckF1dG8gLyp3aWR0aCovIDogX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IGhlaWdodCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ0hlaWdodCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSBNQVRILm1heChvcmlnSGVpZ2h0LCBfdGFyZ2V0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNIXSAtIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBlbmQgY29ycmVjdCBzaXplIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckhlaWdodF0gPSBoZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUNvdmVyRWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgbWluIHdpZHRoIC8gbWluIGhlaWdodCB0byBwcmV2ZW50IHRleHRhcmVhIGNvbGxhcHNpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJXaWR0aF0gPSBtaW5XaWR0aCAvKisgKCFfaXNCb3JkZXJCb3ggJiYgX3dpZHRoQXV0b0NhY2hlID8gX3BhZGRpbmdYICsgX2JvcmRlclggOiAwKSovO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBtaW5IZWlnaHQgLyorICghX2lzQm9yZGVyQm94ICYmIF9oZWlnaHRBdXRvQ2FjaGUgPyBfcGFkZGluZ1kgKyBfYm9yZGVyWSA6IDApKi87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9vcmlnaW5hbFdpZHRoOiBvcmlnV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfb3JpZ2luYWxIZWlnaHQ6IG9yaWdIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZHluYW1pY1dpZHRoOiB3aWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9keW5hbWljSGVpZ2h0OiBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdXBkYXRlSGludHMgQSBvYmplY3RzIHdoaWNoIGNvbnRhaW5zIGhpbnRzIGZvciB0aGlzIHVwZGF0ZTpcclxuICAgICAgICAgICAgICAgICAqIHtcclxuICAgICAgICAgICAgICAgICAqICAgX2hvc3RTaXplQ2hhbmdlZCA6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIF9jb250ZW50U2l6ZUNoYW5nZWQgOiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICogICBfZm9yY2UgOiBib29sZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gcHJldmVudFN3YWxsb3dpbmdcclxuICAgICAgICAgICAgICAgICAqICAgX2NoYW5nZWRPcHRpb25zIDogeyB9LCAgICAgICAgICAgICAgICAgICAgICAgID09IHByZXZlbnRTd2FsbG93aW5nICYmIHByZXZlbnRTbGVlcFxyXG4gICAgICAgICAgICAgICAgKiAgfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGUodXBkYXRlSGludHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUhpbnRzID0gdXBkYXRlSGludHMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9ob3N0U2l6ZUNoYW5nZWQgfD0gdXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZCB8PSB1cGRhdGVIaW50cy5fY29udGVudFNpemVDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2UgfD0gdXBkYXRlSGludHMuX2ZvcmNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgbm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZm9yY2UgPSAhIV9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWRPcHRpb25zID0gdXBkYXRlSGludHMuX2NoYW5nZWRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzd2FsbG93ID0gX3N3YWxsb3dVcGRhdGVMYWcgPiAwICYmIF9pbml0aWFsaXplZCAmJiAhX2Rlc3Ryb3llZCAmJiAhZm9yY2UgJiYgIWNoYW5nZWRPcHRpb25zICYmIChub3cgLSBfbGFzdFVwZGF0ZVRpbWUpIDwgX3N3YWxsb3dVcGRhdGVMYWcgJiYgKCFfaGVpZ2h0QXV0b0NhY2hlICYmICFfd2lkdGhBdXRvQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkaXNwbGF5SXNIaWRkZW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzd2FsbG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlVGltZW91dCA9IHNldFRpbWVvdXQodXBkYXRlLCBfc3dhbGxvd1VwZGF0ZUxhZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWJvcnQgdXBkYXRlIGR1ZSB0bzpcclxuICAgICAgICAgICAgICAgICAgICAvL2Rlc3Ryb3llZFxyXG4gICAgICAgICAgICAgICAgICAgIC8vc3dhbGxvd2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vc2xlZXBpbmdcclxuICAgICAgICAgICAgICAgICAgICAvL2hvc3QgaXMgaGlkZGVuIG9yIGhhcyBmYWxzZSBkaXNwbGF5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQgfHwgc3dhbGxvdyB8fCAoX3NsZWVwaW5nICYmICFjaGFuZ2VkT3B0aW9ucykgfHwgKF9pbml0aWFsaXplZCAmJiAhZm9yY2UgJiYgKGRpc3BsYXlJc0hpZGRlbiA9IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpKSkgfHwgX2hvc3RFbGVtZW50LmNzcygnZGlzcGxheScpID09PSAnaW5saW5lJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfbGFzdFVwZGF0ZVRpbWUgPSBub3c7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vaWYgc2Nyb2xsYmFyIHN0eWxpbmcgaXMgcG9zc2libGUgYW5kIG5hdGl2ZSBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZCB0aGUgc2Nyb2xsYmFyIHN0eWxpbmcgd2lsbCBiZSBhcHBsaWVkIHdoaWNoIGhpZGVzIHRoZSBuYXRpdmUgc2Nyb2xsYmFycyBjb21wbGV0ZWx5LlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZyAmJiAhKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9uYXRpdmUgc2Nyb2xsYmFycyBhcmUgaGlkZGVuLCBzbyBjaGFuZ2UgdGhlIHZhbHVlcyB0byB6ZXJvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTaXplLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBuYXRpdmUgc2Nyb2xsYmFyIHNpemUgKGluIGNhc2Ugb2Ygem9vbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2Nyb2xsYmFyIHBhZGRpbmcgaXMgbmVlZGVkIGZvciBmaXJlZm94LCBiZWNhdXNlIGZpcmVmb3ggaGlkZXMgc2Nyb2xsYmFyIGF1dG9tYXRpY2FsbHkgaWYgdGhlIHNpemUgb2YgdGhlIGRpdiBpcyB0b28gc21hbGwuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhbGN1bGF0aW9uOiBbc2Nyb2xsYmFyIHNpemUgKzMgKjNdXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCszIGJlY2F1c2Ugb2YgcG9zc2libGUgZGVjb3JhdGlvbiBlLmcuIGJvcmRlcnMsIG1hcmdpbnMgZXRjLiwgYnV0IG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhciBpcyBOT1QgYSBvdmVybGFpZCBzY3JvbGxiYXIpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCozIGJlY2F1c2UgKDEpaW5jcmVhc2UgLyAoMilkZWNyZWFzZSAtYnV0dG9uIGFuZCAoMylyZXNpemUgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiAoX25hdGl2ZVNjcm9sbGJhclNpemUueCArIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ID8gMCA6IDMpKSAqIDMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IChfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICsgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyAwIDogMykpICogM1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHRpb25zID0gY2hhbmdlZE9wdGlvbnMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tDYWNoZUF1dG9Gb3JjZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrQ2FjaGUuYXBwbHkodGhpcywgW10uc2xpY2UuY2FsbChhcmd1bWVudHMpLmNvbmNhdChbZm9yY2VdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zYXZlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxUb3BdKClcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy50ZXh0YXJlYTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIHZpc2liaWxpdHk6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMudmlzaWJpbGl0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzVmlzaWJpbGl0eSwgX3Njcm9sbGJhcnNWaXNpYmlsaXR5Q2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGU6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNBdXRvSGlkZSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzQXV0b0hpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyBjbGljayBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuY2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZywgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIGRyYWcgc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuZHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZywgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGNsYXNzTmFtZSwgX2NsYXNzTmFtZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZXNpemVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMucmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShyZXNpemUsIF9yZXNpemVDYWNoZSkgJiYgIV9pc0JvZHk7IC8vYm9keSBjYW4ndCBiZSByZXNpemVkIHNpbmNlIHRoZSB3aW5kb3cgaXRzZWxmIGFjdHMgYXMgcmVzaXplIHBvc3NpYmlsaXR5LlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3BhZGRpbmdBYnNvbHV0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nQWJzb2x1dGUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5wYWRkaW5nQWJzb2x1dGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHBhZGRpbmdBYnNvbHV0ZSwgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jbGlwQWx3YXlzXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsaXBBbHdheXMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGlwQWx3YXlzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGlwQWx3YXlzQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY2xpcEFsd2F5cywgX2NsaXBBbHdheXNDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2l6ZUF1dG9DYXBhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnNpemVBdXRvQ2FwYWJsZSAmJiAhX2lzQm9keTsgLy9ib2R5IGNhbiBuZXZlciBiZSBzaXplIGF1dG8sIGJlY2F1c2UgaXQgc2hhbGwgYmUgYWx3YXlzIGFzIGJpZyBhcyB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNpemVBdXRvQ2FwYWJsZSwgX3NpemVBdXRvQ2FwYWJsZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zaG93TmF0aXZlU2Nyb2xsYmFyc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLnNob3dOYXRpdmVTY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZywgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYXV0b1VwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhdXRvVXBkYXRlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuYXV0b1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1VwZGF0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGF1dG9VcGRhdGUsIF9hdXRvVXBkYXRlQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL292ZXJmbG93QmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvciA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm92ZXJmbG93QmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShvdmVyZmxvd0JlaGF2aW9yLCBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLCBmb3JjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZHluV2lkdGg6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGggPSBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEuZHluV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGhDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5XaWR0aENhY2hlLCB0ZXh0YXJlYUR5bldpZHRoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9keW5IZWlnaHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluSGVpZ2h0ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1RleHRhcmVhLmR5bkhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZSwgdGV4dGFyZWFEeW5IZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgdmlzaWJpbGl0eVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlciA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ24nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICdzJztcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ20nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ2wnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGVEZWxheVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlRGVsYXk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb2xkIGNsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIF9vbGRDbGFzc05hbWUgPSBfY2xhc3NOYW1lQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZU5vbmUgPSByZXNpemUgPT09ICduJztcclxuICAgICAgICAgICAgICAgICAgICBfcmVzaXplQm90aCA9IHJlc2l6ZSA9PT0gJ2InO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVIb3Jpem9udGFsID0gcmVzaXplID09PSAnaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZVZlcnRpY2FsID0gcmVzaXplID09PSAndic7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vbm9ybWFsaXplUlRMXHJcbiAgICAgICAgICAgICAgICAgICAgX25vcm1hbGl6ZVJUTENhY2hlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubm9ybWFsaXplUlRMO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZSBvdmVybGF5IHNjcm9sbGJhciBoaWRpbmdcclxuICAgICAgICAgICAgICAgICAgICBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyAmJiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZWZyZXNoIG9wdGlvbnMgY2FjaGVcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZSA9IHNjcm9sbGJhcnNWaXNpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSA9IHNjcm9sbGJhcnNBdXRvSGlkZTtcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lQ2FjaGUgPSBjbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZUNhY2hlID0gcmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nQWJzb2x1dGVDYWNoZSA9IHBhZGRpbmdBYnNvbHV0ZTtcclxuICAgICAgICAgICAgICAgICAgICBfY2xpcEFsd2F5c0NhY2hlID0gY2xpcEFsd2F5cztcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9DYXBhYmxlQ2FjaGUgPSBzaXplQXV0b0NhcGFibGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSA9IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2F1dG9VcGRhdGVDYWNoZSA9IGF1dG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QmVoYXZpb3JDYWNoZSA9IGV4dGVuZERlZXAoe30sIG92ZXJmbG93QmVoYXZpb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bldpZHRoQ2FjaGUgPSB0ZXh0YXJlYUR5bldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bkhlaWdodENhY2hlID0gdGV4dGFyZWFEeW5IZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBfaGFzT3ZlcmZsb3dDYWNoZSB8fCB7IHg6IGZhbHNlLCB5OiBmYWxzZSB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBjb3JyZWN0IGNsYXNzIG5hbWUgdG8gdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX29sZENsYXNzTmFtZSArIF9zdHJTcGFjZSArIF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIGNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkICYmIGNsYXNzTmFtZSAhPT0gbnVsbCAmJiBjbGFzc05hbWUubGVuZ3RoID4gMCA/IGNsYXNzTmFtZSA6IF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgY29ycmVjdCBhdXRvIFVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRvVXBkYXRlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXV0b1VwZGF0ZSA9PT0gdHJ1ZSB8fCAoYXV0b1VwZGF0ZSA9PT0gbnVsbCAmJiBfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5hZGQoX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3AucmVtb3ZlKF9iYXNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FjdGl2YXRlIG9yIGRlYWN0aXZhdGUgc2l6ZSBhdXRvIGNhcGFiaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbnRlbnRHbHVlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEdsdWVFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmJlZm9yZShfY29udGVudEdsdWVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuYmVmb3JlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFNpemUgPSB7IHc6IC0xLCBoOiAtMSB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0NhY2hlKG5ld1NpemUsIG9sZFNpemUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIChfaGVpZ2h0QXV0b0NhY2hlICYmIG5ld1NpemUuaCA+IDApIHx8IChfd2lkdGhBdXRvQ2FjaGUgJiYgbmV3U2l6ZS53ID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9pbml0aWFsaXplZCAmJiAoIV9oZWlnaHRBdXRvQ2FjaGUgJiYgbmV3U2l6ZS5oID09PSAwKSB8fCAoIV93aWR0aEF1dG9DYWNoZSAmJiBuZXdTaXplLncgPT09IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkU2l6ZSA9IG5ld1NpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0QXV0byBkZXRlY3RvciBidWcgaWYgaGVpZ2h0IGlzIGZpeGVkIGJ1dCBjb250ZW50SGVpZ2h0IGlzIDAuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGUgcHJvYmFiaWxpdHkgdGhpcyBidWcgd2lsbCBldmVyIGhhcHBlbiBpcyB2ZXJ5IHZlcnkgbG93LCB0aGF0cyB3aHkgaXRzIG9rIGlmIHdlIHVzZSBjYWxjIHdoaWNoIGlzbid0IHN1cHBvcnRlZCBpbiBJRTguXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9jc3NDYWxjICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQuY3NzKF9zdHJIZWlnaHQsIF9jc3NDYWxjICsgJygxMDAlICsgMXB4KScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIGZvcmNlLCB1cGRhdGUgYWxsIHJlc2l6ZU9ic2VydmVycyB0b29cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnQuZmluZCgnKicpLnRyaWdnZXIoX3N0clNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmZpbmQoJyonKS50cmlnZ2VyKF9zdHJTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kaXNwbGF5IGhpZGRlbjpcclxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5SXNIaWRkZW4gPSBkaXNwbGF5SXNIaWRkZW4gPT09IHVuZGVmaW5lZCA/IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpIDogZGlzcGxheUlzSGlkZGVuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhIEF1dG9XcmFwcGluZzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmcgPSBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50LmF0dHIoJ3dyYXAnKSAhPT0gJ29mZicgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYUF1dG9XcmFwcGluZywgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBkaXJlY3Rpb246XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc0RpcmVjdGlvbiA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjc3NEaXJlY3Rpb25DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjc3NEaXJlY3Rpb24sIF9jc3NEaXJlY3Rpb25DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJveC1zaXppbmc6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveFNpemluZyA9IF9ob3N0RWxlbWVudC5jc3MoJ2JveC1zaXppbmcnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYm94U2l6aW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm94U2l6aW5nLCBfY3NzQm94U2l6aW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nID0gZ2V0VG9wUmlnaHRCb3R0b21MZWZ0SG9zdChfc3RyUGFkZGluZ01pbnVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy93aWR0aCArIGhlaWdodCBhdXRvIGRldGVjdGluZyB2YXI6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZXhjZXB0aW9uIG9jY3VycyBpbiBJRTggc29tZXRpbWVzICh1bmtub3duIGV4Y2VwdGlvbilcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdCA9IF9zaXplQXV0b09ic2VydmVyQWRkZWQgPyBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCkgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9pc1JUTCA9IGNzc0RpcmVjdGlvbiA9PT0gJ3J0bCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9yZGVyQm94ID0gKGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExMZWZ0ID0gX2lzUlRMID8gX3N0ckxlZnQgOiBfc3RyUmlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMUmlnaHQgPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3Qgd2lkdGggYXV0bzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uID0gKF9zaXplQXV0b09ic2VydmVyQWRkZWQgJiYgKF9ob3N0RWxlbWVudC5jc3MoX3N0ckZsb2F0KSAhPT0gJ25vbmUnIC8qfHwgX2lzVGV4dGFyZWEgKi8pKSA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnJpZ2h0IC0gc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRCQ1JlY3QubGVmdCkgPT09IDApICYmICghcGFkZGluZ0Fic29sdXRlID8gKF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmNXXSAtIF9wYWRkaW5nWCkgPiAwIDogdHJ1ZSkgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlICYmICF3aWR0aEF1dG9PYnNlcnZlckRldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wQ3Vyckhvc3RXaWR0aCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoID0gX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCBfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wTmV3SG9zdFdpZHRoID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gdG1wQ3Vyckhvc3RXaWR0aCAhPT0gdG1wTmV3SG9zdFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCB0bXBDdXJySG9zdFdpZHRoICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBOZXdIb3N0V2lkdGggPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vV107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbiA9IHRtcEN1cnJIb3N0V2lkdGggIT09IHRtcE5ld0hvc3RXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvID0gKHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uIHx8IHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikgJiYgc2l6ZUF1dG9DYXBhYmxlICYmICFkaXNwbGF5SXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHdpZHRoQXV0bywgX3dpZHRoQXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzV2lkdGhBdXRvID0gIXdpZHRoQXV0byAmJiBfd2lkdGhBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGhlaWdodCBhdXRvOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHRBdXRvID0gX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCAmJiBzaXplQXV0b0NhcGFibGUgJiYgIWRpc3BsYXlJc0hpZGRlbiA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LmJvdHRvbSAtIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnRvcCkgPT09IDApIC8qICYmICghcGFkZGluZ0Fic29sdXRlICYmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfbXNpZVZlcnNpb24pID8gdHJ1ZSA6IHRydWUpICovIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodEF1dG9DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShoZWlnaHRBdXRvLCBfaGVpZ2h0QXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzSGVpZ2h0QXV0byA9ICFoZWlnaHRBdXRvICYmIF9oZWlnaHRBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJvcmRlcjpcclxuICAgICAgICAgICAgICAgICAgICAvL3dlIG5lZWQgdGhlIGJvcmRlciBvbmx5IGlmIGJvcmRlciBib3ggYW5kIGF1dG8gc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVCb3JkZXJYID0gKHdpZHRoQXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZUJvcmRlclkgPSAoaGVpZ2h0QXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvcmRlciA9IGdldFRvcFJpZ2h0Qm90dG9tTGVmdEhvc3QoX3N0ckJvcmRlck1pbnVzLCAnLScgKyBfc3RyV2lkdGgsICF1cGRhdGVCb3JkZXJYLCAhdXBkYXRlQm9yZGVyWSlcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3QgbWFyZ2luOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW4gPSBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KF9zdHJNYXJnaW5NaW51cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdmFycyB0byBhcHBseSBjb3JyZWN0IGNzc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZUVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mdW5jc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRIb3N0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9oYXMgdG8gYmUgY2xpZW50U2l6ZSBiZWNhdXNlIG9mZnNldFNpemUgcmVzcGVjdCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRWaWV3cG9ydFNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmlld3BvcnQgc2l6ZSBpcyBwYWRkaW5nIGNvbnRhaW5lciBiZWNhdXNlIGl0IG5ldmVyIGhhcyBwYWRkaW5nLCBtYXJnaW4gYW5kIGEgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vZGV0ZXJtaW5lIHpvb20gcm91bmRpbmcgZXJyb3IgLT4gc29tZXRpbWVzIHNjcm9sbFdpZHRoL0hlaWdodCBpcyBzbWFsbGVyIHRoYW4gY2xpZW50V2lkdGgvSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBoYXBwZW5zIGFkZCB0aGUgZGlmZmVyZW5jZSB0byB0aGUgdmlld3BvcnRTaXplIHRvIGNvbXBlbnNhdGUgdGhlIHJvdW5kaW5nIGVycm9yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10gKyBNQVRILm1heCgwLCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10gLSBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdICsgTUFUSC5tYXgoMCwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdIC0gX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGluZm8gZm9yIHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWCA9IF9wYWRkaW5nWCA9IHBhZGRpbmcubCArIHBhZGRpbmcucjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWSA9IF9wYWRkaW5nWSA9IHBhZGRpbmcudCArIHBhZGRpbmcuYjtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nQWJzb2x1dGVYICo9IHBhZGRpbmdBYnNvbHV0ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdBYnNvbHV0ZVkgKj0gcGFkZGluZ0Fic29sdXRlID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZy5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShwYWRkaW5nLCBfY3NzUGFkZGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgaW5mbyBmb3IgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgX2JvcmRlclggPSBib3JkZXIubCArIGJvcmRlci5yO1xyXG4gICAgICAgICAgICAgICAgICAgIF9ib3JkZXJZID0gYm9yZGVyLnQgKyBib3JkZXIuYjtcclxuICAgICAgICAgICAgICAgICAgICBib3JkZXIuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm9yZGVyLCBfY3NzQm9yZGVyQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBpbmZvIGZvciBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICBfbWFyZ2luWCA9IG1hcmdpbi5sICsgbWFyZ2luLnI7XHJcbiAgICAgICAgICAgICAgICAgICAgX21hcmdpblkgPSBtYXJnaW4udCArIG1hcmdpbi5iO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hcmdpbi5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShtYXJnaW4sIF9jc3NNYXJnaW5DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUF1dG9XcmFwcGluZ0NhY2hlID0gdGV4dGFyZWFBdXRvV3JhcHBpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkNhY2hlID0gY3NzRGlyZWN0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NCb3hTaXppbmdDYWNoZSA9IGJveFNpemluZztcclxuICAgICAgICAgICAgICAgICAgICBfd2lkdGhBdXRvQ2FjaGUgPSB3aWR0aEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2hlaWdodEF1dG9DYWNoZSA9IGhlaWdodEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc1BhZGRpbmdDYWNoZSA9IHBhZGRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0JvcmRlckNhY2hlID0gYm9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NNYXJnaW5DYWNoZSA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9JRUZpeCBkaXJlY3Rpb24gY2hhbmdlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkICYmIF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5jc3MoX3N0ckZsb2F0LCBpc1JUTFJpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYWRkaW5nLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBzaXplQXV0b0NhcGFibGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdWYWx1ZXMgPSBbcGFkZGluZy50LCBwYWRkaW5nLnIsIHBhZGRpbmcuYiwgcGFkZGluZy5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRvcFJpZ2h0Qm90dG9tTGVmdChjb250ZW50R2x1ZUVsZW1lbnRDU1MsIF9zdHJNYXJnaW5NaW51cywgWy1wYWRkaW5nLnQsIC1wYWRkaW5nLnIsIC1wYWRkaW5nLmIsIC1wYWRkaW5nLmxdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdBYnNvbHV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KHBhZGRpbmdFbGVtZW50Q1NTLCBfc3RyRW1wdHksIHBhZGRpbmdWYWx1ZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KF9pc1RleHRhcmVhID8gdGV4dGFyZWFDU1MgOiBjb250ZW50RWxlbWVudENTUywgX3N0clBhZGRpbmdNaW51cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQocGFkZGluZ0VsZW1lbnRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQoX2lzVGV4dGFyZWEgPyB0ZXh0YXJlYUNTUyA6IGNvbnRlbnRFbGVtZW50Q1NTLCBfc3RyUGFkZGluZ01pbnVzLCBwYWRkaW5nVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmNzcyhwYWRkaW5nRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyh0ZXh0YXJlYUNTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3ZpZXdwb3J0IHNpemUgaXMgcGFkZGluZyBjb250YWluZXIgYmVjYXVzZSBpdCBuZXZlciBoYXMgcGFkZGluZywgbWFyZ2luIGFuZCBhIGJvcmRlci5cclxuICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhU2l6ZSA9IF9pc1RleHRhcmVhID8gdGV4dGFyZWFVcGRhdGUoKSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVNpemVDaGFuZ2VkID0gX2lzVGV4dGFyZWEgJiYgY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYVNpemUsIF90ZXh0YXJlYVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluT3JpZ1NpemUgPSBfaXNUZXh0YXJlYSAmJiB0ZXh0YXJlYVNpemUgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IHRleHRhcmVhRHluV2lkdGggPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNXaWR0aCA6IHRleHRhcmVhU2l6ZS5fb3JpZ2luYWxXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5IZWlnaHQgPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNIZWlnaHQgOiB0ZXh0YXJlYVNpemUuX29yaWdpbmFsSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYVNpemVDYWNoZSA9IHRleHRhcmVhU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0IGF1dG8gLyB3aWR0aCBhdXRvIGluIGNvb3BlcmF0aW9uIHdpdGggY3VycmVudCBwYWRkaW5nICYgYm94U2l6aW5nIGJlaGF2aW9yOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoZWlnaHRBdXRvICYmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZy5jIHx8IGJvcmRlci5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvICYmICh3aWR0aEF1dG9DaGFuZ2VkIHx8IHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nLmMgfHwgYm9yZGVyLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ck1heE1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDsgLy9JRSBGaXhcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAod2lkdGhBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJGbG9hdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyTWF4TWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5OyAvL0lFIEZpeFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWFEeW5PcmlnU2l6ZS53IHx8IF9zdHJBdXRvIDo6IGRvZXNudCB3b3JrcyBiZWNhdXNlIGFwcGxpZWQgbWFyZ2luIHdpbGwgc2hpZnQgd2lkdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eVZhbHVlKF9zdHJXaWR0aCwgJ21heC1jb250ZW50IGludHJpbnNpYycpIHx8IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyRmxvYXRdID0gaXNSVExSaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF0gOjogdXNlIGZvciBhbnRpIHNjcm9sbCBqdW1waW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IHRleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vQ0hFQ0tQT0lOVCBIRVJFIH5cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIFtjb250ZW50KGhvc3QpIGNsaWVudCAvIHNjcm9sbCBzaXplLCBvciB0YXJnZXQgZWxlbWVudCBkaXJlY3Rpb24sIG9yIGNvbnRlbnQoaG9zdCkgbWF4LXNpemVzXSBjaGFuZ2VkLCBvciBmb3JjZSBpcyB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhvc3RTaXplQ2hhbmdlZCB8fCBjb250ZW50U2l6ZUNoYW5nZWQgfHwgdGV4dGFyZWFTaXplQ2hhbmdlZCB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHdpZHRoQXV0byB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGNsaXBBbHdheXNDaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkIHx8IHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgfHwgdGV4dGFyZWFEeW5XaWR0aENoYW5nZWQgfHwgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkIHx8IHRleHRhcmVhQXV0b1dyYXBwaW5nQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3cgPSAnb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dYID0gc3RyT3ZlcmZsb3cgKyAnLXgnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dZID0gc3RyT3ZlcmZsb3cgKyAnLXknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RySGlkZGVuID0gJ2hpZGRlbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJWaXNpYmxlID0gJ3Zpc2libGUnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9SZXNldCB0aGUgdmlld3BvcnQgKHZlcnkgaW1wb3J0YW50IGZvciBuYXRpdmVseSBvdmVybGFpZCBzY3JvbGxiYXJzIGFuZCB6b29tIGNoYW5nZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2Rvbid0IGNoYW5nZSB0aGUgb3ZlcmZsb3cgcHJvcCBhcyBpdCBpcyB2ZXJ5IGV4cGVuc2l2ZSBhbmQgYWZmZWN0cyBwZXJmb3JtYW5jZSAhQSBMT1QhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnRSZXNldENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc2V0WFRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnkgJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnlzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyBfdmlld3BvcnRFbGVtZW50LmNzcyhpc1JUTExlZnQpIDogLV9uYXRpdmVTY3JvbGxiYXJTaXplLnkpIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldEJvdHRvbVRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnggJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnhzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggPyBfdmlld3BvcnRFbGVtZW50LmNzcyhfc3RyQm90dG9tKSA6IC1fbmF0aXZlU2Nyb2xsYmFyU2l6ZS54KSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQodmlld3BvcnRFbGVtZW50UmVzZXRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmNzcyh2aWV3cG9ydEVsZW1lbnRSZXNldENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBzZXZlcmFsIHNpemVzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudE1lYXN1cmVFbGVtZW50ID0gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaW4gRmlyZWZveCBjb250ZW50IGVsZW1lbnQgaGFzIHRvIGhhdmUgb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIGVsZW1lbnQgbWFyZ2lucyBhcmVuJ3QgY2FsY3VsYXRlZCBwcm9wZXJseSwgdGhpcyBlbGVtZW50IHByZXZlbnRzIHRoaXMgYnVnLCBidXQgb25seSBpZiBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiB0ZXh0YXJlYUR5bk9yaWdTaXplLncgfHwgY29udGVudE1lYXN1cmVFbGVtZW50W0xFWElDT04uY1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5PcmlnU2l6ZS5oIHx8IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLmNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSB0aGUgY29ycmVjdCB2aWV3cG9ydCBzdHlsZSBhbmQgbWVhc3VyZSB2aWV3cG9ydCBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTW19zdHJCb3R0b21dID0gd2FzSGVpZ2h0QXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0Qm90dG9tVG1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50UmVzZXRDU1NbaXNSVExMZWZ0XSA9IHdhc1dpZHRoQXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0WFRtcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuY3NzKHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYW5kIGNvcnJlY3Qgc2V2ZXJhbCBzaXplc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSBnZXRIb3N0U2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdEFic29sdXRlUmVjdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBob3N0U2l6ZS53IC0gX21hcmdpblggLSBfYm9yZGVyWCAtIChfaXNCb3JkZXJCb3ggPyAwIDogX3BhZGRpbmdYKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGhvc3RTaXplLmggLSBfbWFyZ2luWSAtIF9ib3JkZXJZIC0gKF9pc0JvcmRlckJveCA/IDAgOiBfcGFkZGluZ1kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZVNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsaWVudC9zY3JvbGxTaXplICsgQWJzb2x1dGVQYWRkaW5nIC0+IGJlY2F1c2UgcGFkZGluZyBpcyBvbmx5IGFwcGxpZWQgdG8gdGhlIHBhZGRpbmdFbGVtZW50IGlmIGl0cyBhYnNvbHV0ZSwgc28geW91IGhhdmUgdG8gYWRkIGl0IG1hbnVhbGx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2hvc3RTaXplIGlzIGNsaWVudFNpemUgLT4gc28gcGFkZGluZyBzaG91bGQgYmUgYWRkZWQgbWFudWFsbHksIHJpZ2h0PyBGQUxTRSEgQmVjYXVzZSBjb250ZW50IGdsdWUgaXMgaW5zaWRlIGhvc3RFbGVtZW50LCBzbyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IE1BVEgubWF4KCh3aWR0aEF1dG8gPyBjb250ZW50U2l6ZS53IDogc2Nyb2xsU2l6ZS53KSArIHBhZGRpbmdBYnNvbHV0ZVgsIGhvc3RBYnNvbHV0ZVJlY3RTaXplLncpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogTUFUSC5tYXgoKGhlaWdodEF1dG8gPyBjb250ZW50U2l6ZS5oIDogc2Nyb2xsU2l6ZS5oKSArIHBhZGRpbmdBYnNvbHV0ZVksIGhvc3RBYnNvbHV0ZVJlY3RTaXplLmgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlU2l6ZS5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjb250ZW50R2x1ZVNpemUsIF9jb250ZW50R2x1ZVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZVNpemVDYWNoZSA9IGNvbnRlbnRHbHVlU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgY29ycmVjdCBjb250ZW50R2x1ZSBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2l6ZSBjb250ZW50R2x1ZSBjb3JyZWN0bHkgdG8gbWFrZSBzdXJlIHRoZSBlbGVtZW50IGhhcyBjb3JyZWN0IHNpemUgaWYgdGhlIHNpemluZyBzd2l0Y2hlcyB0byBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudEdsdWVTaXplLmMgfHwgKGhlaWdodEF1dG8gfHwgd2lkdGhBdXRvKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gY29udGVudEdsdWVTaXplLnc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gY29udGVudEdsdWVTaXplLmg7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWEtc2l6ZXMgYXJlIGFscmVhZHkgY2FsY3VsYXRlZCBjb3JyZWN0bHkgYXQgdGhpcyBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDb3ZlckNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdoID0gc2Nyb2xsYmFyVmFycy5fd19oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJXSCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1NpemUgPSBob3Jpem9udGFsID8gd2lkdGhBdXRvIDogaGVpZ2h0QXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyU2l6ZSA9IGhvcml6b250YWwgPyBfYm9yZGVyWCA6IF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nU2l6ZSA9IGhvcml6b250YWwgPyBfcGFkZGluZ1ggOiBfcGFkZGluZ1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblNpemUgPSBob3Jpem9udGFsID8gX21hcmdpblggOiBfbWFyZ2luWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF0gLSBib3JkZXJTaXplIC0gbWFyZ2luU2l6ZSAtIChfaXNCb3JkZXJCb3ggPyAwIDogcGFkZGluZ1NpemUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2UgY29udGVudEdsdWUgc2l6ZSAtMSBpZiBlbGVtZW50IGlzIG5vdCBhdXRvIHNpemVkLCB0byBtYWtlIHN1cmUgdGhhdCBhIHJlc2l6ZSBldmVudCBoYXBwZW5zIHdoZW4gdGhlIGVsZW1lbnQgc2hyaW5rc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXV0b1NpemUgfHwgKCFhdXRvU2l6ZSAmJiBib3JkZXIuYykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBob3N0QWJzb2x1dGVSZWN0U2l6ZVt3aF0gLSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHNpemUgaXMgYXV0byBhbmQgaG9zdCBpcyBzbWFsbGVyIHRoYW4gc2l6ZSBhcyBtaW4gc2l6ZSwgbWFrZSBjb250ZW50IGdsdWUgc2l6ZSAtMSB0byBtYWtlIHN1cmUgc2l6ZSBjaGFuZ2VzIHdpbGwgYmUgZGV0ZWN0ZWQgKHRoaXMgaXMgb25seSBuZWVkZWQgaWYgcGFkZGluZyBpcyAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdXRvU2l6ZSAmJiAoY29udGVudFNpemVbd2hdIDwgdmlld3BvcnRTaXplKSAmJiAoaG9yaXpvbnRhbCAmJiBfaXNUZXh0YXJlYSA/ICF0ZXh0YXJlYUF1dG9XcmFwcGluZyA6IHRydWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhQ292ZXJDU1Nbc3RyV0hdID0gcGFyc2VUb1plcm9Pck51bWJlcihfdGV4dGFyZWFDb3ZlckVsZW1lbnQuY3NzKHN0cldIKSkgLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2Ugc3VyZSBjb250ZW50IGdsdWUgc2l6ZSBpcyBhdCBsZWFzdCAxXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRTaXplW3doXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBNQVRILm1heCgxLCBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50R2x1ZUVsZW1lbnRDU1NmdW5jdGlvbih0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50LmNzcyh0ZXh0YXJlYUNvdmVyQ1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoQXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8gJiYgIV9pc0JvcmRlckJveCAmJiAhX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckZsb2F0XSA9ICdub25lJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgYW5kIHJlc2V0IGNvbnRlbnQgc3R5bGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYWdhaW4sIGJ1dCB0aGlzIHRpbWUgYWxsIGNvcnJlY3Qgc2l6ZXM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNjcm9sbFNpemUuYyA9IGNvbnRlbnRTaXplQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY29udGVudFNjcm9sbFNpemUsIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUgPSBjb250ZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCB2aWV3cG9ydCBzaXplIGFmdGVyIGNvcnJlY3QgbWVhc3VyaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydFNpemUgPSBnZXRWaWV3cG9ydFNpemUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RTaXplID0gZ2V0SG9zdFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShob3N0U2l6ZSwgX2hvc3RTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdFNpemVDYWNoZSA9IGhvc3RTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEgPSBfaXNUZXh0YXJlYSAmJiAoX3ZpZXdwb3J0U2l6ZS53ID09PSAwIHx8IF92aWV3cG9ydFNpemUuaCA9PT0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c092ZXJmbG93QW1vdW50ID0gX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9ySXNWUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvcklzVkggPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JJc1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QW1vdW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNPdmVyZmxvdyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZU92ZXJmbG93ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYW5TY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0UmVjdCA9IF9wYWRkaW5nRWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldE92ZXJmbG93VmFyaWFibGVzID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQgPSBnZXRTY3JvbGxiYXJWYXJzKCFob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eUkgPSBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aCA9IHNjcm9sbGJhclZhcnMuX3dfaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aEhlaWdodCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxNYXggPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3AgKyAnTWF4JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSB2aWV3cG9ydFJlY3Rbd2lkdGhIZWlnaHRdID8gTUFUSC5hYnModmlld3BvcnRSZWN0W3dpZHRoSGVpZ2h0XSAtIF92aWV3cG9ydFNpemVbd2hdKSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSBwcmV2aW91c092ZXJmbG93QW1vdW50ICYmIHByZXZpb3VzT3ZlcmZsb3dBbW91bnRbeHldID4gMCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlW3Njcm9sbE1heF0gPT09IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3Ytcyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3YtaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSA9IG92ZXJmbG93QmVoYXZpb3JbeHldID09PSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0Ftb3VudFt4eV0gPSBNQVRILm1heCgwLCBNQVRILnJvdW5kKChjb250ZW50U2Nyb2xsU2l6ZVt3aF0gLSBfdmlld3BvcnRTaXplW3doXSkgKiAxMDApIC8gMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QW1vdW50W3h5XSAqPSAoaGlkZU92ZXJmbG93Rm9yY2VUZXh0YXJlYSB8fCAoY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgJiYgZnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ID4gMCAmJiBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPCAxKSkgPyAwIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc092ZXJmbG93W3h5XSA9IG92ZXJmbG93QW1vdW50W3h5XSA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9oaWRlT3ZlcmZsb3c6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ggfHwgeSA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIiBPUiBcIm92ZXJmbG93OiBoaWRkZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94cyB8fCB5cyA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93W3h5XSA9IG92ZXJmbG93QmVoYXZpb3JJc1ZTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPyAoaGFzT3ZlcmZsb3dbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVlNbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVkhbeHlJXSkgOiBoYXNPdmVyZmxvd1t4eV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3dbeHkgKyAncyddID0gaGlkZU92ZXJmbG93W3h5XSA/IChvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0pIDogZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuU2Nyb2xsW3h5XSA9IGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRPdmVyZmxvd1ZhcmlhYmxlcyh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0T3ZlcmZsb3dWYXJpYWJsZXMoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uob3ZlcmZsb3dBbW91bnQsIF9vdmVyZmxvd0Ftb3VudENhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QW1vdW50Q2FjaGUgPSBvdmVyZmxvd0Ftb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3cuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaGFzT3ZlcmZsb3csIF9oYXNPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBoYXNPdmVyZmxvdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93LmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGhpZGVPdmVyZmxvdywgX2hpZGVPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hpZGVPdmVyZmxvd0NhY2hlID0gaGlkZU92ZXJmbG93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBuYXRpdmUgc2Nyb2xsYmFyIGlzIG92ZXJsYXkgYXQgeCBPUiB5IGF4aXMsIHByZXBhcmUgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54IHx8IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBib3JkZXJEZXNpZ24gPSAncHggc29saWQgdHJhbnNwYXJlbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRBcnJhbmdlRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFycmFuZ2VDb250ZW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXJyYW5nZUNoYW5nZWQgPSBmb3JjZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXRDb250ZW50RWxlbWVudENTUztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzT3ZlcmZsb3cueCB8fCBoYXNPdmVyZmxvdy55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNvbnRlbnQudyA9IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgJiYgaGFzT3ZlcmZsb3cueSA/IGNvbnRlbnRTY3JvbGxTaXplLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55IDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50LmggPSBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIGhhc092ZXJmbG93LnggPyBjb250ZW50U2Nyb2xsU2l6ZS5oICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYXJyYW5nZUNvbnRlbnQsIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FycmFuZ2VDb250ZW50U2l6ZUNhY2hlID0gYXJyYW5nZUNvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93LmMgfHwgaGlkZU92ZXJmbG93LmMgfHwgY29udGVudFNjcm9sbFNpemUuYyB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgd2lkdGhBdXRvIHx8IGhlaWdodEF1dG8gfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IGNvbnRlbnRFbGVtZW50Q1NTW19zdHJCb3JkZXJNaW51cyArIGlzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckRpcmVjdGlvbiA9IGhvcml6b250YWwgPyBfc3RyQm90dG9tIDogaXNSVExMZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW52ZXJ0ZWRBdXRvU2l6ZSA9IGhvcml6b250YWwgPyBoZWlnaHRBdXRvIDogd2lkdGhBdXRvO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSAmJiBoYXNPdmVyZmxvd1t4eV0gJiYgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IGludmVydGVkQXV0b1NpemUgPyAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA/IF9zdHJFbXB0eSA6IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSkgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyQm9yZGVyTWludXMgKyBzdHJEaXJlY3Rpb25dID0gKChob3Jpem9udGFsID8gIWludmVydGVkQXV0b1NpemUgOiB0cnVlKSAmJiAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykgPyAoX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbeHldICsgYm9yZGVyRGVzaWduKSA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50W3Njcm9sbGJhclZhcnNJbnZlcnRlZC5fd19oXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckJvcmRlck1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlLCAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50RWxlbWVudENTUyhmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ29udGVudC53ID0gYXJyYW5nZUNvbnRlbnQuaCA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYW5nZUNoYW5nZWQgJiYgIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBoaWRlT3ZlcmZsb3cueSA/IGFycmFuZ2VDb250ZW50LncgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gaGlkZU92ZXJmbG93LnggPyBhcnJhbmdlQ29udGVudC5oIDogX3N0ckVtcHR5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEFycmFuZ2VFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucHJlcGVuZChfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoY29udGVudEFycmFuZ2VFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2V0Vmlld3BvcnRDU1M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgaGFzT3ZlcmZsb3cuYyB8fCBoaWRlT3ZlcmZsb3cuYyB8fCBjb250ZW50U2Nyb2xsU2l6ZS5jIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBjbGlwQWx3YXlzQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW2lzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1MgPSBmdW5jdGlvbiAoaG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHh5ID0gc2Nyb2xsYmFyVmFycy5feF95O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBYWSA9IHNjcm9sbGJhclZhcnMuX1hfWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyRGlyZWN0aW9uID0gaG9yaXpvbnRhbCA/IF9zdHJCb3R0b20gOiBpc1JUTExlZnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50Qm9yZGVyU2l6ZVtzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3dfaF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nIHx8IF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSAtKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSA/IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSA6IF9uYXRpdmVTY3JvbGxiYXJTaXplW3h5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEJvcmRlclNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl93X2hdID0gX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWRbeHldID8gX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl94X3ldIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1ModHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRWaWV3cG9ydENTUyhmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHNjcm9sbCBjb250YWluZXIgaXMgdG9vIHNtYWxsIGFuZCBpZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgd2l0aCBubyBvdmVybGF5IHNjcm9sbGJhciAoYW5kIHNjcm9sbGJhciBzdHlsaW5nIGlzbid0IHBvc3NpYmxlKSwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHZpZXdwb3J0IGVsZW1lbnQgZ3JlYXRlciBpbiBzaXplIChGaXJlZm94IGhpZGUgU2Nyb2xsYmFycyBmaXgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGZpcmVmb3ggc3RhcnRzIGhpZGluZyBzY3JvbGxiYXJzIG9uIHRvbyBzbWFsbCBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCB0aGlzIGJlaGF2aW9yIHRoZSBvdmVyZmxvdyBjYWxjdWxhdGlvbiBtYXkgYmUgaW5jb3JyZWN0IG9yIHRoZSBzY3JvbGxiYXJzIHdvdWxkIGFwcGVhciBzdWRkZW5seVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkyMjg0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKF92aWV3cG9ydFNpemUuaCA8IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnggfHwgX3ZpZXdwb3J0U2l6ZS53IDwgX25hdGl2ZVNjcm9sbGJhck1pblNpemUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoKGhhc092ZXJmbG93LnggJiYgaGlkZU92ZXJmbG93LnggJiYgIV9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLngpIHx8IChoYXNPdmVyZmxvdy55ICYmIGhpZGVPdmVyZmxvdy55ICYmICFfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID0gX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgX3N0clRvcF0gPSAtX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMUmlnaHRdID0gLV9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyUGFkZGluZ01pbnVzICsgaXNSVExMZWZ0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMTGVmdF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgKHggT1IgeSBheGlzKSBhbmQgdGhpcyBvdmVyZmxvdyBzaGFsbCBiZSBoaWRkZW4sIG1ha2Ugb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIG92ZXJmbG93IHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaGFzT3ZlcmZsb3cueCAmJiBoaWRlT3ZlcmZsb3cueCkgfHwgKGhhc092ZXJmbG93LnkgJiYgaGlkZU92ZXJmbG93LnkpIHx8IGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgaGlkZSBpZiBpcyBUZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSAmJiBoaWRlT3ZlcmZsb3dGb3JjZVRleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0ckhpZGRlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNsaXBBbHdheXMgfHwgKG92ZXJmbG93QmVoYXZpb3JJc1ZILnggfHwgb3ZlcmZsb3dCZWhhdmlvcklzVlMueCB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSC55IHx8IG92ZXJmbG93QmVoYXZpb3JJc1ZTLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSB1bi1oaWRlIGlmIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0clZpc2libGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5jc3MocGFkZGluZ0VsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5jc3Modmlld3BvcnRFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2Ugc29mdCByZWRyYXcgaW4gd2Via2l0IGJlY2F1c2Ugd2l0aG91dCB0aGUgc2Nyb2xsYmFycyB3aWxsIG1heSBhcHBlYXIgYmVjYXVzZSBET00gd29udCBiZSByZWRyYXduIHVuZGVyIHNwZWNpYWwgY29uZGl0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChoYXNPdmVyZmxvdy5jIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgd2lkdGhBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkgJiYgIShfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTdHlsZSA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAnc2NhbGUoMSknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS5kaXNwbGF5ID0gJ3J1bi1pbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUuZGlzcGxheSA9IF9zdHJFbXB0eTsgLy98fCBkdW1wOyAvL3VzZSBkdW1wIHRvIHByZXZlbnQgaXQgZnJvbSBkZWxldGlvbiBpZiBtaW5pZnlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUud2Via2l0VHJhbnNmb3JtID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2UgaGFyZCByZWRyYXcgaW4gd2Via2l0IGlmIG5hdGl2ZSBvdmVybGFpZCBzY3JvbGxiYXJzIHNoYWxsIGFwcGVhclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkICYmIGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NoYW5nZSB0byBkaXJlY3Rpb24gUlRMIGFuZCB3aWR0aCBhdXRvIEJ1Z2ZpeCBpbiBXZWJraXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy93aXRob3V0IHRoaXMgZml4LCB0aGUgRE9NIHN0aWxsIHRoaW5rcyB0aGUgc2Nyb2xsYmFyIGlzIExUUiBhbmQgdGh1cyB0aGUgY29udGVudCBpcyBzaGlmdGVkIHRvIHRoZSBsZWZ0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwgJiYgd2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0VG1wID0gX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyRmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aG91dEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgX3N0ckVtcHR5KS5jc3MoX3N0ckxlZnQsIF9zdHJFbXB0eSkucG9zaXRpb24oKS5sZWZ0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgZmxvYXRUbXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQucG9zaXRpb24oKS5sZWZ0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc0xlZnRXaXRob3V0RmxvYXQgIT09IHBvc0xlZnRXaXRoRmxvYXQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJMZWZ0XSA9IHBvc0xlZnRXaXRob3V0RmxvYXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTGVmdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhICYmIGNvbnRlbnRTaXplQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhSW5mbyA9IGdldFRleHRhcmVhSW5mbygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVJvd3NDaGFuZ2VkID0gX3RleHRhcmVhSW5mb0NhY2hlID09PSB1bmRlZmluZWQgPyB0cnVlIDogdGV4dGFyZWFJbmZvLl9yb3dzICE9PSBfdGV4dGFyZWFJbmZvQ2FjaGUuX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclJvdyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUm93O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUluZm8uX2N1cnNvckNvbHVtbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkZXN0Um93ID0gdGV4dGFyZWFJbmZvLl93aWRlc3RSb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RSb3cgPSB0ZXh0YXJlYUluZm8uX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RDb2wgPSB0ZXh0YXJlYUluZm8uX2NvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclBvcyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvck1heCA9IHRleHRhcmVhSW5mby5fY3Vyc29yTWF4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JJc0xhc3RQb3NpdGlvbiA9IChjdXJzb3JQb3MgPj0gY3Vyc29yTWF4ICYmIF90ZXh0YXJlYUhhc0ZvY3VzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFTY3JvbGxBbW91bnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6ICghdGV4dGFyZWFBdXRvV3JhcHBpbmcgJiYgKGN1cnNvckNvbCA9PT0gbGFzdENvbCAmJiBjdXJzb3JSb3cgPT09IHdpZGVzdFJvdykpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueCA6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiAodGV4dGFyZWFBdXRvV3JhcHBpbmcgPyBjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkICYmIChwcmV2aW91c092ZXJmbG93QW1vdW50ID8gKGN1cnJTY3JvbGwueSA9PT0gcHJldmlvdXNPdmVyZmxvd0Ftb3VudC55KSA6IGZhbHNlKSA6IChjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkKSAmJiBjdXJzb3JSb3cgPT09IGxhc3RSb3cpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueSA6IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyU2Nyb2xsLnggPSB0ZXh0YXJlYVNjcm9sbEFtb3VudC54ID4gLTEgPyAoX2lzUlRMICYmIF9ub3JtYWxpemVSVExDYWNoZSAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IDAgOiB0ZXh0YXJlYVNjcm9sbEFtb3VudC54KSA6IGN1cnJTY3JvbGwueDsgLy9pZiBpbnZlcnRlZCwgc2Nyb2xsIHRvIDAgLT4gbm9ybWFsaXplZCB0aGlzIG1lYW5zIHRvIG1heCBzY3JvbGwgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJTY3JvbGwueSA9IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgPiAtMSA/IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgOiBjdXJyU2Nyb2xsLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFJbmZvQ2FjaGUgPSB0ZXh0YXJlYUluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ICYmIGhhc092ZXJmbG93LnggJiYgX25vcm1hbGl6ZVJUTENhY2hlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjcm9sbC54ICs9IF9jb250ZW50Qm9yZGVyU2l6ZS53IHx8IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY3VyclNjcm9sbC54KVtfc3RyU2Nyb2xsVG9wXShjdXJyU2Nyb2xsLnkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIG1hbmFnZW1lbnQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzVmlzaWJpbGl0eVZpc2libGUgPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ3YnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4gPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ2gnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlBdXRvID0gc2Nyb2xsYmFyc1Zpc2liaWxpdHkgPT09ICdhJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eSA9IGZ1bmN0aW9uIChzaG93WCwgc2hvd1kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dZID0gc2hvd1kgPT09IHVuZGVmaW5lZCA/IHNob3dYIDogc2hvd1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZSh0cnVlLCBzaG93WCwgY2FuU2Nyb2xsLngpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZShmYWxzZSwgc2hvd1ksIGNhblNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgY2xhc3MgbmFtZSB3aGljaCBpbmRpY2F0ZXMgc2Nyb2xsYWJsZSBvdmVyZmxvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3csIGhpZGVPdmVyZmxvdy54IHx8IGhpZGVPdmVyZmxvdy55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WCwgaGlkZU92ZXJmbG93LngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLCBoaWRlT3ZlcmZsb3cueSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBvciByZW1vdmUgcnRsIGNsYXNzIG5hbWUgZm9yIHN0eWxpbmcgcHVycG9zZXMgZXhjZXB0IHdoZW4gaXRzIGJvZHksIHRoZW4gdGhlIHNjcm9sbGJhciBzdGF5c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzRGlyZWN0aW9uQ2hhbmdlZCAmJiAhX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFJUTCwgX2lzUlRMKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHJlc2l6ZSBmZWF0dXJlIChDU1MzIHJlc2l6ZSBcInBvbHlmaWxsXCIgZm9yIHRoaXMgcGx1Z2luKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQsIF9yZXNpemVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplLCAhX3Jlc2l6ZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVCLCBfcmVzaXplQm90aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsIF9yZXNpemVIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplViwgX3Jlc2l6ZVZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHNjcm9sbGJhcnMgZ2VuZXJhbCB2aXNpYmlsaXR5ICsgdGhlIHNjcm9sbGJhciBpbnRlcmFjdGl2aXR5ICh1bnVzYWJsZSBjbGFzcyBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGhpZGVPdmVyZmxvdy5jIHx8IGhhc092ZXJmbG93LmMgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RTY3JvbGxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eShjYW5TY3JvbGwueCwgY2FuU2Nyb2xsLnkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc1Zpc2liaWxpdHkoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSB0aGUgc2Nyb2xsYmFycyBhdXRvIGhpZGUgZmVhdHVyZSAoYXV0byBoaWRlIHRoZW0gYWZ0ZXIgc3BlY2lmaWMgYWN0aW9ucylcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoIV9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIsICFfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSBzY3JvbGxiYXJzIGhhbmRsZSBsZW5ndGggJiBvZmZzZXQgLSBkb24ndCByZW1vdmUhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgb3ZlcmZsb3dBbW91bnQuYyB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZUxlbmd0aChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgaW50ZXJhY3Rpdml0eVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUodHJ1ZSwgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUoZmFsc2UsIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsbGJhY2tzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRpcmVjdGlvbkNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTDogX2lzUlRMLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyOiBjc3NEaXJlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY3NzRGlyZWN0aW9uQ2hhbmdlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uSG9zdFNpemVDaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IF9ob3N0U2l6ZUNhY2hlLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IF9ob3N0U2l6ZUNhY2hlLmhcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgaG9zdFNpemVDaGFuZ2VkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Db250ZW50U2l6ZUNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUudyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUuaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBjb250ZW50U2l6ZUNoYW5nZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbk92ZXJmbG93Q2hhbmdlZCcsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGhhc092ZXJmbG93LngsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBoYXNPdmVyZmxvdy55LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeFNjcm9sbGFibGU6IGhpZGVPdmVyZmxvdy54cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlTY3JvbGxhYmxlOiBoaWRlT3ZlcmZsb3cueXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwcGVkOiBoaWRlT3ZlcmZsb3cueCB8fCBoaWRlT3ZlcmZsb3cueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBoYXNPdmVyZmxvdy5jIHx8IGhpZGVPdmVyZmxvdy5jKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25PdmVyZmxvd0Ftb3VudENoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBvdmVyZmxvd0Ftb3VudC54LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogb3ZlcmZsb3dBbW91bnQueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBvdmVyZmxvd0Ftb3VudC5jKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZml4IGJvZHkgbWluIHNpemVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSAmJiBfYm9keU1pblNpemVDYWNoZSAmJiAoX2hhc092ZXJmbG93Q2FjaGUuYyB8fCBfYm9keU1pblNpemVDYWNoZS5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2l0cyBwb3NzaWJsZSB0aGF0IG5vIG1pbiBzaXplIHdhcyBtZWFzdXJlZCB1bnRpbCBub3csIGJlY2F1c2UgdGhlIGNvbnRlbnQgYXJyYW5nZSBlbGVtZW50IHdhcyBqdXN0IGFkZGVkIG5vdywgaW4gdGhpcyBjYXNlLCBtZWFzdXJlIG5vdyB0aGUgbWluIHNpemUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2JvZHlNaW5TaXplQ2FjaGUuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiBfaGFzT3ZlcmZsb3dDYWNoZS54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyTWluTWludXMgKyBfc3RyV2lkdGgsIF9ib2R5TWluU2l6ZUNhY2hlLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX2hhc092ZXJmbG93Q2FjaGUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodCwgX2JvZHlNaW5TaXplQ2FjaGUuaCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYm9keU1pblNpemVDYWNoZS5jID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIGNoYW5nZWRPcHRpb25zLnVwZGF0ZU9uTG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVFbGVtZW50c09uTG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uVXBkYXRlZCcsIHsgZm9yY2VkOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFVwZGF0ZXMgdGhlIGZvdW5kIGVsZW1lbnRzIG9mIHdoaWNoIHRoZSBsb2FkIGV2ZW50IHNoYWxsIGJlIGhhbmRsZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaFVwZGF0ZU9uTG9hZChmdW5jdGlvbiAoaSwgdXBkYXRlT25Mb2FkU2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5maW5kKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uIChpLCBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGVsZW1lbnQgZG9lc24ndCBoYXZlIGEgdXBkYXRlT25Mb2FkQ2FsbGJhY2sgYXBwbGllZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmluQShlbCwgX3VwZGF0ZU9uTG9hZEVsbXMpIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcy5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKGVsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9mZihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjaylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gT3B0aW9ucyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgbmV3IG9wdGlvbnMgYnV0IGRvZXNuJ3QgY2FsbCB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIFRoZSBvYmplY3Qgd2hpY2ggY29udGFpbnMgdGhlIG5ldyBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBjaGFuZ2VkIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldE9wdGlvbnMobmV3T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZGF0ZWRPcHRzID0gX3BsdWdpbnNPcHRpb25zLl92YWxpZGF0ZShuZXdPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBfY3VycmVudE9wdGlvbnMpXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9jdXJyZW50T3B0aW9ucyA9IGV4dGVuZERlZXAoe30sIF9jdXJyZW50T3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fZGVmYXVsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMgPSBleHRlbmREZWVwKHt9LCBfY3VycmVudFByZXBhcmVkT3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBTdHJ1Y3R1cmUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTdHJ1Y3R1cmVET00oZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJQYXJlbnQgPSAncGFyZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJIb3N0ID0gJ29zLXJlc2l6ZS1vYnNlcnZlci1ob3N0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50RnVsbCA9IF9jbGFzc05hbWVUZXh0YXJlYUVsZW1lbnQgKyBfc3RyU3BhY2UgKyBfY2xhc3NOYW1lVGV4dEluaGVyaXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ2xhc3MgPSBfaXNUZXh0YXJlYSA/IF9zdHJTcGFjZSArIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWRvcHRBdHRycyA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnRleHRhcmVhLmluaGVyaXRlZEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZG9wdEF0dHJzTWFwID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGx5QWRvcHRlZEF0dHJzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXBwbHlBZG9wdGVkQXR0cnNFbG0gPSBkZXN0cm95ID8gX3RhcmdldEVsZW1lbnQgOiBfaG9zdEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goYWRvcHRBdHRyc01hcCwgZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PSBMRVhJQ09OLmMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmFkZENsYXNzKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmF0dHIoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RFbGVtZW50Q2xhc3NOYW1lcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RTY3JvbGxiYXJWZXJ0aWNhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RUcmFuc2l0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGhlbWVOb25lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dEluaGVyaXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVDYWNoZV0uam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBob3N0IGVsZW1lbnQgYXMgZmlyc3QgZWxlbWVudCwgYmVjYXVzZSB0aGF0J3MgdGhlIG1vc3QgdXBwZXIgZWxlbWVudCBhbmQgcmVxdWlyZWQgZm9yIHRoZSBvdGhlciBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudCA9IF9ob3N0RWxlbWVudCB8fCAoX2lzVGV4dGFyZWEgPyAoX2RvbUV4aXN0cyA/IF90YXJnZXRFbGVtZW50W3N0clBhcmVudF0oKVtzdHJQYXJlbnRdKClbc3RyUGFyZW50XSgpW3N0clBhcmVudF0oKSA6IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCkpKSA6IF90YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQgPSBfY29udGVudEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZUNvbnRlbnRFbGVtZW50ICsgdGV4dGFyZWFDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudCA9IF92aWV3cG9ydEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCArIHRleHRhcmVhQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudCA9IF9wYWRkaW5nRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lUGFkZGluZ0VsZW1lbnQgKyB0ZXh0YXJlYUNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9zaXplT2JzZXJ2ZXJFbGVtZW50IHx8IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKGNsYXNzTmFtZVJlc2l6ZU9ic2VydmVySG9zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50ID0gX3RleHRhcmVhQ292ZXJFbGVtZW50IHx8IChfaXNUZXh0YXJlYSA/IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVUZXh0YXJlYUNvdmVyRWxlbWVudCkgOiB1bmRlZmluZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FkZCB0aGlzIGNsYXNzIHRvIHdvcmthcm91bmQgY2xhc3MgY2hhbmdpbmcgaXNzdWVzIHdpdGggVUkgZnJhbWV3b3JrcyBlc3BlY2lhbGx5IFZ1ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL29uIGRlc3Ryb3ksIHJlbW92ZSBhbGwgZ2VuZXJhdGVkIGNsYXNzIG5hbWVzIGZyb20gdGhlIGhvc3QgZWxlbWVudCBiZWZvcmUgY29sbGVjdGluZyB0aGUgYWRvcHRlZCBhdHRyaWJ1dGVzIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vdG8gcHJldmVudCBhZG9wdGluZyBnZW5lcmF0ZWQgY2xhc3MgbmFtZXNcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBob3N0RWxlbWVudENsYXNzTmFtZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NvbGxlY3QgYWxsIGFkb3B0ZWQgYXR0cmlidXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIGFkb3B0QXR0cnMgPSB0eXBlKGFkb3B0QXR0cnMpID09IFRZUEVTLnMgPyBhZG9wdEF0dHJzLnNwbGl0KF9zdHJTcGFjZSkgOiBhZG9wdEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShhZG9wdEF0dHJzKSAmJiBfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGFkb3B0QXR0cnMsIGZ1bmN0aW9uIChpLCB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSh2KSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRvcHRBdHRyc01hcFt2XSA9IGRlc3Ryb3kgPyBfaG9zdEVsZW1lbnQuYXR0cih2KSA6IF90YXJnZXRFbGVtZW50LmF0dHIodik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0RWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3RhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfdGFyZ2V0RWxlbWVudC5jc3MoX3N0ckhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmFkZENsYXNzKF9jbGFzc05hbWVUZXh0SW5oZXJpdCkud3JhcChfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50ID0gX3RhcmdldEVsZW1lbnRbc3RyUGFyZW50XSgpLmNzcyhob3N0RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdGhlIGNvcnJlY3QgY2xhc3MgdG8gdGhlIHRhcmdldCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdGFyZ2V0RWxlbWVudCwgX2lzVGV4dGFyZWEgPyBjbGFzc05hbWVUZXh0YXJlYUVsZW1lbnRGdWxsIDogX2NsYXNzTmFtZUhvc3RFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3dyYXAgdGhlIGNvbnRlbnQgaW50byB0aGUgZ2VuZXJhdGVkIGVsZW1lbnRzIHRvIGNyZWF0ZSB0aGUgcmVxdWlyZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQud3JhcElubmVyKF9jb250ZW50RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud3JhcElubmVyKF92aWV3cG9ydEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndyYXBJbm5lcihfcGFkZGluZ0VsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVDb250ZW50RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LnByZXBlbmQoX3RleHRhcmVhQ292ZXJFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseUFkb3B0ZWRBdHRycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF92aWV3cG9ydEVsZW1lbnQsIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2h0bWxFbGVtZW50LCBfY2xhc3NOYW1lSFRNTEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZU9ic2VydmVyRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50TmF0aXZlID0gX2hvc3RFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0VsZW1lbnROYXRpdmUgPSBfcGFkZGluZ0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUgPSBfdmlld3BvcnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnROYXRpdmUgPSBfY29udGVudEVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVWaWV3cG9ydEF0dHJzRnJvbVRhcmdldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsZWFyIHNpemUgb2JzZXJ2ZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50LmNoaWxkcmVuKCkucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhlIHN0eWxlIHByb3BlcnR5IGFuZCBjbGFzc2VzIGZyb20gYWxyZWFkeSBnZW5lcmF0ZWQgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goW19wYWRkaW5nRWxlbWVudCwgX3ZpZXdwb3J0RWxlbWVudCwgX2NvbnRlbnRFbGVtZW50LCBfdGV4dGFyZWFDb3ZlckVsZW1lbnRdLCBmdW5jdGlvbiAoaSwgZWxtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhlbG0ucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBjbGFzc2VzIHRvIHRoZSBob3N0IGVsZW1lbnQgd2hpY2ggd2FzIHJlbW92ZWQgcHJldmlvdXNseSB0byBtYXRjaCB0aGUgZXhwZWN0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9pc1RleHRhcmVhID8gX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgOiBfY2xhc3NOYW1lSG9zdEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgc2l6ZSBvYnNlcnZlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Vud3JhcCB0aGUgY29udGVudCB0byByZXN0b3JlIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNvbnRlbnRzKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQudW53cmFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9ob3N0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF90ZXh0YXJlYUNvdmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlBZG9wdGVkQXR0cnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaHRtbEVsZW1lbnQsIF9jbGFzc05hbWVIVE1MRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIGFsbCB3cmFwcGVyIGVsZW1lbnRzIGludGVyYWN0aXZpdHkgZXZlbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIEV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFN0cnVjdHVyZUV2ZW50cygpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMywgICAgLy9GMSB0byBGMTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgMzMsIDM0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGFnZSB1cCwgcGFnZSBkb3duXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDM3LCAzOCwgMzksIDQwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xlZnQsIHVwLCByaWdodCwgZG93biBhcnJvd3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAxNDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vU2hpZnQsIEN0cmwsIEFsdCwgUGF1c2UsIENhcHNMb2NrLCBOdW1Mb2NrXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcFRpbWVvdXRJZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcERlbGF5ID0gMTc1O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJGb2N1cyA9ICdmb2N1cyc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRleHRhcmVhKGRvQ2xlYXJJbnRlcnZhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUoX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9DbGVhckludGVydmFsICYmIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25TY3JvbGwoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIF9ub3JtYWxpemVSVExDYWNoZSA/IDk5OTk5OTkgOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbkRyb3AoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYU9uRm9jdXMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUhhc0ZvY3VzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBzdHJGb2N1cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25Gb2N1c291dCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhSGFzRm9jdXMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgc3RyRm9jdXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0W0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCA9IHNldEludGVydmFsKHVwZGF0ZVRleHRhcmVhLCAxMDAwIC8gNjApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0KSA8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0LnB1c2goa2V5Q29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gaW5BcnJheShrZXlDb2RlLCB0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3RbTEVYSUNPTi5sXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb250ZW50T25UcmFuc2l0aW9uRW5kKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfYXV0b1VwZGF0ZUNhY2hlID09PSB0cnVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1NpemVBZmZlY3RpbmdDU1NQcm9wZXJ0eShldmVudC5wcm9wZXJ0eU5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdmlld3BvcnRPblNjcm9sbChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbFN0b3BUaW1lb3V0SWQgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsU3RvcFRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25TY3JvbGxTdGFydCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGEgc2Nyb2xsYmFycyBoYW5kbGUgZ2V0cyBkcmFnZ2VkLCB0aGUgbW91c2Vtb3ZlIGV2ZW50IGlzIHJlc3BvbnNpYmxlIGZvciByZWZyZXNoaW5nIHRoZSBoYW5kbGUgb2Zmc2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2JlY2F1c2UgaWYgQ1NTIHNjcm9sbC1zbmFwIGlzIHVzZWQsIHRoZSBoYW5kbGUgb2Zmc2V0IGdldHMgb25seSByZWZyZXNoZWQgb24gZXZlcnkgc25hcCBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIGxvb2tzIGxhZ2d5ICYgY2x1bmt5LCBpdCBsb29rcyBtdWNoIGJldHRlciBpZiB0aGUgb2Zmc2V0IHJlZnJlc2hlcyB3aXRoIHRoZSBtb3VzZW1vdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsJywgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFN0b3BUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9PblNjcm9sbFN0b3A6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChzY3JvbGxTdG9wVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsU3RvcFRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsU3RvcCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBzY3JvbGxTdG9wRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCwgJ2lucHV0JywgdXBkYXRlVGV4dGFyZWEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3RhcmdldEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJLZXlEb3duRXZlbnQsIF9zdHJLZXlVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dGFyZWFPbktleURvd24sIHRleHRhcmVhT25LZXlVcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2Nyb2xsLCAnZHJvcCcsIHN0ckZvY3VzLCBzdHJGb2N1cyArICdvdXQnXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0ZXh0YXJlYU9uU2Nyb2xsLCB0ZXh0YXJlYU9uRHJvcCwgdGV4dGFyZWFPbkZvY3VzLCB0ZXh0YXJlYU9uRm9jdXNvdXRdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF9jb250ZW50RWxlbWVudCwgX3N0clRyYW5zaXRpb25FbmRFdmVudCwgY29udGVudE9uVHJhbnNpdGlvbkVuZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJTY3JvbGwsIHZpZXdwb3J0T25TY3JvbGwsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyBhbGwgc2Nyb2xsYmFyIERPTSBlbGVtZW50cyAoc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIERPTSBzaGFsbCBiZSBidWlsZCBvciBkZXN0cm95ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU2Nyb2xsYmFyc0RPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00gPSBmdW5jdGlvbiAoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJDbGFzc05hbWUgPSBpc0hvcml6b250YWwgPyBfY2xhc3NOYW1lU2Nyb2xsYmFySG9yaXpvbnRhbCA6IF9jbGFzc05hbWVTY3JvbGxiYXJWZXJ0aWNhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhciA9IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVTY3JvbGxiYXIgKyBfc3RyU3BhY2UgKyBzY3JvbGxiYXJDbGFzc05hbWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2ssIHNjcm9sbGJhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlLCBzY3JvbGxiYXIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzICYmICFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXIuYXBwZW5kKHRyYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmFwcGVuZChoYW5kbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogc2Nyb2xsYmFyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiB0cmFjayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGU6IGhhbmRsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyID0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzY3JvbGxiYXJWYXJzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZSA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChbc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlXSwgZnVuY3Rpb24gKGksIGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGVsbS5yZW1vdmVBdHRyKExFWElDT04ucyksIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoc2Nyb2xsYmFyIHx8IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKS5fc2Nyb2xsYmFyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9yaXpvbnRhbEVsZW1lbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ZXJ0aWNhbEVsZW1lbnRzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbEVsZW1lbnRzID0gc2VsZWN0T3JHZW5lcmF0ZVNjcm9sbGJhckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljYWxFbGVtZW50cyA9IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fdHJhY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5faGFuZGxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50ID0gdmVydGljYWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxUcmFja0VsZW1lbnQgPSB2ZXJ0aWNhbEVsZW1lbnRzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCA9IHZlcnRpY2FsRWxlbWVudHMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0U2Nyb2xsYmFyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNldFNjcm9sbGJhckRPTSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGFsbCBzY3JvbGxiYXIgaW50ZXJhY3Rpdml0eSBldmVudHMuICh0cmFjayBhbmQgaGFuZGxlIGRyYWdnaW5nLCBjbGlja2luZywgc2Nyb2xsaW5nKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGlzSG9yaXpvbnRhbCBUcnVlIGlmIHRoZSB0YXJnZXQgc2Nyb2xsYmFyIGlzIHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciwgZmFsc2UgaWYgdGhlIHRhcmdldCBzY3JvbGxiYXIgaXMgdGhlIHZlcnRpY2FsIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJFdmVudHMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGlzSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnNJbmZvID0gc2Nyb2xsYmFyVmFycy5faW5mbztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zaWRlSUZyYW1lID0gX3dpbmRvd0VsZW1lbnROYXRpdmUudG9wICE9PSBfd2luZG93RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSBzY3JvbGxiYXJWYXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIFhZID0gc2Nyb2xsYmFyVmFycy5fWF9ZO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3A7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckFjdGl2ZSA9ICdhY3RpdmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJTbmFwSGFuZGxlID0gJ3NuYXBIYW5kbGUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbGlja0V2ZW50ID0gJ2NsaWNrJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmNyZWFzZURlY3JlYXNlU2Nyb2xsQW1vdW50S2V5Q29kZXMgPSBbMTYsIDE3XTsgLy9zaGlmdCwgY3RybFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja1RpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25JbnZlcnRlZFNjYWxlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQb2ludGVyUG9zaXRpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9tc2llVmVyc2lvbiAmJiBpbnNpZGVJRnJhbWUgPyBldmVudFsnc2NyZWVuJyArIFhZXSA6IENPTVBBVElCSUxJVFkucGFnZShldmVudClbeHldOyAvL3VzZSBzY3JlZW4gY29vcmRpbmF0ZXMgaW4gRURHRSAmIElFIGJlY2F1c2UgdGhlIHBhZ2UgdmFsdWVzIGFyZSBpbmNvcnJlY3QgaW4gZnJhbWVzLlxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24obmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuc2Nyb2xsYmFyc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAwLjU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbER1cmF0aW9uRmFjdG9yID0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoZXZlbnQua2V5Q29kZSwgaW5jcmVhc2VEZWNyZWFzZVNjcm9sbEFtb3VudEtleUNvZGVzKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGV2ZW50LmtleUNvZGUsIGluY3JlYXNlRGVjcmVhc2VTY3JvbGxBbW91bnRLZXlDb2RlcykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudCB8fCBldmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVG91Y2hFdmVudCA9IG9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3NsZWVwaW5nIHx8IF9kZXN0cm95ZWQgfHwgbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB8fCAhX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgfHwgKGlzVG91Y2hFdmVudCAmJiAhZ2V0UHJlcGFyZWRTY3JvbGxiYXJzT3B0aW9uKCd0b3VjaFN1cHBvcnQnKSkgPyBmYWxzZSA6IENPTVBBVElCSUxJVFkubUJ0bihldmVudCkgPT09IDEgfHwgaXNUb3VjaEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5fdHJhY2tMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlTGVuZ3RoID0gc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF3ID0gKGdldFBvaW50ZXJQb3NpdGlvbihldmVudCkgLSBtb3VzZURvd25PZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEZWx0YVBlcmNlbnQgPSBzY3JvbGxSYXcgLyAodHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbERlbHRhID0gKHNjcm9sbFJhbmdlICogc2Nyb2xsRGVsdGFQZXJjZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhID0gaXNGaW5pdGUoc2Nyb2xsRGVsdGEpID8gc2Nyb2xsRGVsdGEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhICo9IC0xO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShNQVRILnJvdW5kKG1vdXNlRG93blNjcm9sbCArIHNjcm9sbERlbHRhKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgbW91c2VEb3duU2Nyb2xsICsgc2Nyb2xsRGVsdGEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3N1cHBvcnRQYXNzaXZlRXZlbnRzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRNb3VzZVRvdWNoVXAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50IHx8IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0cktleURvd25FdmVudCwgX3N0cktleVVwRXZlbnQsIF9zdHJTZWxlY3RTdGFydEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudERyYWdNb3ZlLCBkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuckFGKCkoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsIHN0ckNsaWNrRXZlbnQsIHN0b3BDbGlja0V2ZW50UHJvcGFnYXRpb24sIHRydWUsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhzY3JvbGxiYXJWYXJzLl90cmFjaywgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25PZmZzZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bkludmVydGVkU2NhbGUgPSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrVGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVjdCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZUluc2lkZUhvc3QgPSBldmVudC5jbGllbnRYID49IHJlY3QubGVmdCAmJiBldmVudC5jbGllbnRYIDw9IHJlY3QucmlnaHQgJiYgZXZlbnQuY2xpZW50WSA+PSByZWN0LnRvcCAmJiBldmVudC5jbGllbnRZIDw9IHJlY3QuYm90dG9tO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgbW91c2UgaXMgb3V0c2lkZSBob3N0IGVsZW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW91c2VJbnNpZGVIb3N0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTGVhdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbkhhbmRsZU1vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25IYW5kbGVNb3VzZVRvdWNoRG93bkFjdGlvbihldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uSGFuZGxlTW91c2VUb3VjaERvd25BY3Rpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IGlzTmFOKG1vdXNlRG93blNjcm9sbCkgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLm4gfHwgIV9pc1JUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IG1vdXNlRG93blNjcm9sbCA8IDAgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IGdldEhvc3RFbGVtZW50SW52ZXJ0ZWRTY2FsZSgpW3h5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gZ2V0UG9pbnRlclBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcyA9ICFnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24oc3RyU25hcEhhbmRsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIHN0ckFjdGl2ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCwgc3RyQ2xpY2tFdmVudCwgc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbiwgZmFsc2UsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gfHwgIV9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25UcmFja01vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVG9WaWV3cG9ydFJhdGlvID0gc2Nyb2xsYmFyVmFycy5faW5mby5faGFuZGxlTGVuZ3RoIC8gTWF0aC5yb3VuZChNQVRILm1pbigxLCBfdmlld3BvcnRTaXplW3Njcm9sbGJhclZhcnMuX3dfaF0gLyBfY29udGVudFNjcm9sbFNpemVDYWNoZVtzY3JvbGxiYXJWYXJzLl93X2hdKSAqIHNjcm9sbGJhclZhcnMuX2luZm8uX3RyYWNrTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEaXN0YW5jZSA9IE1BVEgucm91bmQoX3ZpZXdwb3J0U2l6ZVtzY3JvbGxiYXJWYXJzLl93X2hdICogaGFuZGxlVG9WaWV3cG9ydFJhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxCYXNlRHVyYXRpb24gPSAyNzAgKiBoYW5kbGVUb1ZpZXdwb3J0UmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRmlyc3RJdGVyYXRpb25EZWxheSA9IDQwMCAqIGhhbmRsZVRvVmlld3BvcnRSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja09mZnNldCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrLm9mZnNldCgpW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW50U2Nyb2xsID0gZXZlbnQuc2hpZnRLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFRyYW5zaXRpb24gPSBpbnN0YW50U2Nyb2xsICYmIGN0cmxLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNGaXJzdEl0ZXJhdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWFzaW5nID0gJ2xpbmVhcic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluaXNoZWRDb25kaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uRmluc2lzaGVkID0gZnVuY3Rpb24gKHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgdHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEFjdGlvbkluc3RhbnRGaW5pc2hlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb25GaW5zaXNoZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkhhbmRsZU1vdXNlVG91Y2hEb3duQWN0aW9uKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VPZmZzZXQgPSAobW91c2VEb3duT2Zmc2V0IC0gdHJhY2tPZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZU9mZnNldCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0gc2Nyb2xsYmFyVmFyc0luZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEdXJhdGlvbiA9IHNjcm9sbEJhc2VEdXJhdGlvbiAqIHNjcm9sbER1cmF0aW9uRmFjdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZW91dERlbGF5ID0gaXNGaXJzdEl0ZXJhdGlvbiA/IE1BVEgubWF4KHNjcm9sbEZpcnN0SXRlcmF0aW9uRGVsYXksIHNjcm9sbER1cmF0aW9uKSA6IHNjcm9sbER1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gc2Nyb2xsUmFuZ2UgKiAoKG1vdXNlT2Zmc2V0IC0gKGhhbmRsZUxlbmd0aCAvIDIpKSAvICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCkpOyAvLyAxMDAlICogcG9zaXRpb25QZXJjZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBydGxJc05vcm1hbCA9IF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgKCghX3J0bFNjcm9sbEJlaGF2aW9yLmkgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5uKSB8fCBfbm9ybWFsaXplUlRMQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGxDb25kaXRpb24gPSBydGxJc05vcm1hbCA/IGhhbmRsZU9mZnNldCA8IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ID4gbW91c2VPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFuaW1hdGlvbk9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2luZzogZWFzaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcDogZnVuY3Rpb24gKG5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0hhbmRsZXNEZWZpbmVTY3JvbGxQb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKG5vdyk7IC8vaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvaXNzdWVzLzQzNDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIG5vdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBpc0Zpbml0ZShpbnN0YW50U2Nyb2xsUG9zaXRpb24pID8gaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAoc2Nyb2xsUmFuZ2UgLSBpbnN0YW50U2Nyb2xsUG9zaXRpb24pIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9fYmFzZS5zY3JvbGxTdG9wKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFudFNjcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGluc3RhbnRTY3JvbGxQb3NpdGlvbik7IC8vc2Nyb2xsIGluc3RhbnRseSB0byBuZXcgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW50U2Nyb2xsVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gYWZ0ZXIgaW5zdGFudCBzY3JvbGwgKGluIGNhc2UgQ1NTIFNuYXAgUG9pbnRzIGFyZSB1c2VkKSB0byBnZXQgdGhlIGNvcnJlY3Qgc25hcHBlZCBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FuZCB0aGUgYW5pbWF0aW9uIHN0b3BzIGF0IHRoZSBjb3JyZWN0IHBvaW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGwgYmFjayB0byB0aGUgcG9zaXRpb24gYmVmb3JlIGluc3RhbnQgc2Nyb2xsaW5nIHNvIGFuaW1hdGlvbiBjYW4gYmUgcGVyZm9ybWVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGN1cnJTY3JvbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBydGxJc05vcm1hbCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IChzY3JvbGxSYW5nZSAtIGluc3RhbnRTY3JvbGxQb3NpdGlvbikgOiBpbnN0YW50U2Nyb2xsUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gcnRsSXNOb3JtYWwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gPyAtaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbChzY3JvbGxPYmosIGV4dGVuZERlZXAoYW5pbWF0aW9uT2JqLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAxMzAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBzY3JvbGxBY3Rpb25JbnN0YW50RmluaXNoZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsQWN0aW9uSW5zdGFudEZpbmlzaGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzZVNjcm9sbCA9IGlzRmlyc3RJdGVyYXRpb24gPyBkZWNyZWFzZVNjcm9sbENvbmRpdGlvbiA6IGRlY3JlYXNlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoZWRDb25kaXRpb24gPSBydGxJc05vcm1hbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluaXNoZWRDb25kaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tUaW1lb3V0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbEFjdGlvbkZpbnNpc2hlZCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHNldFRpbWVvdXQoc2Nyb2xsQWN0aW9uLCB0aW1lb3V0RGVsYXkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gKGRlY3JlYXNlU2Nyb2xsID8gJy09JyA6ICcrPScpICsgc2Nyb2xsRGlzdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2Uuc2Nyb2xsKHNjcm9sbE9iaiwgZXh0ZW5kRGVlcChhbmltYXRpb25PYmosIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IHNjcm9sbER1cmF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdEl0ZXJhdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdHJsS2V5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKClbeHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gQ09NUEFUSUJJTElUWS5wYWdlKGV2ZW50KVt4eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gIWdldFByZXBhcmVkU2Nyb2xsYmFyc09wdGlvbihzdHJTbmFwSGFuZGxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKHNjcm9sbGJhclZhcnMuX3RyYWNrLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hVcEV2ZW50LCBfc3RyS2V5RG93bkV2ZW50LCBfc3RyS2V5VXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgYm90aCBzY3JvbGxiYXJzIHdpbGwgc3RheSB2aXNpYmxlIGlmIG9uZSBzY3JvbGxiYXIgaXMgaG92ZXJlZCBpZiBhdXRvSGlkZSBpcyBcInNjcm9sbFwiIG9yIFwibW92ZVwiLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVIb3ZlcmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uU2Nyb2xsYmFyTW91c2VUb3VjaERvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX2hhbmRsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uSGFuZGxlTW91c2VUb3VjaERvd24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX3RyYWNrLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsIF9zdHJNb3VzZUVudGVyLCBfc3RyTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtvblRyYWNrTW91c2VUb3VjaERvd24sIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIsIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmVdKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbGJhck1vdXNlVG91Y2hEb3duKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0VHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCAhPT0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyWzBdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2hvd3Mgb3IgaGlkZXMgdGhlIGdpdmVuIHNjcm9sbGJhciBhbmQgYXBwbGllZCBhIGNsYXNzIG5hbWUgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBzY3JvbGxiYXIgaXMgc2Nyb2xsYWJsZSBvciBub3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGlzIHRoZSB0YXJnZXQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgaXMgdGhlIHRhcmdldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzaGFsbEJlVmlzaWJsZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXIgc2hhbGwgYmUgc2hvd24sIGZhbHNlIGlmIGhpZGRlbi5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjYW5TY3JvbGwgVHJ1ZSBpZiB0aGUgc2Nyb2xsYmFyIGlzIHNjcm9sbGFibGUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckFwcGVhcmFuY2UoaXNIb3Jpem9udGFsLCBzaGFsbEJlVmlzaWJsZSwgY2FuU2Nyb2xsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSA9IGlzSG9yaXpvbnRhbCA/IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbiA6IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFyVmVydGljYWxIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckVsZW1lbnQgPSBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQgOiBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSwgIXNoYWxsQmVWaXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhzY3JvbGxiYXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUsICFjYW5TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQXV0b3Nob3dzIC8gYXV0b2hpZGVzIGJvdGggc2Nyb2xsYmFycyB3aXRoLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHNoYWxsQmVWaXNpYmxlIFRydWUgaWYgdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgYXV0b3Nob3duIChvbmx5IHRoZSBjYXNlIGlmIHRoZXkgYXJlIGhpZGRlbiBieSBhIGF1dG9oaWRlKSwgZmFsc2UgaWYgdGhlIHNoYWxsIGJlIGF1dG8gaGlkZGVuLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlbGF5ZnJlZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXJzIHNoYWxsIGJlIGhpZGRlbiB3aXRob3V0IGEgZGVsYXksIGZhbHNlIG9yIHVuZGVmaW5lZCBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoc2hhbGxCZVZpc2libGUsIGRlbGF5ZnJlZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfc2Nyb2xsYmFyc0F1dG9IaWRlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hhbGxCZVZpc2libGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZihfaGFzT3ZlcmZsb3dDYWNoZS54ICYmIF9oaWRlT3ZlcmZsb3dDYWNoZS54cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYoX2hhc092ZXJmbG93Q2FjaGUueSAmJiBfaGlkZU92ZXJmbG93Q2FjaGUueXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbnlBY3RpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBY3RpdmUgPSAnYWN0aXZlJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zY3JvbGxiYXJzSGFuZGxlSG92ZXJlZCAmJiAhX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueUFjdGl2ZSA9IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudC5oYXNDbGFzcyhzdHJBY3RpdmUpIHx8IF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQuaGFzQ2xhc3Moc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlRGVsYXkgPiAwICYmIGRlbGF5ZnJlZSAhPT0gdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBsZW5ndGggb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZ2l0ID0gMTAwMDAwMDtcclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBhbmQgYXBwbHkgaW50ZW5kZWQgaGFuZGxlIGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVSYXRpbyA9IE1BVEgubWluKDEsIF92aWV3cG9ydFNpemVbc2Nyb2xsYmFyVmFycy5fd19oXSAvIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlW3Njcm9sbGJhclZhcnMuX3dfaF0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZUNTU1tzY3JvbGxiYXJWYXJzLl93aWR0aF9oZWlnaHRdID0gKE1BVEguZmxvb3IoaGFuZGxlUmF0aW8gKiAxMDAgKiBkaWdpdCkgLyBkaWdpdCkgKyAnJSc7IC8vdGhlIGxhc3QgKiBkaWdpdCAvIGRpZ2l0IGlzIGZvciBmbG9vcmluZyB0byB0aGUgNHRoIGRpZ2l0XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhoYW5kbGVDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgdGhlIGhhbmRsZSBsZW5ndGggdG8gcmVzcGVjdCBtaW4gJiBtYXggbGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZVswXVsnb2Zmc2V0JyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF07XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aFJhdGlvID0gaGFuZGxlUmF0aW87XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBvZmZzZXQgb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2Nyb2xsT3JUcmFuc2l0aW9uIFRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIGdpdmVuIHNjcm9sbGJhciBheGlzIHRvIHdoaWNoIHRoZSBoYW5kbGUgc2hhbGwgYmUgbW92ZWQgb3IgYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIGEgdHJhbnNpdGlvbiBzaGFsbCBiZSBhcHBsaWVkLiBJZiB1bmRlZmluZWQgb3IgYm9vbGVhbiBpZiB0aGUgY3VycmVudCBzY3JvbGwtb2Zmc2V0IGlzIHRha2VuLiAoaWYgaXNIb3Jpem9udGFsID8gc2Nyb2xsTGVmdCA6IHNjcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHNjcm9sbE9yVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uID0gdHlwZShzY3JvbGxPclRyYW5zaXRpb24pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zaXRpb25EdXJhdGlvbiA9IDI1MDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc0hvcml6b250YWwgPSBfaXNSVEwgJiYgaXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zbGF0ZUJyYWNlID0gJ3RyYW5zbGF0ZSgnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJUcmFuc2Zvcm0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zaXRpb24gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGwgPSBpc0hvcml6b250YWwgPyBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpIDogX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50U2Nyb2xsID0gc2Nyb2xsT3JUcmFuc2l0aW9uID09PSB1bmRlZmluZWQgfHwgdHJhbnNpdGlvbiA/IG5hdGl2ZVNjcm9sbCA6IHNjcm9sbE9yVHJhbnNpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHRoZSBoYW5kbGUgbGVuZ3RoIHRvIHJlc3BlY3QgbWluICYgbWF4IGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrWzBdWydvZmZzZXQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVHJhY2tEaWZmID0gdHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2Zvcm1PZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0RPTlQgdXNlIHRoZSB2YXJpYWJsZSAnX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGVbc2Nyb2xsYmFyVmFycy5fd19oXScgaW5zdGVhZCBvZiAnX3ZpZXdwb3J0RWxlbWVudFswXVsnc2Nyb2xsJyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0nXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYSBiaXQgYmVoaW5kIGR1cmluZyB0aGUgc21hbGwgZGVsYXkgd2hlbiBjb250ZW50IHNpemUgdXBkYXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vKGRlbGF5ID0gbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcsIGlmIGl0cyAwIHRoZW4gdGhpcyB2YXIgY291bGQgYmUgdXNlZClcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF4U2Nyb2xsID0gKF92aWV3cG9ydEVsZW1lbnROYXRpdmVbX3N0clNjcm9sbCArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0gLSBfdmlld3BvcnRFbGVtZW50TmF0aXZlWydjbGllbnQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XSkgKiAoX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgaXNSVExpc0hvcml6b250YWwgPyAtMSA6IDEpOyAvLyogLTEgaWYgcnRsIHNjcm9sbCBtYXggaXMgbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0U2Nyb2xsUmF0aW8gPSBmdW5jdGlvbiAoYmFzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4oYmFzZSAvIG1heFNjcm9sbCkgPyAwIDogTUFUSC5tYXgoMCwgTUFUSC5taW4oMSwgYmFzZSAvIG1heFNjcm9sbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldEhhbmRsZU9mZnNldCA9IGZ1bmN0aW9uIChzY3JvbGxSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gaGFuZGxlVHJhY2tEaWZmICogc2Nyb2xsUmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IGlzTmFOKG9mZnNldCkgPyAwIDogb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAoaXNSVExpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKSA/ICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCAtIG9mZnNldCkgOiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IE1BVEgubWF4KDAsIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF0aW8gPSBnZXRTY3JvbGxSYXRpbyhuYXRpdmVTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1bnNuYXBwZWRTY3JvbGxSYXRpbyA9IGdldFNjcm9sbFJhdGlvKGN1cnJlbnRTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVPZmZzZXQgPSBnZXRIYW5kbGVPZmZzZXQodW5zbmFwcGVkU2Nyb2xsUmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzbmFwcGVkSGFuZGxlT2Zmc2V0ID0gZ2V0SGFuZGxlT2Zmc2V0KHNjcm9sbFJhdGlvKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX21heFNjcm9sbCA9IG1heFNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbCA9IG5hdGl2ZVNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbFJhdGlvID0gc2Nyb2xsUmF0aW87XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1PZmZzZXQgPSBpc1JUTGlzSG9yaXpvbnRhbCA/IC0odHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGggLSBoYW5kbGVPZmZzZXQpIDogaGFuZGxlT2Zmc2V0OyAvL2luIHB4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJhbnNmb3JtT2Zmc2V0ID0gKHRyYW5zZm9ybU9mZnNldCAvIHRyYWNrTGVuZ3RoICogMTAwKSAqICh0cmFja0xlbmd0aCAvIGhhbmRsZUxlbmd0aCk7IC8vaW4gJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGVWYWx1ZSA9IGlzSG9yaXpvbnRhbCA/IHN0clRyYW5zbGF0ZUJyYWNlICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4LCAwKScgOiBzdHJUcmFuc2xhdGVCcmFjZSArICcwLCAnICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4KSc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNmb3JtXSA9IHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBvciBjbGVhciB1cCB0cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNpdGlvbl0gPSB0cmFuc2l0aW9uICYmIE1BVEguYWJzKGhhbmRsZU9mZnNldCAtIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQpID4gMSA/IGdldENTU1RyYW5zaXRpb25TdHJpbmcoc2Nyb2xsYmFyVmFycy5faGFuZGxlKSArICcsICcgKyAoc3RyVHJhbnNmb3JtICsgX3N0clNwYWNlICsgdHJhbnNpdGlvbkR1cmF0aW9uICsgJ21zJykgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ1NTW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXSA9IGhhbmRsZU9mZnNldDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb25seSBhcHBseSBjc3MgaWYgb2Zmc2V0IGhhcyBjaGFuZ2VkIGFuZCBvdmVyZmxvdyBleGlzdHMuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5jc3MoaGFuZGxlQ1NTKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2xlYXIgdXAgdHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2Zvcm0gJiYgX3N1cHBvcnRUcmFuc2l0aW9uICYmIHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5vbmUoX3N0clRyYW5zaXRpb25FbmRFdmVudCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhzdHJUcmFuc2l0aW9uLCBfc3RyRW1wdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQgPSBoYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX3NuYXBwZWRIYW5kbGVPZmZzZXQgPSBzbmFwcGVkSGFuZGxlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aCA9IHRyYWNrTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVmcmVzaGVzIHRoZSBpbnRlcmFjdGl2aXR5IG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc1RyYWNrIFRydWUgaWYgdGhlIHRyYWNrIGVsZW1lbnQgaXMgdGhlIHRhcmdldCwgZmFsc2UgaWYgdGhlIGhhbmRsZSBlbGVtZW50IGlzIHRoZSB0YXJnZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVHJ1ZSBmb3IgaW50ZXJhY3Rpdml0eSBmYWxzZSBmb3Igbm8gaW50ZXJhY3Rpdml0eS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhcnNJbnRlcmFjdGl2ZShpc1RyYWNrLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb24gPSB2YWx1ZSA/ICdyZW1vdmVDbGFzcycgOiAnYWRkQ2xhc3MnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50MSA9IGlzVHJhY2sgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudDIgPSBpc1RyYWNrID8gX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gaXNUcmFjayA/IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA6IF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmY7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQxW2FjdGlvbl0oY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50MlthY3Rpb25dKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGlzIHVzZWQgZm9yIGZhc3QgYWNjZXNzIGZvciBzcGVjaWZpYyB2YXJpYWJsZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIHZhcnMgc2hhbGwgYmUgYWNjZXNzZWQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgdmFycyBzaGFsbCBiZSBhY2Nlc3NlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7d2g6IHN0cmluZywgV0g6IHN0cmluZywgbHQ6IHN0cmluZywgX3doOiBzdHJpbmcsIF9sdDogc3RyaW5nLCB0OiAqLCBoOiAqLCBjOiB7fSwgczogKn19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3dpZHRoX2hlaWdodDogaXNIb3Jpem9udGFsID8gX3N0cldpZHRoIDogX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1dpZHRoX0hlaWdodDogaXNIb3Jpem9udGFsID8gJ1dpZHRoJyA6ICdIZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbGVmdF90b3A6IGlzSG9yaXpvbnRhbCA/IF9zdHJMZWZ0IDogX3N0clRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX0xlZnRfVG9wOiBpc0hvcml6b250YWwgPyAnTGVmdCcgOiAnVG9wJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3hfeTogaXNIb3Jpem9udGFsID8gX3N0clggOiBfc3RyWSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1hfWTogaXNIb3Jpem9udGFsID8gJ1gnIDogJ1knLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd19oOiBpc0hvcml6b250YWwgPyAndycgOiAnaCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sX3Q6IGlzSG9yaXpvbnRhbCA/ICdsJyA6ICd0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZTogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2luZm86IGlzSG9yaXpvbnRhbCA/IF9zY3JvbGxIb3Jpem9udGFsSW5mbyA6IF9zY3JvbGxWZXJ0aWNhbEluZm9cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFyIENvcm5lciA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyB0aGUgc2Nyb2xsYmFyIGNvcm5lciBET00gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBET00gc2hhbGwgYmUgYnVpbGQgb3IgZGVzdHJveWVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFNjcm9sbGJhckNvcm5lckRPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQgPSBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50LmFwcGVuZChfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhbGwgc2Nyb2xsYmFyIGNvcm5lciBpbnRlcmFjdGl2aXR5IGV2ZW50cy5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJDb3JuZXJFdmVudHMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZUlGcmFtZSA9IF93aW5kb3dFbGVtZW50TmF0aXZlLnRvcCAhPT0gX3dpbmRvd0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blBvc2l0aW9uID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWNvbm5lY3RNdXRhdGlvbk9ic2VydmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZU9mZnNldCA9IGdldENvb3JkaW5hdGVzKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9yZXNpemVIb3Jpem9udGFsIHx8IF9yZXNpemVCb3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSAobW91c2VEb3duU2l6ZS53ICsgKHBhZ2VPZmZzZXQueCAtIG1vdXNlRG93blBvc2l0aW9uLngpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS54KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcmVzaXplVmVydGljYWwgfHwgX3Jlc2l6ZUJvdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSAobW91c2VEb3duU2l6ZS5oICsgKHBhZ2VPZmZzZXQueSAtIG1vdXNlRG93blBvc2l0aW9uLnkpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5jc3MoaG9zdEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50TW91c2VUb3VjaFVwKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRJc1RydXN0ZWQgPSBldmVudCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJTZWxlY3RTdGFydEV2ZW50LCBfc3RyTW91c2VUb3VjaE1vdmVFdmVudCwgX3N0ck1vdXNlVG91Y2hVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE9uU2VsZWN0U3RhcnQsIGRvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2JvZHlFbGVtZW50LCBfY2xhc3NOYW1lRHJhZ2dpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVsZWFzZUNhcHR1cmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5yZWxlYXNlQ2FwdHVyZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50SXNUcnVzdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0TXV0YXRpb25PYnNlcnZlcilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TXV0YXRpb25PYnNlcnZlcnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNUb3VjaEV2ZW50ID0gb3JpZ2luYWxFdmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfc2xlZXBpbmcgfHwgX2Rlc3Ryb3llZCA/IGZhbHNlIDogQ09NUEFUSUJJTElUWS5tQnRuKGV2ZW50KSA9PT0gMSB8fCBpc1RvdWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldENvb3JkaW5hdGVzKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfbXNpZVZlcnNpb24gJiYgaW5zaWRlSUZyYW1lID8geyB4OiBldmVudC5zY3JlZW5YLCB5OiBldmVudC5zY3JlZW5ZIH0gOiBDT01QQVRJQklMSVRZLnBhZ2UoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9uTW91c2VUb3VjaERvd25Db250aW51ZShldmVudCkgJiYgIV9yZXNpemVOb25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duUG9zaXRpb24gPSBnZXRDb29yZGluYXRlcyhldmVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2l6ZS53ID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddIC0gKCFfaXNCb3JkZXJCb3ggPyBfcGFkZGluZ1ggOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNpemUuaCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXSAtICghX2lzQm9yZGVyQm94ID8gX3BhZGRpbmdZIDogMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2VsZWN0U3RhcnRFdmVudCwgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50T25TZWxlY3RTdGFydCwgZG9jdW1lbnREcmFnTW92ZSwgZG9jdW1lbnRNb3VzZVRvdWNoVXBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQuc2V0Q2FwdHVyZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5zZXRDYXB0dXJlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFV0aWxzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIG5hbWUuIFRoZSBDb250ZXh0IG9mIHRoaXMgY2FsbGJhY2sgaXMgYWx3YXlzIF9iYXNlICh0aGlzKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3Mgd2l0aCB3aGljaCB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlcGVuZGVudCBCb29sZWFuIHdoaWNoIGRlY2lkZXMgd2hldGhlciB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgZmlyZWQsIHVuZGVmaW5lZCBpcyBsaWtlIGEgXCJ0cnVlXCIgdmFsdWUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2sobmFtZSwgYXJncywgZGVwZW5kZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVudCA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLmNhbGxiYWNrc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbk9uTmFtZSA9IG5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uT25OYW1lLnN1YnN0cigwLCAyKSA9PT0gJ29uJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk9uTmFtZSA9IGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMiwgMSkudG9Mb3dlckNhc2UoKSArIGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShjYWxsYmFjaykgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoX2Jhc2UsIGFyZ3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChfZXh0ZW5zaW9ucywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGV4dC5vbikgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQub24oZXh0ZW5zaW9uT25OYW1lLCBhcmdzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2FsbGJhY2tzSW5pdFFldWV1ZS5wdXNoKHsgbjogbmFtZSwgYTogYXJncyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgcHJvcGVydGllcywgd2l0aCBhIGdpdmVuIHByZWZpeCwgb2YgdGhlIGdpdmVuIGNzcyBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0Q1NTT2JqZWN0IFRoZSBjc3Mgb2JqZWN0IHRvIHdoaWNoIHRoZSB2YWx1ZXMgc2hhbGwgYmUgYXBwbGllZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdwYWRkaW5nLScgaXMgYSB2YWxpZCBwcmVmaXgpXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWVzIEEgYXJyYXkgb2YgdmFsdWVzIHdoaWNoIHNoYWxsIGJlIGFwcGxpZWQgdG8gdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgLXByb3BlcnRpZXMuIFRoZSBhcnJheSBvcmRlciBpcyBbdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoaXMgYXJndW1lbnQgaXMgdW5kZWZpbmVkIHRoZSB2YWx1ZSAnJyAoZW1wdHkgc3RyaW5nKSB3aWxsIGJlIGFwcGxpZWQgdG8gYWxsIHByb3BlcnRpZXMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldFRvcFJpZ2h0Qm90dG9tTGVmdCh0YXJnZXRDU1NPYmplY3QsIHByZWZpeCwgdmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4IHx8IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMgfHwgW19zdHJFbXB0eSwgX3N0ckVtcHR5LCBfc3RyRW1wdHksIF9zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldENTU09iamVjdFtwcmVmaXggKyBfc3RyVG9wXSA9IHZhbHVlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0clJpZ2h0XSA9IHZhbHVlc1sxXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0ckJvdHRvbV0gPSB2YWx1ZXNbMl07XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q1NTT2JqZWN0W3ByZWZpeCArIF9zdHJMZWZ0XSA9IHZhbHVlc1szXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIENTUyBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBwcmVmaXggZnJvbSB0aGUgaG9zdCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IG9mIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIGNzcyBwcm9wZXJ0aWVzLiAoZXhhbXBsZTogJ3BhZGRpbmctJyBpcyBhIHZhbGlkIHByZWZpeClcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzdWZmaXggVGhlIHN1ZmZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdib3JkZXItJyBpcyBhIHZhbGlkIHByZWZpeCB3aXRoICctd2lkdGgnIGlzIGEgdmFsaWQgc3VmZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9YIFRydWUgaWYgdGhlIHggYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9ZIFRydWUgaWYgdGhlIHkgYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t9fSBUaGUgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBudW1iZXJzIG9mIHRoZSByZWFkIENTUyBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KHByZWZpeCwgc3VmZml4LCB6ZXJvWCwgemVyb1kpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWZmaXggPSBzdWZmaXggfHwgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeCB8fCBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdDogemVyb1kgPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJUb3AgKyBzdWZmaXgpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcjogemVyb1ggPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJSaWdodCArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBiOiB6ZXJvWSA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckJvdHRvbSArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsOiB6ZXJvWCA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckxlZnQgKyBzdWZmaXgpKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBDU1MgdHJhbnNpdGlvbiBzdHJpbmcgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHRyYW5zaXRpb24gc3RyaW5nIHNoYWxsIGJlIHJldHVybmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIENTUyB0cmFuc2l0aW9uIHN0cmluZyBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRDU1NUcmFuc2l0aW9uU3RyaW5nKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblN0ciA9IFZFTkRPUlMuX2Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFzc2VtYmxlZFZhbHVlID0gZWxlbWVudC5jc3ModHJhbnNpdGlvblN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFzc2VtYmxlZFZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXNzZW1ibGVkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cFN0cmluZyA9ICdcXFxccyooJyArICcoW14sKF0rKFxcXFwoLis/XFxcXCkpPykrJyArICcpW1xcXFxzLF0qJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwTWFpbiA9IG5ldyBSZWdFeHAocmVnRXhwU3RyaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwVmFsaWRhdGUgPSBuZXcgUmVnRXhwKCdeKCcgKyByZWdFeHBTdHJpbmcgKyAnKSskJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSAncHJvcGVydHkgZHVyYXRpb24gdGltaW5nLWZ1bmN0aW9uIGRlbGF5Jy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFycmF5O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgajtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRDc3NTdHlsZUJ5Q29tbWEgPSBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0clJlc3VsdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0ci5tYXRjaChyZWdFeHBWYWxpZGF0ZSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3RyLm1hdGNoKHJlZ0V4cE1haW4pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJSZXN1bHQucHVzaChSZWdFeHAuJDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocmVnRXhwTWFpbiwgX3N0ckVtcHR5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0clJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJvcGVydGllc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJheSA9IHNwbGl0Q3NzU3R5bGVCeUNvbW1hKGVsZW1lbnQuY3NzKHRyYW5zaXRpb25TdHIgKyAnLScgKyBwcm9wZXJ0aWVzW2ldKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUFycmF5W0xFWElDT04ubF07IGorKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtqXSA9IChyZXN1bHRbal0gPyByZXN1bHRbal0gKyBfc3RyU3BhY2UgOiBfc3RyRW1wdHkpICsgdmFsdWVBcnJheVtqXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcsICcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2VuZXJhdGVzIGEgUmVndWxhciBFeHByZXNzaW9uIHdoaWNoIG1hdGNoZXMgd2l0aCBhIHN0cmluZyB3aGljaCBzdGFydHMgd2l0aCAnb3MtaG9zdCcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhDdXJyQ2xhc3NOYW1lT3B0aW9uIFRoZSBSZWd1bGFyIEV4cHJlc3Npb24gYWxzbyBtYXRjaGVzIGlmIHRoZSBzdHJpbmcgaXMgdGhlIGN1cnJlbnQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2l0aE9sZENsYXNzTmFtZU9wdGlvbiBUaGUgUmVndWxhciBFeHByZXNzaW9uIGFsc28gbWF0Y2hlcyBpZiB0aGUgc3RyaW5nIGlzIHRoZSBvbGQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY3JlYXRlSG9zdENsYXNzTmFtZVJlZ0V4cCh3aXRoQ3VyckNsYXNzTmFtZU9wdGlvbiwgd2l0aE9sZENsYXNzTmFtZU9wdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXBwZW5kaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVuZENsYXNzZXMgPSBmdW5jdGlvbiAoY2xhc3NlcywgY29uZGl0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25kaXRpb24gJiYgdHlwZW9mIGNsYXNzZXMgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgPSBjbGFzc2VzLnNwbGl0KF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3BsaXRbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ICs9ICd8JyArIHNwbGl0W2ldICsgJyQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BsaXRbaV0ucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKSBmb3IgZXNjYXBpbmcgcmVnZXggY2hhcmFjdGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBlbmRpeDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChcclxuICAgICAgICAgICAgICAgICAgICAgICAgJyheJyArIF9jbGFzc05hbWVIb3N0RWxlbWVudCArICcoWy1fXS4rfCkkKScgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRDbGFzc2VzKF9jbGFzc05hbWVDYWNoZSwgd2l0aEN1cnJDbGFzc05hbWVPcHRpb24pICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ2xhc3Nlcyhfb2xkQ2xhc3NOYW1lLCB3aXRoT2xkQ2xhc3NOYW1lT3B0aW9uKSwgJ2cnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGhvc3QtZWxlbWVudHMgaW52ZXJ0ZWQgc2NhbGUuIChpbnZlcnRlZFNjYWxlID0gMSAvIHNjYWxlKVxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t4OiBudW1iZXIsIHk6IG51bWJlcn19IFRoZSBzY2FsZSBvZiB0aGUgaG9zdC1lbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRIb3N0RWxlbWVudEludmVydGVkU2NhbGUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogX3N1cHBvcnRUcmFuc2Zvcm0gPyAxIC8gKE1BVEgucm91bmQocmVjdC53aWR0aCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10pIHx8IDEgOiAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfc3VwcG9ydFRyYW5zZm9ybSA/IDEgLyAoTUFUSC5yb3VuZChyZWN0LmhlaWdodCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vSF0pIHx8IDEgOiAxXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvIFRoZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY2hlY2tlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBpc0hUTUxFbGVtZW50KG8pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3duZXJEb2N1bWVudCA9ICdvd25lckRvY3VtZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySFRNTEVsZW1lbnQgPSAnSFRNTEVsZW1lbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSBvICYmIG9bc3RyT3duZXJEb2N1bWVudF0gPyAob1tzdHJPd25lckRvY3VtZW50XS5wYXJlbnRXaW5kb3cgfHwgd2luZG93KSA6IHdpbmRvdztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygd25kW3N0ckhUTUxFbGVtZW50XSA9PSBUWVBFUy5vID8gbyBpbnN0YW5jZW9mIHduZFtzdHJIVE1MRWxlbWVudF0gOiAvL0RPTTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8gJiYgdHlwZW9mIG8gPT0gVFlQRVMubyAmJiBvICE9PSBudWxsICYmIG8ubm9kZVR5cGUgPT09IDEgJiYgdHlwZW9mIG8ubm9kZU5hbWUgPT0gVFlQRVMuc1xyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyAyIGFycmF5cyBhbmQgcmV0dXJucyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGVtIGFzIGEgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gYTEgVGhlIGZpcnN0IGFycmF5IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGEyIFRoZSBzZWNvbmQgYXJyYXkgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gYXJyYXlzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRBcnJheURpZmZlcmVuY2VzKGExLCBhMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaztcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTEubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFbYTFbaV1dID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFbYTJbaV1dKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFbYTJbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2EyW2ldXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoayBpbiBhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnB1c2goayk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpZmY7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIFplcm8gb3IgdGhlIG51bWJlciB0byB3aGljaCB0aGUgdmFsdWUgY2FuIGJlIHBhcnNlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgd2hpY2ggc2hhbGwgYmUgcGFyc2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHRvRmxvYXQgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIG51bWJlciBzaGFsbCBiZSBwYXJzZWQgdG8gYSBmbG9hdC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VUb1plcm9Pck51bWJlcih2YWx1ZSwgdG9GbG9hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBudW0gPSB0b0Zsb2F0ID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiBwYXJzZUludCh2YWx1ZSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc05hTihudW0pID8gMCA6IG51bTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgc2V2ZXJhbCBpbmZvcm1hdGlvbiBvZiB0aGUgdGV4dGFyZWEgYW5kIHJldHVybnMgdGhlbSBhcyBhIG9iamVjdCBvciB1bmRlZmluZWQgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IGl0LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3tjdXJzb3JSb3c6IE51bWJlciwgY3Vyc29yQ29sLCByb3dzOiBOdW1iZXIsIGNvbHM6IG51bWJlciwgd1JvdzogbnVtYmVyLCBwb3M6IG51bWJlciwgbWF4IDogbnVtYmVyfX0gb3IgdW5kZWZpbmVkIGlmIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFRleHRhcmVhSW5mbygpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3JlYWQgbmVlZGVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUN1cnNvclBvc2l0aW9uID0gX3RhcmdldEVsZW1lbnROYXRpdmUuc2VsZWN0aW9uU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhQ3Vyc29yUG9zaXRpb24gPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZSA9IF90YXJnZXRFbGVtZW50LnZhbCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxlbmd0aCA9IHRleHRhcmVhVmFsdWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFSb3dTcGxpdCA9IHRleHRhcmVhVmFsdWUuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RSb3cgPSB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ3VycmVudEN1cnNvclJvd1NwbGl0ID0gdGV4dGFyZWFWYWx1ZS5zdWJzdHIoMCwgdGV4dGFyZWFDdXJzb3JQb3NpdGlvbikuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWRlc3RSb3cgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RDb2wgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JSb3cgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFt0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdIC0gMV1bTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcm93Q29scztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9nZXQgd2lkZXN0IFJvdyBhbmQgdGhlIGxhc3QgY29sdW1uIG9mIHRoZSB0ZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dDb2xzID0gdGV4dGFyZWFSb3dTcGxpdFtpXVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93Q29scyA+IHRleHRhcmVhTGFzdENvbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkZXN0Um93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUxhc3RDb2wgPSByb3dDb2xzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUm93OiBjdXJzb3JSb3csIC8vY3Vyc29yUm93XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JDb2x1bW46IGN1cnNvckNvbCwgLy9jdXJzb3JDb2xcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Jvd3M6IHRleHRhcmVhTGFzdFJvdywgLy9yb3dzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb2x1bW5zOiB0ZXh0YXJlYUxhc3RDb2wsIC8vY29sc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd2lkZXN0Um93OiB3aWRlc3RSb3csIC8vd1Jvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUG9zaXRpb246IHRleHRhcmVhQ3Vyc29yUG9zaXRpb24sIC8vcG9zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JNYXg6IHRleHRhcmVhTGVuZ3RoIC8vbWF4XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIERldGVybWluZXMgd2hldGhlciBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChfaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NhY2hlICYmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGVsZW1lbnQgd2hpY2ggaXMgdXNlZCB0byBtZWFzdXJlIHRoZSBjb250ZW50IHNpemUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGV4dGFyZWFDb3ZlciBpZiB0YXJnZXQgZWxlbWVudCBpcyB0ZXh0YXJlYSBlbHNlIHRoZSBDb250ZW50RWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfaXNUZXh0YXJlYSA/IF90ZXh0YXJlYUNvdmVyRWxlbWVudFswXSA6IF9jb250ZW50RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdlbmVyYXRlcyBhIHN0cmluZyB3aGljaCByZXByZXNlbnRzIGEgSFRNTCBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3NlcyBvciBhdHRyaWJ1dGVzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzZXNPckF0dHJzIFRoZSBjbGFzcyBvZiB0aGUgZGl2IGFzIHN0cmluZyBvciBhIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBkaXYuIChUaGUgY2xhc3MgYXR0cmlidXRlIGNhbiBhbHNvIGJlIHdyaXR0ZW4gYXMgXCJjbGFzc05hbWVcIi4pXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgZGl2IGFzIHN0cmluZy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb25jYXRlZCBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBhIEhUTUwgZGl2IGFuZCBpdHMgY29udGVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVEaXYoY2xhc3Nlc09yQXR0cnMsIGNvbnRlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxkaXYgJyArIChjbGFzc2VzT3JBdHRycyA/IHR5cGUoY2xhc3Nlc09yQXR0cnMpID09IFRZUEVTLnMgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnY2xhc3M9XCInICsgY2xhc3Nlc09yQXR0cnMgKyAnXCInIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnMgPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoY2xhc3Nlc09yQXR0cnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gY2xhc3Nlc09yQXR0cnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzICs9IChrZXkgPT09ICdjJyA/ICdjbGFzcycgOiBrZXkpICsgJz1cIicgKyBjbGFzc2VzT3JBdHRyc1trZXldICsgJ1wiICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKCkgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyRW1wdHkpICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJz4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQgfHwgX3N0ckVtcHR5KSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2VsZWN0cyBvciBnZW5lcmF0ZXMgYSBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3MgYXR0cmlidXRlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzTmFtZSBUaGUgY2xhc3MgbmFtZXMgKGRpdmlkZWQgYnkgc3BhY2VzKSBvZiB0aGUgZGl2IHdoaWNoIHNoYWxsIGJlIHNlbGVjdGVkIG9yIGdlbmVyYXRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiBUaGUgcGFyZW50IGVsZW1lbnQgZnJvbSB3aGljaCBvZiB0aGUgZWxlbWVudCBzaGFsbCBiZSBzZWxlY3RlZC4gKGlmIHVuZGVmaW5lZCBvciBib29sZWFuIGl0cyBob3N0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAqIElmIGl0cyBhIGJvb2xlYW4gaXQgZGVjaWRlcyB3aGV0aGVyIG9ubHkgdGhlIGNoaWxkcmVuIG9mIHRoZSBob3N0IGVsZW1lbnQgc2hhbGwgYmUgc2VsZWN0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGdlbmVyYXRlZCBvciBzZWxlY3RlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhjbGFzc05hbWUsIHNlbGVjdFBhcmVudE9yT25seUNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9ubHlDaGlsZHJlbiA9IHR5cGUoc2VsZWN0UGFyZW50T3JPbmx5Q2hpbGRyZW4pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdFBhcmVudCA9IG9ubHlDaGlsZHJlbiA/IF9ob3N0RWxlbWVudCA6IChzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiB8fCBfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKF9kb21FeGlzdHMgJiYgIXNlbGVjdFBhcmVudFtMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG51bGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfZG9tRXhpc3RzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGVjdFBhcmVudFtvbmx5Q2hpbGRyZW4gPyAnY2hpbGRyZW4nIDogJ2ZpbmQnXShfc3RyRG90ICsgY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCBfc3RyRG90KSkuZXEoMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRlJBTUVXT1JLKGdlbmVyYXRlRGl2KGNsYXNzTmFtZSkpXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGZyb20gd2hpY2ggdGhlIHByb3BlcnR5IHZhbHVlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwYXRoIFRoZSBwcm9wZXJ0eSBvZiB3aGljaCB0aGUgdmFsdWUgc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzZWFyY2hlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWQgb2YgdGhlIHByb3BlcnR5IHdhc24ndCBmb3VuZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0T2JqZWN0UHJvcFZhbChvYmosIHBhdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRzID0gcGF0aC5zcGxpdChfc3RyRG90KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ialtMRVhJQ09OLmhPUF0oc3BsaXRzW2ldKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW3NwbGl0c1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpIDwgc3BsaXRzLmxlbmd0aCAmJiB0eXBlKHZhbCkgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IHZhbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgZnJvbSB3aGljaCB0aGUgcHJvcGVydHkgdmFsdWUgc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHBhdGggVGhlIHByb3BlcnR5IG9mIHdoaWNoIHRoZSB2YWx1ZSBzaGFsbCBiZSBzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgd2hpY2ggc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXRPYmplY3RQcm9wVmFsKG9iaiwgcGF0aCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0cyA9IHBhdGguc3BsaXQoX3N0ckRvdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0c0xlbmd0aCA9IHNwbGl0cy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHRlbmRPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kT2JqUm9vdCA9IGV4dGVuZE9iajtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0c0xlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRPYmogPSBleHRlbmRPYmpbc3BsaXRzW2ldXSA9IGkgKyAxIDwgc3BsaXRzTGVuZ3RoID8ge30gOiB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZChvYmosIGV4dGVuZE9ialJvb3QsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBSdW5zIGEgYWN0aW9uIGZvciBlYWNoIHNlbGVjdG9yIGluc2lkZSB0aGUgdXBkYXRlT25Mb2FkIG9wdGlvbi5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIFRoZSBhY3Rpb24gZm9yIGVhY2ggdXBkYXRlT25Mb2FkIHNlbGVjdG9yLCB0aGUgYXJndW1lbnRzIHRoZSBmdW5jdGlvbiB0YWtlcyBpcyB0aGUgaW5kZXggYW5kIHRoZSB2YWx1ZSAodGhlIHNlbGVjdG9yKS5cdFxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBlYWNoVXBkYXRlT25Mb2FkKGFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVPbkxvYWQgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy51cGRhdGVPbkxvYWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlT25Mb2FkID0gdHlwZSh1cGRhdGVPbkxvYWQpID09IFRZUEVTLnMgPyB1cGRhdGVPbkxvYWQuc3BsaXQoX3N0clNwYWNlKSA6IHVwZGF0ZU9uTG9hZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKHVwZGF0ZU9uTG9hZCkgJiYgIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCh1cGRhdGVPbkxvYWQsIGFjdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gVXRpbHMgQ2FjaGUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIG9yIG9iamVjdHMgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZW4ndCBlcXVhbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBmaXJzdCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY2FjaGUgVGhlIHNlY29uZCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgSWYgdHJ1ZSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgYWx3YXlzIHRydWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBib3RoIHZhbHVlcyBvciBvYmplY3RzIGFyZW4ndCBlcXVhbCBvciBmb3JjZSBpcyB0cnVlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrQ2FjaGUoY3VycmVudCwgY2FjaGUsIGZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoY3VycmVudCkgPT0gVFlQRVMubyAmJiB0eXBlKGNhY2hlKSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3AgIT09ICdjJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50W0xFWElDT04uaE9QXShwcm9wKSAmJiBjYWNoZVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrQ2FjaGUoY3VycmVudFtwcm9wXSwgY2FjaGVbcHJvcF0pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50ICE9PSBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2hvcnRjdXRzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogalF1ZXJ5IGV4dGVuZCBtZXRob2Qgc2hvcnRjdXQgd2l0aCBhIGFwcGVuZGVkIFwidHJ1ZVwiIGFzIGZpcnN0IGFyZ3VtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBleHRlbmREZWVwKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGUkFNRVdPUksuZXh0ZW5kLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQoW10uc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgYWRkQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGRDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uYWRkQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgcmVtb3ZlQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8ucmVtb3ZlQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgdGhlIGdpdmVuIGNsYXNzZXMgZGVwZW5kZW50IG9uIHRoZSBib29sZWFuIHZhbHVlLiBUcnVlIGZvciBhZGQsIGZhbHNlIGZvciByZW1vdmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFkZFJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzLCBkb0FkZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb0FkZCA/IGFkZENsYXNzKGVsLCBjbGFzc2VzKSA6IHJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGpRdWVyeSByZW1vdmUgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmUoZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLnJlbW92ZS5jYWxsKGVsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEZpbmRzIHRoZSBmaXJzdCBjaGlsZCBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHNlbGVjdG9yIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsIFRoZSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0aGUgc2VsZWN0b3Igc2hhbGwgYmUgdmFsaWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIG9mIHRoZSBzZWFyY2hlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRoZSBmaXJzdCBlbGVtZW50IHdoaWNoIGlzIGEgY2hpbGQgb2YgdGhlIGdpdmVuIGVsZW1lbnQgYW5kIG1hdGNoZXMgdGhlIGdpdmVucyBzZWxlY3Rvci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZmluZEZpcnN0KGVsLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uZmluZC5jYWxsKGVsLCBzZWxlY3RvcikuZXEoMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBBUEkgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQdXRzIHRoZSBpbnN0YW5jZSB0byBzbGVlcC4gSXQgd29udCByZXNwb25kIHRvIGFueSBjaGFuZ2VzIGluIHRoZSBET00gYW5kIHdvbid0IHVwZGF0ZS4gU2Nyb2xsYmFyIEludGVyYWN0aXZpdHkgaXMgYWxzbyBkaXNhYmxlZCBhcyB3ZWxsIGFzIHRoZSByZXNpemUgaGFuZGxlLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgcmVzZXQgYnkgY2FsbGluZyB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2Uuc2xlZXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgVHJ1ZSBpZiBldmVyeSBwcm9wZXJ0eSBzaGFsbCBiZSB1cGRhdGVkIGFuZCB0aGUgY2FjaGUgc2hhbGwgYmUgaWdub3JlZC5cclxuICAgICAgICAgICAgICAgICAqICFJTlRFUk5BTCBVU0FHRSEgOiBmb3JjZSBjYW4gYmUgYSBzdHJpbmcgXCJhdXRvXCIsIFwic3luY1wiIG9yIFwiem9vbVwiIHRvb1xyXG4gICAgICAgICAgICAgICAgICogaWYgXCJhdXRvXCIgdGhlbiBiZWZvcmUgYSByZWFsIHVwZGF0ZSB0aGUgY29udGVudCBzaXplIGFuZCBob3N0IGVsZW1lbnQgYXR0cmlidXRlcyBnZXRzIGNoZWNrZWQsIGFuZCBpZiB0aGV5IGNoYW5nZWQgb25seSB0aGVuIHRoZSB1cGRhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogaWYgXCJzeW5jXCIgdGhlbiB0aGUgYXN5bmMgdXBkYXRlIHByb2Nlc3MgKE11dGF0aW9uT2JzZXJ2ZXIgb3IgVXBkYXRlTG9vcCkgZ2V0cyBzeW5jaHJvbml6ZWQgYW5kIGEgY29ycmVzcG9uZGluZyB1cGRhdGUgdGFrZXMgcGxhY2UgaWYgb25lIHdhcyBuZWVkZWQgZHVlIHRvIHBlbmRpbmcgY2hhbmdlcy5cclxuICAgICAgICAgICAgICAgICAqIGlmIFwiem9vbVwiIHRoZW4gYSB1cGRhdGUgdGFrZXMgcGxhY2Ugd2hlcmUgaXQncyBhc3N1bWVkIHRoYXQgY29udGVudCBhbmQgaG9zdCBzaXplIGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufHVuZGVmaW5lZH0gXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcInN5bmNcIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIHVwZGF0ZSB3YXMgbmVlZGVkIGR1ZSB0byBwZW5kaW5nIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcImF1dG9cIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGV0aGVyIGEgdXBkYXRlIHdhcyBuZWVkZWQgZHVlIHRvIGF0dHJpYnV0ZSBvciBzaXplIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUgPSBmdW5jdGlvbiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnNDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShmb3JjZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRIb3N0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRDb250ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlID09PSBfc3RyQXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNDaGFuZ2VkID0gbWVhbmluZ2Z1bEF0dHJzQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemVDID0gdXBkYXRlQXV0b0NvbnRlbnRTaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGVBdXRvID0gYXR0cnNDaGFuZ2VkIHx8IGNvbnRlbnRTaXplQztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZUF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudFNpemVDaGFuZ2VkOiBjb250ZW50U2l6ZUMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jaGFuZ2VkT3B0aW9uczogX2luaXRpYWxpemVkID8gdW5kZWZpbmVkIDogX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gX3N0clN5bmMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2soX211dGF0aW9uT2JzZXJ2ZXJIb3N0LnRha2VSZWNvcmRzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dENvbnRlbnQgPSBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayhfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQudGFrZVJlY29yZHMoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gJ3pvb20nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlID0gX3NsZWVwaW5nIHx8IGZvcmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2xlZXBpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfYmFzZS51cGRhdGUoX3N0clN5bmMpIHx8IGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2ZvcmNlOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZUF1dG8gfHwgbXV0SG9zdCB8fCBtdXRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICBHZXRzIG9yIHNldHMgdGhlIGN1cnJlbnQgb3B0aW9ucy4gVGhlIHVwZGF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYXV0b21hdGljYWxseSBpZiBuZXcgb3B0aW9ucyB3ZXJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIElmIG5ldyBvcHRpb25zIGFyZSBnaXZlbiwgdGhlbiB0aGUgbmV3IG9wdGlvbnMgd2lsbCBiZSBzZXQsIGlmIG5ldyBvcHRpb25zIGFyZW4ndCBnaXZlbiAodW5kZWZpbmVkIG9yIGEgbm90IGEgcGxhaW4gb2JqZWN0KSB0aGVuIHRoZSBjdXJyZW50IG9wdGlvbnMgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBJZiBuZXcgb3B0aW9ucyBpcyBhIHByb3BlcnR5IHBhdGggc3RyaW5nLCB0aGVuIHRoaXMgdmFsdWUgd2lsbCBiZSB1c2VkIHRvIHNldCB0aGUgb3B0aW9uIHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBwYXRoIHN0cmluZyBsZWFkcy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5vcHRpb25zID0gZnVuY3Rpb24gKG5ld09wdGlvbnMsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdGlvbiA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkT3BzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBjdXJyZW50IG9wdGlvbnMgaWYgbmV3T3B0aW9ucyBhcmUgdW5kZWZpbmVkIG9yIGVtcHR5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKEZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KG5ld09wdGlvbnMpIHx8ICFGUkFNRVdPUksuaXNQbGFpbk9iamVjdChuZXdPcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShuZXdPcHRpb25zKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRPYmplY3RQcm9wVmFsKG9wdGlvbiwgbmV3T3B0aW9ucywgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHMgPSBzZXRPcHRpb25zKG9wdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE9iamVjdFByb3BWYWwoX2N1cnJlbnRPcHRpb25zLCBuZXdPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZE9wcyA9IHNldE9wdGlvbnMobmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KGNoYW5nZWRPcHMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9jaGFuZ2VkT3B0aW9uczogY2hhbmdlZE9wcyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVzdG9yZSB0aGUgRE9NLCBkaXNjb25uZWN0cyBhbGwgb2JzZXJ2ZXJzLCByZW1vdmUgYWxsIHJlc2l6ZSBvYnNlcnZlcnMgYW5kIHB1dCB0aGUgaW5zdGFuY2UgdG8gc2xlZXAuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIGF1dG8gdXBkYXRlIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5yZW1vdmUoX2Jhc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2Rpc2Nvbm5lY3QgYWxsIG11dGF0aW9uIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcmVzaXplIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBleHROYW1lIGluIF9leHRlbnNpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQoZXh0TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCAnZGVzdHJveScgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKF9kZXN0cm95RXZlbnRzW0xFWElDT04ubF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wb3AoKSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZXZlbnRzIGZyb20gaG9zdCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGhlbHBlciAvIGRldGVjdGlvbiBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoX2NvbnRlbnRHbHVlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9jb250ZW50QXJyYW5nZUVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCBnZW5lcmF0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJzRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyQ29ybmVyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU3RydWN0dXJlRE9NKHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZ2VuZXJhdGVkIGltYWdlIGxvYWQgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfdXBkYXRlT25Mb2FkRWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyhfdXBkYXRlT25Mb2FkRWxtc1tpXSkub2ZmKF91cGRhdGVPbkxvYWRFdmVudE5hbWUsIHVwZGF0ZU9uTG9hZENhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcyA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIHRoZSBpbnN0YW5jZXMgbGlzdFxyXG4gICAgICAgICAgICAgICAgICAgIElOU1RBTkNFUyhwbHVnaW5UYXJnZXRFbGVtZW50LCAwKTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRlc3Ryb3llZCcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcHJvcGVydGllcyBhbmQgbWV0aG9kc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgcHJvcGVydHkgaW4gX2Jhc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgZGVsZXRlIF9iYXNlW3Byb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAvL19iYXNlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNjcm9sbHMgdG8gYSBnaXZlbiBwb3NpdGlvbiBvciBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNvb3JkaW5hdGVzXHJcbiAgICAgICAgICAgICAgICAgKiAxLiBDYW4gYmUgXCJjb29yZGluYXRlc1wiIHdoaWNoIGxvb2tzIGxpa2U6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7IHggOiA/LCB5IDogPyB9IE9SICAgICAgICAgIE9iamVjdCB3aXRoIHggYW5kIHkgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsZWZ0IDogPywgdG9wIDogPyB9IE9SICAgICBPYmplY3Qgd2l0aCBsZWZ0IGFuZCB0b3AgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsIDogPywgdCA6ID8gfSBPUiAgICAgICAgICBPYmplY3Qgd2l0aCBsIGFuZCB0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgICAqICAgIFsgPywgPyBdIE9SICAgICAgICAgICAgICAgICAgQXJyYXkgd2hlcmUgdGhlIGZpcnN0IHR3byBlbGVtZW50IGFyZSB0aGUgY29vcmRpbmF0ZXMgKGZpcnN0IGlzIHgsIHNlY29uZCBpcyB5KVxyXG4gICAgICAgICAgICAgICAgICogICAgPyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBIHNpbmdsZSB2YWx1ZSB3aGljaCBzdGF5cyBmb3IgYm90aCBheGlzXHJcbiAgICAgICAgICAgICAgICAgKiAgICBBIHZhbHVlIGNhbiBiZSBhIG51bWJlciwgYSBzdHJpbmcgb3IgYSBjYWxjdWxhdGlvbi5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBPcGVyYXRvcnM6XHJcbiAgICAgICAgICAgICAgICAgKiAgICBbTk9ORV0gIFRoZSBjdXJyZW50IHNjcm9sbCB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqICAgICcrPScgICAgVGhlIHZhbHVlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJy09JyAgICBUaGUgdmFsdWUgd2lsbCBiZSBzdWJ0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJyo9JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICogICAgJy89JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIGRpdmlkZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFVuaXRzOlxyXG4gICAgICAgICAgICAgICAgICogICAgW05PTkVdICBUaGUgdmFsdWUgaXMgdGhlIGZpbmFsIHNjcm9sbCBhbW91bnQuICAgICAgICAgICAgICAgICAgIGZpbmFsID0gKHZhbHVlICogMSlcclxuICAgICAgICAgICAgICAgICAqICAgICdweCcgICAgU2FtZSBhcyBub25lXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnJScgICAgIFRoZSB2YWx1ZSBpcyBkZXBlbmRlbnQgb24gdGhlIGN1cnJlbnQgc2Nyb2xsIHZhbHVlLiAgICAgZmluYWwgPSAoKGN1cnJlbnRTY3JvbGxWYWx1ZSAvIDEwMCkgKiB2YWx1ZSlcclxuICAgICAgICAgICAgICAgICAqICAgICd2dycgICAgVGhlIHZhbHVlIGlzIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZpZXdwb3J0IHdpZHRoLiAgICAgICBmaW5hbCA9ICh2YWx1ZSAqIHZpZXdwb3J0V2lkdGgpXHJcbiAgICAgICAgICAgICAgICAgKiAgICAndmgnICAgIFRoZSB2YWx1ZSBpcyBtdWx0aXBsaWNhdGVkIGJ5IHRoZSB2aWV3cG9ydCBoZWlnaHQuICAgICAgZmluYWwgPSAodmFsdWUgKiB2aWV3cG9ydEhlaWdodClcclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBleGFtcGxlIGZpbmFsIHZhbHVlczpcclxuICAgICAgICAgICAgICAgICAqICAgIDIwMCwgJzIwMHB4JywgJzUwJScsICcxdncnLCAnMXZoJywgJys9MjAwJywgJy89MXZ3JywgJyo9MnB4JywgJy09NXZoJywgJys9MzMlJywgJys9IDUwJSAtIDJweCcsICctPSAxdncgLSA1MCUnXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogMi4gQ2FuIGJlIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudDpcclxuICAgICAgICAgICAgICAgICAqICAgIFRoZSBmaW5hbCBzY3JvbGwgb2Zmc2V0IGlzIHRoZSBvZmZzZXQgKHdpdGhvdXQgbWFyZ2luKSBvZiB0aGUgZ2l2ZW4gSFRNTCAvIGpRdWVyeSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIDMuIENhbiBiZSBhIG9iamVjdCB3aXRoIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudCB3aXRoIGFkZGl0aW9uYWwgc2V0dGluZ3M6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7XHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIGVsIDogW0hUTUxFbGVtZW50LCBqUXVlcnkgZWxlbWVudF0sICAgICAgICAgICAgIE1VU1QgYmUgc3BlY2lmaWVkLCBlbHNlIHRoaXMgb2JqZWN0IGlzbid0IHZhbGlkLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBzY3JvbGwgOiBbc3RyaW5nLCBhcnJheSwgb2JqZWN0XSwgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdhbHdheXMnLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBibG9jayA6IFtzdHJpbmcsIGFycmF5LCBvYmplY3RdLCAgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdiZWdpbicuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIG1hcmdpbiA6IFtudW1iZXIsIGJvb2xlYW4sIGFycmF5LCBvYmplY3RdICAgICAgIERlZmF1bHQgdmFsdWUgaXMgZmFsc2UuXHJcbiAgICAgICAgICAgICAgICAgKiAgICB9XHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgc2Nyb2xsIHNldHRpbmdzIGFyZTpcclxuICAgICAgICAgICAgICAgICAqICAgICdhbHdheXMnICAgICAgU2Nyb2xscyBhbHdheXMuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnaWZuZWVkZWQnICAgIFNjcm9sbHMgb25seSBpZiB0aGUgZWxlbWVudCBpc250IGZ1bGx5IGluIHZpZXcuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnbmV2ZXInICAgICAgIFNjcm9sbHMgbmV2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgYmxvY2sgc2V0dGluZ3MgYXJlOlxyXG4gICAgICAgICAgICAgICAgICogICAgJ2JlZ2luJyAgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gdGhlIFwiYmVnaW5cIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSB0b3AgYW5kIGxlZnQgZWRnZSBvZiB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnZW5kJyAgICAgQm90aCBheGlzIHNoYWxsIGJlIGRvY2tlZCB0byB0aGUgXCJlbmRcIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSBib3R0b20gYW5kIHJpZ2h0IGVkZ2Ugb2YgdGhlIHZpZXdwb3J0LiAoSWYgZGlyZWN0aW9uIGlzIFJUTCB0byB0aGUgYm90dG9tIGFuZCBsZWZ0IGVkZ2UuKVxyXG4gICAgICAgICAgICAgICAgICogICAgJ2NlbnRlcicgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gXCJjZW50ZXJcIi4gLSBUaGUgZWxlbWVudCB3aWxsIGJlIGNlbnRlcmVkIGluIHRoZSB2aWV3cG9ydC5cclxuICAgICAgICAgICAgICAgICAqICAgICduZWFyZXN0JyBUaGUgZWxlbWVudCB3aWxsIGJlIGRvY2tlZCB0byB0aGUgbmVhcmVzdCBlZGdlKHMpLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFBvc3NpYmxlIG1hcmdpbiBzZXR0aW5ncyBhcmU6IC0tIFRoZSBhY3R1YWwgbWFyZ2luIG9mIHRoZSBlbGVtZW50IHdvbnQgYmUgYWZmZWN0LCB0aGlzIG9wdGlvbiBhZmZlY3RzIG9ubHkgdGhlIGZpbmFsIHNjcm9sbCBvZmZzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICBbQk9PTEVBTl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRydWUgdGhlIGNzcyBtYXJnaW4gb2YgdGhlIGVsZW1lbnQgd2lsbCBiZSB1c2VkLCBpZiBmYWxzZSBubyBtYXJnaW4gd2lsbCBiZSB1c2VkLlxyXG4gICAgICAgICAgICAgICAgICogICAgW05VTUJFUl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgbWFyZ2luIHdpbGwgYmUgdXNlZCBmb3IgYWxsIGVkZ2VzLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHNjcm9sbCBhbmltYXRpb24sIE9SIGEgalF1ZXJ5IGFuaW1hdGlvbiBjb25maWd1cmF0aW9uIG9iamVjdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlYXNpbmcgVGhlIGFuaW1hdGlvbiBlYXNpbmcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29tcGxldGUgVGhlIGFuaW1hdGlvbiBjb21wbGV0ZSBjYWxsYmFjay5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7XHJcbiAgICAgICAgICAgICAgICAgKiAgIHBvc2l0aW9uOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICByYXRpbzoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgbWF4OiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICBoYW5kbGVPZmZzZXQ6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGhhbmRsZUxlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaGFuZGxlTGVuZ3RoUmF0aW86IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sIHRcclxuICAgICAgICAgICAgICAgICAqICAgcmFja0xlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaXNSVEw6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGlzUlRMTm9ybWFsaXplZDogYm9vbGVhblxyXG4gICAgICAgICAgICAgICAgICogIH19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbCA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgZHVyYXRpb24sIGVhc2luZywgY29tcGxldGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBjb29yZGluYXRlcyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmZvWCA9IF9zY3JvbGxIb3Jpem9udGFsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZm9ZID0gX3Njcm9sbFZlcnRpY2FsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZUludmVydCA9IF9ub3JtYWxpemVSVExDYWNoZSAmJiBfaXNSVEwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVOZWdhdGUgPSBfbm9ybWFsaXplUlRMQ2FjaGUgJiYgX2lzUlRMICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWCA9IGluZm9YLl9jdXJyZW50U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWFJhdGlvID0gaW5mb1guX2N1cnJlbnRTY3JvbGxSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1heFNjcm9sbFggPSBpbmZvWC5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYUmF0aW8gPSBub3JtYWxpemVJbnZlcnQgPyAxIC0gc2Nyb2xsWFJhdGlvIDogc2Nyb2xsWFJhdGlvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYID0gbm9ybWFsaXplSW52ZXJ0ID8gbWF4U2Nyb2xsWCAtIHNjcm9sbFggOiBzY3JvbGxYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYICo9IG5vcm1hbGl6ZU5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4U2Nyb2xsWCAqPSBub3JtYWxpemVOZWdhdGUgPyAtMSA6IDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9jdXJyZW50U2Nyb2xsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF0aW86IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYUmF0aW8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2N1cnJlbnRTY3JvbGxSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1heFNjcm9sbFgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX21heFNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU9mZnNldDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVPZmZzZXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZUxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aFJhdGlvOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX2hhbmRsZUxlbmd0aFJhdGlvLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9oYW5kbGVMZW5ndGhSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrTGVuZ3RoOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX3RyYWNrTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl90cmFja0xlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBwZWRIYW5kbGVPZmZzZXQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpbmZvWC5fc25hcHBlZEhhbmRsZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5fc25hcHBlZEhhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUlRMOiBfaXNSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTE5vcm1hbGl6ZWQ6IF9ub3JtYWxpemVSVExDYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJTeW5jKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVJUTCA9IF9ub3JtYWxpemVSVExDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNYQXhpc1Byb3BzID0gW19zdHJYLCBfc3RyTGVmdCwgJ2wnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNZQXhpc1Byb3BzID0gW19zdHJZLCBfc3RyVG9wLCAndCddO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlc09wZXJhdG9ycyA9IFsnKz0nLCAnLT0nLCAnKj0nLCAnLz0nXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb25Jc09iamVjdCA9IHR5cGUoZHVyYXRpb24pID09IFRZUEVTLm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBsZXRlQ2FsbGJhY2sgPSBkdXJhdGlvbklzT2JqZWN0ID8gZHVyYXRpb24uY29tcGxldGUgOiBjb21wbGV0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxTY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb1Njcm9sbExlZnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvU2Nyb2xsVG9wO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhbmltYXRpb25PcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJFbmQgPSAnZW5kJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQmVnaW4gPSAnYmVnaW4nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDZW50ZXIgPSAnY2VudGVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTmVhcmVzdCA9ICduZWFyZXN0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQWx3YXlzID0gJ2Fsd2F5cyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck5ldmVyID0gJ25ldmVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySWZOZWVkZWQgPSAnaWZuZWVkZWQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJMZW5ndGggPSBMRVhJQ09OLmw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQXhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2V0dGluZ3NTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQmxvY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzTWFyZ2luO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMgPSBbX3N0clgsIF9zdHJZLCAneHknLCAneXgnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzQmxvY2tWYWx1ZXMgPSBbc3RyQmVnaW4sIHN0ckVuZCwgc3RyQ2VudGVyLCBzdHJOZWFyZXN0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzID0gW3N0ckFsd2F5cywgc3RyTmV2ZXIsIHN0cklmTmVlZGVkXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPSBjb29yZGluYXRlc1tMRVhJQ09OLmhPUF0oJ2VsJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudCA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuZWwgOiBjb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zc2libGVFbGVtZW50SXNKUXVlcnkgPSBwb3NzaWJsZUVsZW1lbnQgaW5zdGFuY2VvZiBGUkFNRVdPUksgfHwgSlFVRVJZID8gcG9zc2libGVFbGVtZW50IGluc3RhbmNlb2YgSlFVRVJZIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudElzSFRNTEVsZW1lbnQgPSBwb3NzaWJsZUVsZW1lbnRJc0pRdWVyeSA/IGZhbHNlIDogaXNIVE1MRWxlbWVudChwb3NzaWJsZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVTY3JvbGxiYXJJbmZvcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3h5Q29tcGxldGVDYWxsYmFjayA9IHR5cGUoY29tcGxldGVDYWxsYmFjaykgIT0gVFlQRVMuZiA/IHVuZGVmaW5lZCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlU2Nyb2xsYmFySW5mb3MoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGVDYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGN1cnJWYWx1ZSwgYWxsb3dlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZFZhbHVlc1tzdHJMZW5ndGhdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyVmFsdWUgPT09IGFsbG93ZWRWYWx1ZXNbaV0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRSYXdTY3JvbGwoaXNYLCBjb29yZGluYXRlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZVByb3BzID0gaXNYID8gY29vcmRpbmF0ZXNYQXhpc1Byb3BzIDogY29vcmRpbmF0ZXNZQXhpc1Byb3BzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLnMgfHwgdHlwZShjb29yZGluYXRlcykgPT0gVFlQRVMubiA/IFtjb29yZGluYXRlcywgY29vcmRpbmF0ZXNdIDogY29vcmRpbmF0ZXM7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY29vcmRpbmF0ZXMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzWCA/IGNvb3JkaW5hdGVzWzBdIDogY29vcmRpbmF0ZXNbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZGVjaWRlcyBSVEwgbm9ybWFsaXphdGlvbiBcImhhY2tcIiB3aXRoIC5uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vcm1hbGl6ZVJUTCA9IHR5cGUoY29vcmRpbmF0ZXMubikgPT0gVFlQRVMuYiA/IGNvb3JkaW5hdGVzLm4gOiBub3JtYWxpemVSVEw7IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3JkaW5hdGVQcm9wc1tzdHJMZW5ndGhdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVQcm9wc1tpXSBpbiBjb29yZGluYXRlcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzW2Nvb3JkaW5hdGVQcm9wc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0RmluYWxTY3JvbGwoaXNYLCByYXdTY3JvbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShyYXdTY3JvbGwpID09IFRZUEVTLnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEluZm8gPSBpc1ggPyBfc2Nyb2xsSG9yaXpvbnRhbEluZm8gOiBfc2Nyb2xsVmVydGljYWxJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclNjcm9sbCA9IHNjcm9sbEluZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXhTY3JvbGwgPSBzY3JvbGxJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdWx0ID0gJyAqICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc1ggPSBfaXNSVEwgJiYgaXNYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplU2hvcnRjdXRzID0gaXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgIW5vcm1hbGl6ZVJUTDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0clJlcGxhY2UgPSAncmVwbGFjZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldmFsRnVuYyA9IGV2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgb3BlcmF0b3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdTY3JvbGxbc3RyTGVuZ3RoXSA+IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZU9wZXJhdG9yID0gcmF3U2Nyb2xsLnN1YnN0cigwLCAyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5BcnJheShwb3NzaWJsZU9wZXJhdG9yLCBjb29yZGluYXRlc09wZXJhdG9ycykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IgPSBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsY3VsYXRlIHVuaXRzIGFuZCBzaG9ydGN1dHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IG9wZXJhdG9yID8gcmF3U2Nyb2xsLnN1YnN0cigyKSA6IHJhd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IHJhd1Njcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC9taW4vZywgMCkgLy8nbWluJyA9IDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oLzwvZywgMCkgICAvLyc8JyAgID0gMCVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvbWF4L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAvLydtYXgnID0gMTAwJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC8+L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAgIC8vJz4nICAgPSAxMDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3B4L2csIF9zdHJFbXB0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvJS9nLCBtdWx0ICsgKG1heFNjcm9sbCAqIChpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC0xIDogMSkgLyAxMDAuMCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3Z3L2csIG11bHQgKyBfdmlld3BvcnRTaXplLncpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3ZoL2csIG11bHQgKyBfdmlld3BvcnRTaXplLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcGFyc2VUb1plcm9Pck51bWJlcihpc05hTihyYXdTY3JvbGwpID8gcGFyc2VUb1plcm9Pck51bWJlcihldmFsRnVuYyhyYXdTY3JvbGwpLCB0cnVlKS50b0ZpeGVkKCkgOiByYXdTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcmF3U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW1vdW50ICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGFtb3VudCkgJiYgdHlwZShhbW91bnQpID09IFRZUEVTLm4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVJc1JUTGlzWCA9IG5vcm1hbGl6ZVJUTCAmJiBpc1JUTGlzWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvckN1cnJTY3JvbGwgPSBjdXJyU2Nyb2xsICogKG5vcm1hbGl6ZUlzUlRMaXNYICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLTEgOiAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnZlcnQgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZWdhdGUgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yQ3VyclNjcm9sbCA9IGludmVydCA/IChtYXhTY3JvbGwgLSBvcGVyYXRvckN1cnJTY3JvbGwpIDogb3BlcmF0b3JDdXJyU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJys9JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCArIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnLT0nOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gb3BlcmF0b3JDdXJyU2Nyb2xsIC0gYW1vdW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcqPSc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBvcGVyYXRvckN1cnJTY3JvbGwgKiBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy89JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCAvIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gaW52ZXJ0ID8gbWF4U2Nyb2xsIC0gZmluYWxWYWx1ZSA6IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlICo9IG5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IE1BVEgubWluKDAsIE1BVEgubWF4KG1heFNjcm9sbCwgZmluYWxWYWx1ZSkpIDogTUFUSC5tYXgoMCwgTUFUSC5taW4obWF4U2Nyb2xsLCBmaW5hbFZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVmFsdWUgPT09IGN1cnJTY3JvbGwgPyB1bmRlZmluZWQgOiBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQZXJBeGlzVmFsdWUodmFsdWUsIHZhbHVlSW50ZXJuYWxUeXBlLCBkZWZhdWx0VmFsdWUsIGFsbG93ZWRWYWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdERlZmF1bHQgPSBbZGVmYXVsdFZhbHVlLCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVUeXBlID0gdHlwZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFyckxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJySXRlbTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmFsdWUgY2FuIGJlIFsgc3RyaW5nLCBvciBhcnJheSBvZiB0d28gc3RyaW5ncyBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPT0gdmFsdWVJbnRlcm5hbFR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWVUeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQXJyTGVuZ3RoID0gdmFsdWVbc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA+IDIgfHwgdmFsdWVBcnJMZW5ndGggPCAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcmVzdWx0RGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA9PT0gMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMV0gPSBkZWZhdWx0VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlQXJyTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJJdGVtID0gdmFsdWVbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlQXJySXRlbSkgIT0gdmFsdWVJbnRlcm5hbFR5cGUgfHwgIWNoZWNrU2V0dGluZ3NTdHJpbmdWYWx1ZSh2YWx1ZUFyckl0ZW0sIGFsbG93ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZVR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlW19zdHJYXSB8fCBkZWZhdWx0VmFsdWUsIHZhbHVlW19zdHJZXSB8fCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHg6IHZhbHVlWzBdLCB5OiB2YWx1ZVsxXSB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZU1hcmdpbihtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWVUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVEaXJlY3Rpb25zID0gW19zdHJUb3AsIF9zdHJSaWdodCwgX3N0ckJvdHRvbSwgX3N0ckxlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbWFyZ2luVG9wUmlnaHRCb3R0b21MZWZ0QXJyYXlbc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gdmFsdWVEaXJlY3Rpb25zW3N0ckxlbmd0aF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmFsdWUgPSBtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWYWx1ZVR5cGUgPSB0eXBlKGN1cnJWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclZhbHVlVHlwZSA9PSBUWVBFUy5iKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZSA/IHBhcnNlVG9aZXJvT3JOdW1iZXIoZmluYWxFbGVtZW50LmNzcyhfc3RyTWFyZ2luTWludXMgKyB2YWx1ZURpcmVjdGlvbnNbaV0pKSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZVR5cGUgPT0gVFlQRVMubiA/IGN1cnJWYWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocG9zc2libGVFbGVtZW50SXNKUXVlcnkgfHwgcG9zc2libGVFbGVtZW50SXNIVE1MRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBzZXR0aW5nc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luID0gY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPyBjb29yZGluYXRlcy5tYXJnaW4gOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXhpcyA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYXhpcyA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLnNjcm9sbCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYmxvY2sgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luRGVmYXVsdCA9IFswLCAwLCAwLCAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblR5cGUgPSB0eXBlKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW5MZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsRWxlbWVudCA9IHBvc3NpYmxlRWxlbWVudElzSlF1ZXJ5ID8gcG9zc2libGVFbGVtZW50IDogRlJBTUVXT1JLKHBvc3NpYmxlRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxFbGVtZW50W3N0ckxlbmd0aF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21hcmdpbiBjYW4gYmUgWyBib29sZWFuLCBudW1iZXIsIGFycmF5IG9mIDIsIGFycmF5IG9mIDQsIG9iamVjdCBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5uIHx8IG1hcmdpblR5cGUgPT0gVFlQRVMuYilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luLCBtYXJnaW4sIG1hcmdpbiwgbWFyZ2luXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXJnaW5UeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5MZW5ndGggPSBtYXJnaW5bc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luTGVuZ3RoID09PSAyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luWzBdLCBtYXJnaW5bMV0sIG1hcmdpblswXSwgbWFyZ2luWzFdXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luTGVuZ3RoID49IDQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKFttYXJnaW5bX3N0clRvcF0sIG1hcmdpbltfc3RyUmlnaHRdLCBtYXJnaW5bX3N0ckJvdHRvbV0sIG1hcmdpbltfc3RyTGVmdF1dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmxvY2sgPSB0eXBlKGJsb2NrKSA9PT0gVFlQRVMuYiA/IGJsb2NrID8gWyBzdHJOZWFyZXN0LCBzdHJCZWdpbiBdIDogWyBzdHJOZWFyZXN0LCBzdHJFbmQgXSA6IGJsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NBeGlzID0gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGF4aXMsIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMpID8gYXhpcyA6ICd4eSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc1Njcm9sbCA9IGdldFBlckF4aXNWYWx1ZShzY3JvbGwsIFRZUEVTLnMsIHN0ckFsd2F5cywgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzQmxvY2sgPSBnZXRQZXJBeGlzVmFsdWUoYmxvY2ssIFRZUEVTLnMsIHN0ckJlZ2luLCBlbGVtZW50T2JqU2V0dGluZ3NCbG9ja1ZhbHVlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc01hcmdpbiA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTY3JvbGwgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbDogX3Njcm9sbEhvcml6b250YWxJbmZvLl9jdXJyZW50U2Nyb2xsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQ6IF9zY3JvbGxWZXJ0aWNhbEluZm8uX2N1cnJlbnRTY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgcGFkZGluZyBlbGVtZW50IGluc3RlYWQgb2Ygdmlld3BvcnQgZWxlbWVudCBiZWNhdXNlIHBhZGRpbmcgZWxlbWVudCBoYXMgbmV2ZXIgcGFkZGluZywgbWFyZ2luIG9yIHBvc2l0aW9uIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRPZmZzZXQgPSBfcGFkZGluZ0VsZW1lbnQub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9nZXQgY29vcmRpbmF0ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50T2Zmc2V0ID0gZmluYWxFbGVtZW50Lm9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvTm90U2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHNldHRpbmdzU2Nyb2xsLnggPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJYXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE9mZnNldFtfc3RyVG9wXSAtPSBzZXR0aW5nc01hcmdpblswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC09IHNldHRpbmdzTWFyZ2luWzNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBNQVRILnJvdW5kKGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC0gdmlld3BvcnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogTUFUSC5yb3VuZChlbGVtZW50T2Zmc2V0W19zdHJUb3BdIC0gdmlld3BvcnRPZmZzZXRbX3N0clRvcF0gKyB2aWV3cG9ydFNjcm9sbC50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9ydGxTY3JvbGxCZWhhdmlvci5uICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IuaSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5uICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggKj0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgKF9zY3JvbGxIb3Jpem9udGFsSW5mby5fbWF4U2Nyb2xsIC0gdmlld3BvcnRTY3JvbGwubCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyaW5nIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3NCbG9jay54ICE9IHN0ckJlZ2luIHx8IHNldHRpbmdzQmxvY2sueSAhPSBzdHJCZWdpbiB8fCBzZXR0aW5nc1Njcm9sbC54ID09IHN0cklmTmVlZGVkIHx8IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RySWZOZWVkZWQgfHwgX2lzUlRMKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lYXN1cmluZ0VsbSA9IGZpbmFsRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmF3RWxlbWVudFNpemUgPSBfc3VwcG9ydFRyYW5zZm9ybSA/IG1lYXN1cmluZ0VsbVtMRVhJQ09OLmJDUl0oKSA6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG1lYXN1cmluZ0VsbVtMRVhJQ09OLm9XXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBtZWFzdXJpbmdFbG1bTEVYSUNPTi5vSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50U2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcmF3RWxlbWVudFNpemVbX3N0cldpZHRoXSArIHNldHRpbmdzTWFyZ2luWzNdICsgc2V0dGluZ3NNYXJnaW5bMV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IHJhd0VsZW1lbnRTaXplW19zdHJIZWlnaHRdICsgc2V0dGluZ3NNYXJnaW5bMF0gKyBzZXR0aW5nc01hcmdpblsyXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmFsaXplQmxvY2sgPSBmdW5jdGlvbiAoaXNYKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc1gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2ggPSB2YXJzLl93X2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsdCA9IHZhcnMuX2xlZnRfdG9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSB2YXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzRW5kID0gc2V0dGluZ3NCbG9ja1t4eV0gPT0gKGlzWCA/IF9pc1JUTCA/IHN0ckJlZ2luIDogc3RyRW5kIDogc3RyRW5kKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJsb2NrSXNDZW50ZXIgPSBzZXR0aW5nc0Jsb2NrW3h5XSA9PSBzdHJDZW50ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzTmVhcmVzdCA9IHNldHRpbmdzQmxvY2tbeHldID09IHN0ck5lYXJlc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxOZXZlciA9IHNldHRpbmdzU2Nyb2xsW3h5XSA9PSBzdHJOZXZlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbElmTmVlZGVkID0gc2V0dGluZ3NTY3JvbGxbeHldID09IHN0cklmTmVlZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdnBTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2cE9mZnNldCA9IHZpZXdwb3J0T2Zmc2V0W2x0XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsU2l6ZSA9IGVsZW1lbnRTaXplW3doXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsT2Zmc2V0ID0gZWxlbWVudE9mZnNldFtsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXZpZGUgPSBibG9ja0lzQ2VudGVyID8gMiA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50Q2VudGVyT2Zmc2V0ID0gZWxPZmZzZXQgKyAoZWxTaXplIC8gMik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydENlbnRlck9mZnNldCA9IHZwT2Zmc2V0ICsgKHZwU2l6ZSAvIDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNJblZpZXcgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxTaXplIDw9IHZwU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZWxPZmZzZXQgPj0gdnBPZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGVsT2Zmc2V0ICsgZWxTaXplIDw9IHZwT2Zmc2V0ICsgdnBTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbE5ldmVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWRvTm90U2Nyb2xsW3h5XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrSXNOZWFyZXN0IHx8IHNjcm9sbElmTmVlZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gc2Nyb2xsSWZOZWVkZWQgPyBpc0luVmlldyA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrSXNFbmQgPSBlbFNpemUgPCB2cFNpemUgPyBlbGVtZW50Q2VudGVyT2Zmc2V0ID4gdmlld3BvcnRDZW50ZXJPZmZzZXQgOiBlbGVtZW50Q2VudGVyT2Zmc2V0IDwgdmlld3BvcnRDZW50ZXJPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXNbeHldIC09IGJsb2NrSXNFbmQgfHwgYmxvY2tJc0NlbnRlciA/ICgodnBTaXplIC8gZGl2aWRlKSAtIChlbFNpemUgLyBkaXZpZGUpKSAqIChpc1ggJiYgX2lzUlRMICYmIG5vcm1hbGl6ZVJUTCA/IC0xIDogMSkgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZUJsb2NrKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsaXplQmxvY2soZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbExlZnRdID0gZ2V0RmluYWxTY3JvbGwodHJ1ZSwgZ2V0UmF3U2Nyb2xsKHRydWUsIGNvb3JkaW5hdGVzKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gPSBnZXRGaW5hbFNjcm9sbChmYWxzZSwgZ2V0UmF3U2Nyb2xsKGZhbHNlLCBjb29yZGluYXRlcykpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsTGVmdCA9IGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsVG9wID0gZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gIT09IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChkb1Njcm9sbExlZnQgfHwgZG9TY3JvbGxUb3ApICYmIChkdXJhdGlvbiA+IDAgfHwgZHVyYXRpb25Jc09iamVjdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uSXNPYmplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uLmNvbXBsZXRlID0gcHJveHlDb21wbGV0ZUNhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBkdXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25PcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTogcHJveHlDb21wbGV0ZUNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKGVhc2luZykgfHwgRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoZWFzaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbExlZnRdID0gZWFzaW5nWzBdIHx8IGVhc2luZy54O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbFRvcF0gPSBlYXNpbmdbMV0gfHwgZWFzaW5nLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uT3B0aW9ucy5zcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbk9wdGlvbnMuZWFzaW5nID0gZWFzaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBhbmltYXRpb25PcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVTY3JvbGxiYXJJbmZvcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyBhbGwgc2Nyb2xsIGFuaW1hdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGN1cnJlbnQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgKGZvciBjaGFpbmluZykuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbFN0b3AgPSBmdW5jdGlvbiAocGFyYW0xLCBwYXJhbTIsIHBhcmFtMykge1xyXG4gICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuc3RvcChwYXJhbTEsIHBhcmFtMiwgcGFyYW0zKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBhbGwgcmVsZXZhbnQgZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3RhcmdldDogKiwgaG9zdDogKiwgcGFkZGluZzogKiwgdmlld3BvcnQ6ICosIGNvbnRlbnQ6ICosIHNjcm9sbGJhckhvcml6b250YWw6IHtzY3JvbGxiYXI6ICosIHRyYWNrOiAqLCBoYW5kbGU6ICp9LCBzY3JvbGxiYXJWZXJ0aWNhbDoge3Njcm9sbGJhcjogKiwgdHJhY2s6ICosIGhhbmRsZTogKn0sIHNjcm9sbGJhckNvcm5lcjogKn0gfCAqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5nZXRFbGVtZW50cyA9IGZ1bmN0aW9uIChlbGVtZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldDogX3RhcmdldEVsZW1lbnROYXRpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3Q6IF9ob3N0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogX3BhZGRpbmdFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydDogX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJIb3Jpem9udGFsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrOiBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZTogX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZlcnRpY2FsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnRbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjazogX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50WzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlOiBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckNvcm5lcjogX3Njcm9sbGJhckNvcm5lckVsZW1lbnRbMF1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlKGVsZW1lbnROYW1lKSA9PSBUWVBFUy5zID8gZ2V0T2JqZWN0UHJvcFZhbChvYmosIGVsZW1lbnROYW1lKSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGRlc2NyaWJlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHN0YXRlUHJvcGVydHkgQSBzcGVjaWZpYyBwcm9wZXJ0eSBmcm9tIHRoZSBzdGF0ZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3dpZHRoQXV0bywgaGVpZ2h0QXV0bywgb3ZlcmZsb3dBbW91bnQsIGhpZGVPdmVyZmxvdywgaGFzT3ZlcmZsb3csIGNvbnRlbnRTY3JvbGxTaXplLCB2aWV3cG9ydFNpemUsIGhvc3RTaXplLCBhdXRvVXBkYXRlfSB8ICp9XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmdldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlUHJvcGVydHkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBwcmVwYXJlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc1BsYWluT2JqZWN0KG9iaikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kZWQgPSBleHRlbmREZWVwKHt9LCBvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlUHJvcGVydHlOYW1lID0gZnVuY3Rpb24gKGZyb20sIHRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5kZWRbTEVYSUNPTi5oT1BdKGZyb20pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRbdG9dID0gZXh0ZW5kZWRbZnJvbV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV4dGVuZGVkW2Zyb21dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VQcm9wZXJ0eU5hbWUoJ3cnLCBfc3RyV2lkdGgpOyAvL2NoYW5nZSB3IHRvIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZVByb3BlcnR5TmFtZSgnaCcsIF9zdHJIZWlnaHQpOyAvL2NoYW5nZSBoIHRvIGhlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZXh0ZW5kZWQuYzsgLy9kZWxldGUgYyAodGhlICdjaGFuZ2VkJyBwcm9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZW5kZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXN0cm95ZWQ6ICEhcHJlcGFyZShfZGVzdHJveWVkKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2xlZXBpbmc6ICEhcHJlcGFyZShfc2xlZXBpbmcpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlOiBwcmVwYXJlKCFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aEF1dG86IHByZXBhcmUoX3dpZHRoQXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0QXV0bzogcHJlcGFyZShfaGVpZ2h0QXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogcHJlcGFyZShfY3NzUGFkZGluZ0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQ6IHByZXBhcmUoX292ZXJmbG93QW1vdW50Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3c6IHByZXBhcmUoX2hpZGVPdmVyZmxvd0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3c6IHByZXBhcmUoX2hhc092ZXJmbG93Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50U2Nyb2xsU2l6ZTogcHJlcGFyZShfY29udGVudFNjcm9sbFNpemVDYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0U2l6ZTogcHJlcGFyZShfdmlld3BvcnRTaXplKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemU6IHByZXBhcmUoX2hvc3RTaXplQ2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudE1peGVkOiBwcmVwYXJlKF9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUoc3RhdGVQcm9wZXJ0eSkgPT0gVFlQRVMucyA/IGdldE9iamVjdFByb3BWYWwob2JqLCBzdGF0ZVByb3BlcnR5KSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIGFsbCBvciBzcGVjaWZpYyBleHRlbnNpb24gaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbmFtZSBvciB1bmRlZmluZWQgaWYgdGhlIGluc3RhbmNlIGNvdWxkbid0IGJlIGZvdW5kLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5leHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByaXZhdGVNZXRob2RzID0gX2V4dGVuc2lvbnNQcml2YXRlTWV0aG9kcy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHROYW1lKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGV4dGVuZERlZXAoe30sIF9leHRlbnNpb25zW2V4dE5hbWVdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJpdmF0ZU1ldGhvZHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3VsdFtwcml2YXRlTWV0aG9kc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gX2V4dGVuc2lvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBleHRlbmREZWVwKHt9LCBfYmFzZS5leHQoaSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEFkZHMgYSBleHRlbnNpb24gdG8gdGhpcyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBleHROYW1lIFRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgYWRkZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uT3B0aW9ucyBUaGUgZXh0ZW5zaW9uIG9wdGlvbnMgd2hpY2ggc2hhbGwgYmUgdXNlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBhZGRlZCBleHRlbnNpb24gb3IgdW5kZWZpbmVkIGlmIHRoZSBleHRlbnNpb24gY291bGRuJ3QgYmUgYWRkZWQgcHJvcGVybHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmFkZEV4dCA9IGZ1bmN0aW9uIChleHROYW1lLCBleHRlbnNpb25PcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ2lzdGVyZWRFeHRlbnNpb25PYmogPSBfcGx1Z2luLmV4dGVuc2lvbihleHROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQWRkZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQ29udHJhY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRyYWN0UmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250cmFjdEZ1bGZpbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRFeHRlbnNpb25PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5leHRlbnNpb25GYWN0b3J5LmNhbGwoX2Jhc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kRGVlcCh7fSwgcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5kZWZhdWx0T3B0aW9ucyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udHJhY3QgPSBpbnN0YW5jZS5jb250cmFjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUNvbnRyYWN0KSA9PSBUWVBFUy5mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYWN0UmVzdWx0ID0gaW5zdGFuY2VDb250cmFjdCh3aW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdEZ1bGZpbGxlZCA9IHR5cGUoY29udHJhY3RSZXN1bHQpID09IFRZUEVTLmIgPyBjb250cmFjdFJlc3VsdCA6IGNvbnRyYWN0RnVsZmlsbGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udHJhY3RGdWxmaWxsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2V4dGVuc2lvbnNbZXh0TmFtZV0gPSBpbnN0YW5jZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZCA9IGluc3RhbmNlLmFkZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUFkZGVkKSA9PSBUWVBFUy5mKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZChleHRlbnNpb25PcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQSBleHRlbnNpb24gd2l0aCB0aGUgbmFtZSBcXFwiXCIgKyBleHROYW1lICsgXCJcXFwiIGlzbid0IHJlZ2lzdGVyZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZXMgYSBleHRlbnNpb24gZnJvbSB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB3aGljaCBzaGFsbCBiZSByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV4dGVuc2lvbiB3YXMgcmVtb3ZlZCwgZmFsc2Ugb3RoZXJ3aXNlIGUuZy4gaWYgdGhlIGV4dGVuc2lvbiB3YXNuJ3QgYWRkZWQgYmVmb3JlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IF9leHRlbnNpb25zW2V4dE5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZXh0ZW5zaW9uc1tleHROYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCA9IGluc3RhbmNlLnJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGluc3RhbmNlUmVtb3ZlZCkgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgcGx1Z2luIHNoYWxsIGJlIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgaW5pdGlhbCBvcHRpb25zIG9mIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9uKHMpIHdoaWNoIHNoYWxsIGJlIGFkZGVkIHJpZ2h0IGFmdGVyIHRoZSBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwbHVnaW4gd2FzIHN1Y2Nlc3NmdWxseSBpbml0aWFsaXplZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb25zdHJ1Y3QodGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0T3B0aW9ucyA9IGdsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcgPSBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkKTtcclxuICAgICAgICAgICAgICAgICAgICBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSA9IGV4dGVuZERlZXAoe30sIGdsb2JhbHMub3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3J0bFNjcm9sbEJlaGF2aW9yID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5ydGxTY3JvbGxCZWhhdmlvcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcGFyc2UgJiBzZXQgb3B0aW9ucyBidXQgZG9uJ3QgdXBkYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0T3B0aW9ucyhleHRlbmREZWVwKHt9LCBfZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0NhbGMgPSBnbG9iYWxzLmNzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICAgICAgX21zaWVWZXJzaW9uID0gZ2xvYmFscy5tc2llO1xyXG4gICAgICAgICAgICAgICAgICAgIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQgPSBnbG9iYWxzLmF1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydFRyYW5zaXRpb24gPSBnbG9iYWxzLnN1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0VHJhbnNmb3JtID0gZ2xvYmFscy5zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyA9IGdsb2JhbHMuc3VwcG9ydFBhc3NpdmVFdmVudHM7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N1cHBvcnRSZXNpemVPYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc3RyaWN0ZWRNZWFzdXJpbmcgPSBnbG9iYWxzLnJlc3RyaWN0ZWRNZWFzdXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50Lm93bmVyRG9jdW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9kb2N1bWVudEVsZW1lbnROYXRpdmUgPSBfZG9jdW1lbnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50ID0gRlJBTUVXT1JLKF9kb2N1bWVudEVsZW1lbnROYXRpdmUuZGVmYXVsdFZpZXcgfHwgX2RvY3VtZW50RWxlbWVudE5hdGl2ZS5wYXJlbnRXaW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50TmF0aXZlID0gX3dpbmRvd0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgX2h0bWxFbGVtZW50ID0gZmluZEZpcnN0KF9kb2N1bWVudEVsZW1lbnQsICdodG1sJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlFbGVtZW50ID0gZmluZEZpcnN0KF9odG1sRWxlbWVudCwgJ2JvZHknKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudE5hdGl2ZSA9IF90YXJnZXRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pc1RleHRhcmVhID0gX3RhcmdldEVsZW1lbnQuaXMoJ3RleHRhcmVhJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9keSA9IF90YXJnZXRFbGVtZW50LmlzKCdib2R5Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50TWl4ZWQgPSBfZG9jdW1lbnRFbGVtZW50TmF0aXZlICE9PSBkb2N1bWVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyogT24gYSBkaXYgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy1ob3N0XCJcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyBhIGEgY2hpbGQgd2l0aCB0aGUgY2xhc3MgXCJvcy1wYWRkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy1ob3N0XCIgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy12aWV3cG9ydFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3MtY29udGVudFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItdHJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci1oYW5kbGVcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItdmVydGljYWxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItY29ybmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgICAgICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgICAgICAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIE9uIGEgVGV4dGFyZWEgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy10ZXh0YXJlYVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIC0gdGhlIHRhcmdldEVsZW1lbnQgaXMgaW5zaWRlIGEgZWxlbWVudCB3aXRoIHRoZSBjbGFzcyBcIm9zLWNvbnRlbnRcIiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy10ZXh0YXJlYVwiICh0ZXh0YXJlYSkgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdC10ZXh0YXJlYVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZyBvcy10ZXh0LWluaGVyaXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtdmlld3BvcnQgb3MtdGV4dC1pbmhlcml0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1jb250ZW50IG9zLXRleHQtaW5oZXJpdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXRleHRhcmVhLWNvdmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJvcy10ZXh0YXJlYSBvcy10ZXh0LWluaGVyaXRcIj48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItaG9yaXpvbnRhbCBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci10cmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWhhbmRsZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWNvcm5lclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfZG9tRXhpc3RzID0gX2lzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBfdGFyZ2V0RWxlbWVudC5oYXNDbGFzcyhfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5wYXJlbnQoKS5oYXNDbGFzcyhfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogX3RhcmdldEVsZW1lbnQuaGFzQ2xhc3MoX2NsYXNzTmFtZUhvc3RFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVBhZGRpbmdFbGVtZW50KVtMRVhJQ09OLmxdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdEJvZHlTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHlNb3VzZVRvdWNoRG93bkxpc3RlbmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwbHVnaW4gaGFzbid0IHRvIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiAhX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLmluaXRpYWxpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Jbml0aWFsaXphdGlvbldpdGhkcmF3bicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zbGVlcGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC5sID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKCksIF9odG1sRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oKSwgX3dpbmRvd0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC50ID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oKSwgX2h0bWxFbGVtZW50W19zdHJTY3JvbGxUb3BdKCksIF93aW5kb3dFbGVtZW50W19zdHJTY3JvbGxUb3BdKCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi50aSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBib2R5TW91c2VUb3VjaERvd25MaXN0ZW5lciwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYnVpbGQgT3ZlcmxheVNjcm9sbGJhcnMgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBPdmVybGF5U2Nyb2xsYmFycyBldmVudHNcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFN0cnVjdHVyZUV2ZW50cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckV2ZW50cygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBtdXRhdGlvbiBvYnNlcnZlcnNcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2J1aWxkIHJlc2l6ZSBvYnNlcnZlciBmb3IgdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQsIGhvc3RPblJlc2l6ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IHRoZSBib2R5IHNjcm9sbCB0byBoYW5kbGUgaXQgcmlnaHQgaW4gdGhlIHVwZGF0ZSBtZXRob2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oaW5pdEJvZHlTY3JvbGwubClbX3N0clNjcm9sbFRvcF0oaW5pdEJvZHlTY3JvbGwudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB0aGUgZm9jdXMgb24gdGhlIHZpZXdwb3J0IGVsZW1lbnQgc28geW91IGRvbnQgaGF2ZSB0byBjbGljayBvbiB0aGUgcGFnZSB0byB1c2Uga2V5Ym9hcmQga2V5cyAodXAgLyBkb3duIC8gc3BhY2UpIGZvciBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gdGFyZ2V0RWxlbWVudCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlLmZvY3VzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBhIHRhYmluZGV4IHRvIG1ha2UgdGhlIHZpZXdwb3J0RWxlbWVudCBmb2N1c2FibGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihMRVhJQ09OLnRpLCAnLTEnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0aGUgdGFiaW5kZXggaGFzIHRvIGJlIHJlbW92ZWQgZHVlIHRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogSWYgeW91IHNldCB0aGUgdGFiaW5kZXggYXR0cmlidXRlIG9uIGFuIDxkaXY+LCB0aGVuIGl0cyBjaGlsZCBjb250ZW50IGNhbm5vdCBiZSBzY3JvbGxlZCB3aXRoIHRoZSBhcnJvdyBrZXlzIHVubGVzcyB5b3Ugc2V0IHRhYmluZGV4IG9uIHRoZSBjb250ZW50LCB0b29cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvR2xvYmFsX2F0dHJpYnV0ZXMvdGFiaW5kZXhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfdmlld3BvcnRFbGVtZW50LCBfc3RyTW91c2VUb3VjaERvd25FdmVudCwgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy91cGRhdGUgZm9yIHRoZSBmaXJzdCB0aW1lICYgaW5pdGlhbGl6ZSBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhlIHBsdWdpbiBpcyBpbml0aWFsaXplZCBub3chXHJcbiAgICAgICAgICAgICAgICAgICAgX2luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkluaXRpYWxpemVkJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vY2FsbCBhbGwgY2FsbGJhY2tzIHdoaWNoIHdvdWxkIGZpcmUgYmVmb3JlIHRoZSBpbml0aWFsaXplZCB3YXMgY29tcGxldGVcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKF9jYWxsYmFja3NJbml0UWV1ZXVlLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IGRpc3BhdGNoQ2FsbGJhY2sodmFsdWUubiwgdmFsdWUuYSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jYWxsYmFja3NJbml0UWV1ZXVlID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHRlbnNpb25zKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gW2V4dGVuc2lvbnNdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShleHRlbnNpb25zKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChleHRlbnNpb25zLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IF9iYXNlLmFkZEV4dCh2YWx1ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KGV4dGVuc2lvbnMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGV4dGVuc2lvbnMsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7IF9iYXNlLmFkZEV4dChrZXksIHZhbHVlKTsgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSB0cmFuc2l0aW9uIGNsYXNzIGZvciB0cmFuc2l0aW9ucyBBRlRFUiB0aGUgZmlyc3QgdXBkYXRlICYgQUZURVIgdGhlIGFwcGxpZWQgZXh0ZW5zaW9ucyAoZm9yIHByZXZlbnRpbmcgdW53YW50ZWQgdHJhbnNpdGlvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24gJiYgIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgMzMzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfcGx1Z2luLnZhbGlkKGNvbnN0cnVjdChwbHVnaW5UYXJnZXRFbGVtZW50LCBvcHRpb25zLCBleHRlbnNpb25zKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCwgX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3IE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2Ugb2JqZWN0IG9yIGNoYW5nZXMgb3B0aW9ucyBpZiBhbHJlYWR5IGluaXRpYWxpemVkIG9yIHJldHVybnMgdGhlIGN1cnJlbnQgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50cyBUaGUgZWxlbWVudHMgdG8gd2hpY2ggdGhlIFBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIGN1c3RvbSBvcHRpb25zIHdpdGggd2hpY2ggdGhlIHBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbihzKSB3aGljaCBzaGFsbCBiZSBhZGRlZCByaWdodCBhZnRlciBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luID0gd2luZG93W1BMVUdJTk5BTUVdID0gZnVuY3Rpb24gKHBsdWdpblRhcmdldEVsZW1lbnRzLCBvcHRpb25zLCBleHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW0xFWElDT04ubF0gPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdHNJc1BsYWluT2JqID0gRlJBTUVXT1JLLmlzUGxhaW5PYmplY3Qob3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5zdDtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9wbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKCFwbHVnaW5UYXJnZXRFbGVtZW50cylcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0c0lzUGxhaW5PYmogfHwgIW9wdGlvbnMgPyByZXN1bHQgOiBhcnI7XHJcblxyXG4gICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgIHBsdWdpblRhcmdldEVsZW1lbnRzIHdpbGwgYmUgY29udmVydGVkIHRvOlxyXG4gICAgICAgICAgICAgICAgICAgMS4gQSBqUXVlcnlFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAyLiBBIEhUTUxFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAzLiBBIEFycmF5IHdpdGggYSBzaW5nbGUgSFRNTCBFbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICBzbyBwbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBhbHdheXMgYSBhcnJheS5cclxuICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBwbHVnaW5UYXJnZXRFbGVtZW50cyA9IHBsdWdpblRhcmdldEVsZW1lbnRzW0xFWElDT04ubF0gIT0gdW5kZWZpbmVkID8gcGx1Z2luVGFyZ2V0RWxlbWVudHMgOiBbcGx1Z2luVGFyZ2V0RWxlbWVudHNbMF0gfHwgcGx1Z2luVGFyZ2V0RWxlbWVudHNdO1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5UYXJnZXRFbGVtZW50c1tMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzSXNQbGFpbk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZWFjaChwbHVnaW5UYXJnZXRFbGVtZW50cywgZnVuY3Rpb24gKGksIHYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3QgPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3QgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChPdmVybGF5U2Nyb2xsYmFyc0luc3RhbmNlKGluc3QsIG9wdGlvbnMsIGV4dGVuc2lvbnMsIF9wbHVnaW5zR2xvYmFscywgX3BsdWdpbnNBdXRvVXBkYXRlTG9vcCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKHBsdWdpblRhcmdldEVsZW1lbnRzLCBmdW5jdGlvbiAoaSwgdikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCA9IElOU1RBTkNFUyh2KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob3B0aW9ucyA9PT0gJyEnICYmIF9wbHVnaW4udmFsaWQoaW5zdCkpIHx8IChDT01QQVRJQklMSVRZLnR5cGUob3B0aW9ucykgPT0gVFlQRVMuZiAmJiBvcHRpb25zKHYsIGluc3QpKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFycltMRVhJQ09OLmxdID09PSAxID8gYXJyWzBdIDogYXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGdsb2JhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGx1Z2luIGFuZCBlYWNoIGluc3RhbmNlIG9mIGl0LlxyXG4gICAgICAgICAgICAgKiBUaGUgcmV0dXJuZWQgb2JqZWN0IGlzIGp1c3QgYSBjb3B5LCB0aGF0IG1lYW5zIHRoYXQgY2hhbmdlcyB0byB0aGUgcmV0dXJuZWQgb2JqZWN0IHdvbid0IGhhdmUgYW55IGVmZmVjdCB0byB0aGUgb3JpZ2luYWwgb2JqZWN0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi5nbG9iYWxzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGdsb2JhbHMgPSBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHt9LCBfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIGdsb2JhbHNbJ21zaWUnXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBnbG9iYWxzO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEdldHMgb3IgU2V0cyB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBlYWNoIG5ldyBwbHVnaW4gaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBuZXdEZWZhdWx0T3B0aW9ucyBUaGUgb2JqZWN0IHdpdGggd2hpY2ggdGhlIGRlZmF1bHQgb3B0aW9ucyBzaGFsbCBiZSBleHRlbmRlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIF9wbHVnaW4uZGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAobmV3RGVmYXVsdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKTtcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyRGVmYXVsdE9wdGlvbnMgPSBfcGx1Z2luc0dsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3RGVmYXVsdE9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL3NldCB0aGUgbmV3IGRlZmF1bHQgb3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgX3BsdWdpbnNHbG9iYWxzLmRlZmF1bHRPcHRpb25zID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3ZhbGlkYXRlKG5ld0RlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBjdXJyRGVmYXVsdE9wdGlvbnMpLl9kZWZhdWx0KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcGFzc2VkIGluc3RhbmNlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9zSW5zdGFuY2UgVGhlIHBvdGVudGlhbCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc2VkIHZhbHVlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi52YWxpZCA9IGZ1bmN0aW9uIChvc0luc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb3NJbnN0YW5jZSBpbnN0YW5jZW9mIF9wbHVnaW4gJiYgIW9zSW5zdGFuY2UuZ2V0U3RhdGUoKS5kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogUmVnaXN0ZXJzLCBVbnJlZ2lzdGVycyBvciByZXR1cm5zIGEgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgbmFtZSBhbmQgdGhlIGV4dGVuc2lvbi4gKGRlZmF1bHRPcHRpb25zIGlzIG9wdGlvbmFsKVxyXG4gICAgICAgICAgICAgKiBVbnJlZ2lzdGVyOiBQYXNzIHRoZSBuYW1lIGFuZCBhbnl0aGluZyBleGNlcHQgYSBmdW5jdGlvbiBhcyBleHRlbnNpb24gcGFyYW1ldGVyLlxyXG4gICAgICAgICAgICAgKiBHZXQgZXh0ZW5zaW9uOiBQYXNzIHRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgYWxsIGV4dGVuc2lvbnM6IFBhc3Mgbm8gYXJndW1lbnRzLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHdoaWNoIHNoYWxsIGJlIHJlZ2lzdGVyZWQsIHVucmVnaXN0ZXJlZCBvciByZXR1cm5lZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbiBBIGZ1bmN0aW9uIHdoaWNoIGdlbmVyYXRlcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIGV4dGVuc2lvbiBvciBhbnl0aGluZyBvdGhlciB0byByZW1vdmUgYSBhbHJlYWR5IHJlZ2lzdGVyZWQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdE9wdGlvbnMgVGhlIGRlZmF1bHQgb3B0aW9ucyB3aGljaCBzaGFsbCBiZSB1c2VkIGZvciB0aGUgcmVnaXN0ZXJlZCBleHRlbnNpb24uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luLmV4dGVuc2lvbiA9IGZ1bmN0aW9uIChleHRlbnNpb25OYW1lLCBleHRlbnNpb24sIGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXh0TmFtZVR5cGVTdHJpbmcgPSBDT01QQVRJQklMSVRZLnR5cGUoZXh0ZW5zaW9uTmFtZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgIHZhciBhcmdMZW4gPSBhcmd1bWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPCAxIHx8ICFleHROYW1lVHlwZVN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGEgY29weSBvZiBhbGwgZXh0ZW5zaW9uIG9iamVjdHNcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7IGxlbmd0aDogX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF0gfSwgX3BsdWdpbnNFeHRlbnNpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV4dE5hbWVUeXBlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkudHlwZShleHRlbnNpb24pID09IFRZUEVTLmYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlciBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BsdWdpbnNFeHRlbnNpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZXh0ZW5zaW9uTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbkZhY3Rvcnk6IGV4dGVuc2lvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zOiBkZWZhdWx0T3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9wbHVnaW5zRXh0ZW5zaW9uc1tpXS5uYW1lID09PSBleHRlbnNpb25OYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ0xlbiA+IDEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zRXh0ZW5zaW9ucy5zcGxpY2UoaSwgMSk7IC8vcmVtb3ZlIGV4dGVuc2lvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIF9wbHVnaW5zRXh0ZW5zaW9uc1tpXSk7IC8vcmV0dXJuIGV4dGVuc2lvbiB3aXRoIHRoZSBnaXZlbiBuYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gX3BsdWdpbjtcclxuICAgICAgICB9KSgpO1xyXG5cclxuICAgICAgICBpZiAoSlFVRVJZICYmIEpRVUVSWS5mbikge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGpRdWVyeSBpbml0aWFsaXphdGlvbiBpbnRlcmZhY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBpbml0aWFsIG9wdGlvbnMgZm9yIHRoZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIHBsdWdpbi4gVG8gaW5pdGlhbGl6ZSB0aGUgcGx1Z2luLCB0aGlzIG9wdGlvbiBoYXMgdG8gYmUgYSBvYmplY3QhIElmIGl0IGlzbid0IGEgb2JqZWN0LCB0aGUgaW5zdGFuY2UocykgYXJlIHJldHVybmVkIGFuZCB0aGUgcGx1Z2luIHdvbnQgYmUgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb24ocykgd2hpY2ggc2hhbGwgYmUgYWRkZWQgcmlnaHQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBBZnRlciBpbml0aWFsaXphdGlvbiBpdCByZXR1cm5zIHRoZSBqUXVlcnkgZWxlbWVudCBhcnJheSwgZWxzZSBpdCByZXR1cm5zIHRoZSBpbnN0YW5jZShzKSBvZiB0aGUgZWxlbWVudHMgd2hpY2ggYXJlIHNlbGVjdGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgSlFVRVJZLmZuLm92ZXJsYXlTY3JvbGxiYXJzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgIHZhciBfZWxlbWVudHMgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgaWYgKEpRVUVSWS5pc1BsYWluT2JqZWN0KG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgSlFVRVJZLmVhY2goX2VsZW1lbnRzLCBmdW5jdGlvbiAoKSB7IFBMVUdJTih0aGlzLCBvcHRpb25zLCBleHRlbnNpb25zKTsgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9lbGVtZW50cztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUExVR0lOKF9lbGVtZW50cywgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBQTFVHSU47XHJcbiAgICB9XHJcbikpOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1090\n")}}]);
|
|
1
|
+
(window.webpackJsonp=window.webpackJsonp||[]).push([[11],{1012:function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OverlayScrollbarsComponent", function() { return OverlayScrollbarsComponent; });\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(578);\n/* harmony import */ var core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_constructor_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);\n/* harmony import */ var core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_exec_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(120);\n/* harmony import */ var core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_regexp_to_string_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(48);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(28);\n/* harmony import */ var core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_join_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(51);\n/* harmony import */ var core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_filter_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(71);\n/* harmony import */ var core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_split_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(118);\n/* harmony import */ var core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_match_js__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(20);\n/* harmony import */ var core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_concat_js__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(18);\n/* harmony import */ var core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_keys_js__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(4);\n/* harmony import */ var core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_symbol_js__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9);\n/* harmony import */ var core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_assign_js__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(1);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(1091);\n/* harmony import */ var overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(overlayscrollbars__WEBPACK_IMPORTED_MODULE_13__);\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n\n\n\n/**\n * Using overlayscrollbars-react component results use the esm modules\n * which doesn\'t go through babel leading to IE 11 uncompatibility\n * A PR is submitted that may fix this:\n * https://github.com/KingSora/OverlayScrollbars/pull/218\n * */\nvar OverlayScrollbarsComponent = function OverlayScrollbarsComponent(_ref) {\n var _ref$options = _ref.options,\n options = _ref$options === void 0 ? {} : _ref$options,\n extensions = _ref.extensions,\n className = _ref.className,\n children = _ref.children,\n rest = _objectWithoutProperties(_ref, ["options", "extensions", "className", "children"]);\n\n var osTargetRef = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n var osInstance = react__WEBPACK_IMPORTED_MODULE_12___default.a.useRef();\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n osInstance.current = overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default()(osTargetRef.current, options, extensions);\n mergeHostClassNames(osInstance.current, className);\n return function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.destroy();\n osInstance.current = null;\n }\n };\n }, []);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n osInstance.current.options(options);\n }\n }, [options]);\n react__WEBPACK_IMPORTED_MODULE_12___default.a.useEffect(function () {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance.current)) {\n mergeHostClassNames(osInstance.current, className);\n }\n }, [className]);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", _extends({\n className: "os-host"\n }, rest, {\n ref: osTargetRef\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-resize-observer-host"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-padding"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-viewport"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-content"\n }, children))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-horizontal "\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar os-scrollbar-vertical"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-track"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-handle"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_12___default.a.createElement("div", {\n className: "os-scrollbar-corner"\n }));\n};\nOverlayScrollbarsComponent.displayName = "OverlayScrollbarsComponent";\n\nfunction mergeHostClassNames(osInstance, className) {\n if (overlayscrollbars__WEBPACK_IMPORTED_MODULE_13___default.a.valid(osInstance)) {\n var _osInstance$getElemen = osInstance.getElements(),\n host = _osInstance$getElemen.host;\n\n var regex = new RegExp("(^os-host([-_].+|)$)|".concat(osInstance.options().className.replace(/\\s/g, \'$|\'), "$"), \'g\');\n var osClassNames = host.className.split(\' \').filter(function (name) {\n return name.match(regex);\n }).join(\' \');\n host.className = "".concat(osClassNames, " ").concat(className || \'\');\n }\n}\n\n/* harmony default export */ __webpack_exports__["default"] = (OverlayScrollbarsComponent);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvQHN0b3J5Ym9vay9jb21wb25lbnRzL2Rpc3QvZXNtL1Njcm9sbEFyZWEvT3ZlcmxheVNjcm9sbGJhcnMuanM/ZmIzZiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBa0Q7QUFDUDtBQUNLO0FBQ0Y7QUFDSjtBQUNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0Q7QUFDTDtBQUNPOztBQUU3QyxxQkFBcUIsZ0RBQWdELGdCQUFnQixzQkFBc0IsT0FBTywyQkFBMkIsMEJBQTBCLHlEQUF5RCwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsZUFBZSxHQUFHLHdDQUF3Qzs7QUFFM1QscURBQXFELCtCQUErQiw4REFBOEQsWUFBWSxvQ0FBb0MsNkRBQTZELFlBQVksNkJBQTZCLE9BQU8sMkJBQTJCLDBDQUEwQyx3RUFBd0UsMkJBQTJCLEVBQUUsRUFBRSxlQUFlOztBQUUxZSwwREFBMEQsK0JBQStCLGlCQUFpQixzQ0FBc0MsWUFBWSxZQUFZLHVCQUF1QixPQUFPLHFCQUFxQiwwQ0FBMEMsMkJBQTJCLEVBQUUsZUFBZTs7QUFFdlI7QUFDd0I7O0FBRWxEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsb0JBQW9CLDZDQUFLO0FBQ3pCLG1CQUFtQiw2Q0FBSztBQUN4QixFQUFFLDZDQUFLO0FBQ1AseUJBQXlCLHlEQUFpQjtBQUMxQztBQUNBO0FBQ0EsVUFBVSx5REFBaUI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRSw2Q0FBSztBQUNQLFFBQVEseURBQWlCO0FBQ3pCO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsc0JBQXNCLDZDQUFLO0FBQzNCO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRyxnQkFBZ0IsNkNBQUs7QUFDeEI7QUFDQSxHQUFHLGdCQUFnQiw2Q0FBSztBQUN4QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsZUFBZSw2Q0FBSztBQUN2QjtBQUNBLEdBQUcsNEJBQTRCLDZDQUFLO0FBQ3BDO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxlQUFlLDZDQUFLO0FBQ3ZCO0FBQ0EsR0FBRyxrQkFBa0IsNkNBQUs7QUFDMUI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGVBQWUsNkNBQUs7QUFDdkI7QUFDQSxHQUFHLGtCQUFrQiw2Q0FBSztBQUMxQjtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0EsTUFBTSx5REFBaUI7QUFDdkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVlLHlGQUEwQiIsImZpbGUiOiIxMDEyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5jb25zdHJ1Y3Rvci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnJlZ2V4cC5leGVjLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMucmVnZXhwLnRvLXN0cmluZy5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5yZXBsYWNlLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuYXJyYXkuam9pbi5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmZpbHRlci5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5zcGxpdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLnN0cmluZy5tYXRjaC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLmFycmF5LmNvbmNhdC5qc1wiO1xuaW1wb3J0IFwiY29yZS1qcy9tb2R1bGVzL2VzLm9iamVjdC5rZXlzLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMuc3ltYm9sLmpzXCI7XG5pbXBvcnQgXCJjb3JlLWpzL21vZHVsZXMvZXMub2JqZWN0LmFzc2lnbi5qc1wiO1xuXG5mdW5jdGlvbiBfZXh0ZW5kcygpIHsgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9OyByZXR1cm4gX2V4dGVuZHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpOyB2YXIga2V5LCBpOyBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykgeyB2YXIgc291cmNlU3ltYm9sS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKTsgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHsga2V5ID0gc291cmNlU3ltYm9sS2V5c1tpXTsgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTsgaWYgKCFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoc291cmNlLCBrZXkpKSBjb250aW51ZTsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IHJldHVybiB0YXJnZXQ7IH1cblxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkgeyBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTsgdmFyIHRhcmdldCA9IHt9OyB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7IHZhciBrZXksIGk7IGZvciAoaSA9IDA7IGkgPCBzb3VyY2VLZXlzLmxlbmd0aDsgaSsrKSB7IGtleSA9IHNvdXJjZUtleXNbaV07IGlmIChleGNsdWRlZC5pbmRleE9mKGtleSkgPj0gMCkgY29udGludWU7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gcmV0dXJuIHRhcmdldDsgfVxuXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE92ZXJsYXlTY3JvbGxiYXJzIGZyb20gJ292ZXJsYXlzY3JvbGxiYXJzJztcblxuLyoqXG4gKiBVc2luZyBvdmVybGF5c2Nyb2xsYmFycy1yZWFjdCBjb21wb25lbnQgcmVzdWx0cyB1c2UgdGhlIGVzbSBtb2R1bGVzXG4gKiB3aGljaCBkb2Vzbid0IGdvIHRocm91Z2ggYmFiZWwgbGVhZGluZyB0byBJRSAxMSB1bmNvbXBhdGliaWxpdHlcbiAqIEEgUFIgaXMgc3VibWl0dGVkIHRoYXQgbWF5IGZpeCB0aGlzOlxuICogaHR0cHM6Ly9naXRodWIuY29tL0tpbmdTb3JhL092ZXJsYXlTY3JvbGxiYXJzL3B1bGwvMjE4XG4gKiAqL1xuZXhwb3J0IHZhciBPdmVybGF5U2Nyb2xsYmFyc0NvbXBvbmVudCA9IGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50KF9yZWYpIHtcbiAgdmFyIF9yZWYkb3B0aW9ucyA9IF9yZWYub3B0aW9ucyxcbiAgICAgIG9wdGlvbnMgPSBfcmVmJG9wdGlvbnMgPT09IHZvaWQgMCA/IHt9IDogX3JlZiRvcHRpb25zLFxuICAgICAgZXh0ZW5zaW9ucyA9IF9yZWYuZXh0ZW5zaW9ucyxcbiAgICAgIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLFxuICAgICAgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgICAgcmVzdCA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhfcmVmLCBbXCJvcHRpb25zXCIsIFwiZXh0ZW5zaW9uc1wiLCBcImNsYXNzTmFtZVwiLCBcImNoaWxkcmVuXCJdKTtcblxuICB2YXIgb3NUYXJnZXRSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgdmFyIG9zSW5zdGFuY2UgPSBSZWFjdC51c2VSZWYoKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBvc0luc3RhbmNlLmN1cnJlbnQgPSBPdmVybGF5U2Nyb2xsYmFycyhvc1RhcmdldFJlZi5jdXJyZW50LCBvcHRpb25zLCBleHRlbnNpb25zKTtcbiAgICBtZXJnZUhvc3RDbGFzc05hbWVzKG9zSW5zdGFuY2UuY3VycmVudCwgY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50LmRlc3Ryb3koKTtcbiAgICAgICAgb3NJbnN0YW5jZS5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9O1xuICB9LCBbXSk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKE92ZXJsYXlTY3JvbGxiYXJzLnZhbGlkKG9zSW5zdGFuY2UuY3VycmVudCkpIHtcbiAgICAgIG9zSW5zdGFuY2UuY3VycmVudC5vcHRpb25zKG9wdGlvbnMpO1xuICAgIH1cbiAgfSwgW29wdGlvbnNdKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoT3ZlcmxheVNjcm9sbGJhcnMudmFsaWQob3NJbnN0YW5jZS5jdXJyZW50KSkge1xuICAgICAgbWVyZ2VIb3N0Q2xhc3NOYW1lcyhvc0luc3RhbmNlLmN1cnJlbnQsIGNsYXNzTmFtZSk7XG4gICAgfVxuICB9LCBbY2xhc3NOYW1lXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgY2xhc3NOYW1lOiBcIm9zLWhvc3RcIlxuICB9LCByZXN0LCB7XG4gICAgcmVmOiBvc1RhcmdldFJlZlxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1yZXNpemUtb2JzZXJ2ZXItaG9zdFwiXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXBhZGRpbmdcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXZpZXdwb3J0XCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1jb250ZW50XCJcbiAgfSwgY2hpbGRyZW4pKSksIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiXG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwib3Mtc2Nyb2xsYmFyLXRyYWNrXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItaGFuZGxlXCJcbiAgfSkpKSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCJcbiAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJvcy1zY3JvbGxiYXItdHJhY2tcIlxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1oYW5kbGVcIlxuICB9KSkpLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIm9zLXNjcm9sbGJhci1jb3JuZXJcIlxuICB9KSk7XG59O1xuT3ZlcmxheVNjcm9sbGJhcnNDb21wb25lbnQuZGlzcGxheU5hbWUgPSBcIk92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50XCI7XG5cbmZ1bmN0aW9uIG1lcmdlSG9zdENsYXNzTmFtZXMob3NJbnN0YW5jZSwgY2xhc3NOYW1lKSB7XG4gIGlmIChPdmVybGF5U2Nyb2xsYmFycy52YWxpZChvc0luc3RhbmNlKSkge1xuICAgIHZhciBfb3NJbnN0YW5jZSRnZXRFbGVtZW4gPSBvc0luc3RhbmNlLmdldEVsZW1lbnRzKCksXG4gICAgICAgIGhvc3QgPSBfb3NJbnN0YW5jZSRnZXRFbGVtZW4uaG9zdDtcblxuICAgIHZhciByZWdleCA9IG5ldyBSZWdFeHAoXCIoXm9zLWhvc3QoWy1fXS4rfCkkKXxcIi5jb25jYXQob3NJbnN0YW5jZS5vcHRpb25zKCkuY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCAnJHwnKSwgXCIkXCIpLCAnZycpO1xuICAgIHZhciBvc0NsYXNzTmFtZXMgPSBob3N0LmNsYXNzTmFtZS5zcGxpdCgnICcpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xuICAgICAgcmV0dXJuIG5hbWUubWF0Y2gocmVnZXgpO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgICBob3N0LmNsYXNzTmFtZSA9IFwiXCIuY29uY2F0KG9zQ2xhc3NOYW1lcywgXCIgXCIpLmNvbmNhdChjbGFzc05hbWUgfHwgJycpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IE92ZXJsYXlTY3JvbGxiYXJzQ29tcG9uZW50OyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1012\n')},1091:function(module,exports,__webpack_require__){eval("var __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * OverlayScrollbars\r\n * https://github.com/KingSora/OverlayScrollbars\r\n *\r\n * Version: 1.13.0\r\n *\r\n * Copyright KingSora | Rene Haas.\r\n * https://github.com/KingSora\r\n *\r\n * Released under the MIT license.\r\n * Date: 02.08.2020\r\n */\r\n\r\n(function (global, factory) {\r\n if (true)\r\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { return factory(global, global.document, undefined); }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\r\n else {}\r\n}(typeof window !== 'undefined' ? window : this,\r\n function (window, document, undefined) {\r\n 'use strict';\r\n var PLUGINNAME = 'OverlayScrollbars';\r\n var TYPES = {\r\n o: 'object',\r\n f: 'function',\r\n a: 'array',\r\n s: 'string',\r\n b: 'boolean',\r\n n: 'number',\r\n u: 'undefined',\r\n z: 'null'\r\n //d : 'date',\r\n //e : 'error',\r\n //r : 'regexp',\r\n //y : 'symbol'\r\n };\r\n var LEXICON = {\r\n c: 'class',\r\n s: 'style',\r\n i: 'id',\r\n l: 'length',\r\n p: 'prototype',\r\n ti: 'tabindex',\r\n oH: 'offsetHeight',\r\n cH: 'clientHeight',\r\n sH: 'scrollHeight',\r\n oW: 'offsetWidth',\r\n cW: 'clientWidth',\r\n sW: 'scrollWidth',\r\n hOP: 'hasOwnProperty',\r\n bCR: 'getBoundingClientRect'\r\n };\r\n var VENDORS = (function () {\r\n //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix\r\n var jsCache = {};\r\n var cssCache = {};\r\n var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-'];\r\n var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS'];\r\n function firstLetterToUpper(str) {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n }\r\n\r\n return {\r\n _cssPrefixes: cssPrefixes,\r\n _jsPrefixes: jsPrefixes,\r\n _cssProperty: function (name) {\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var uppercasedName = firstLetterToUpper(name);\r\n var elmStyle = document.createElement('div')[LEXICON.s];\r\n var resultPossibilities;\r\n var i = 0;\r\n var v;\r\n var currVendorWithoutDashes;\r\n\r\n for (; i < cssPrefixes.length; i++) {\r\n currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, '');\r\n resultPossibilities = [\r\n name, //transition\r\n cssPrefixes[i] + name, //-webkit-transition\r\n currVendorWithoutDashes + uppercasedName, //webkitTransition\r\n firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition\r\n ];\r\n for (v = 0; v < resultPossibilities[LEXICON.l]; v++) {\r\n if (elmStyle[resultPossibilities[v]] !== undefined) {\r\n result = resultPossibilities[v];\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _cssPropertyValue: function (property, values, suffix) {\r\n var name = property + ' ' + values;\r\n var result = cssCache[name];\r\n\r\n if (cssCache[LEXICON.hOP](name))\r\n return result;\r\n\r\n var dummyStyle = document.createElement('div')[LEXICON.s];\r\n var possbleValues = values.split(' ');\r\n var preparedSuffix = suffix || '';\r\n var i = 0;\r\n var v = -1;\r\n var prop;\r\n\r\n for (; i < possbleValues[LEXICON.l]; i++) {\r\n for (; v < VENDORS._cssPrefixes[LEXICON.l]; v++) {\r\n prop = v < 0 ? possbleValues[i] : VENDORS._cssPrefixes[v] + possbleValues[i];\r\n dummyStyle.cssText = property + ':' + prop + preparedSuffix;\r\n if (dummyStyle[LEXICON.l]) {\r\n result = prop;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n cssCache[name] = result;\r\n return result;\r\n },\r\n _jsAPI: function (name, isInterface, fallback) {\r\n var i = 0;\r\n var result = jsCache[name];\r\n\r\n if (!jsCache[LEXICON.hOP](name)) {\r\n result = window[name];\r\n for (; i < jsPrefixes[LEXICON.l]; i++)\r\n result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)];\r\n jsCache[name] = result;\r\n }\r\n return result || fallback;\r\n }\r\n }\r\n })();\r\n var COMPATIBILITY = (function () {\r\n function windowSize(x) {\r\n return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH];\r\n }\r\n function bind(func, thisObj) {\r\n if (typeof func != TYPES.f) {\r\n throw \"Can't bind function!\";\r\n // closest thing possible to the ECMAScript 5\r\n // internal IsCallable function\r\n //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');\r\n }\r\n var proto = LEXICON.p;\r\n var aArgs = Array[proto].slice.call(arguments, 2);\r\n var fNOP = function () { };\r\n var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); };\r\n\r\n if (func[proto])\r\n fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property\r\n fBound[proto] = new fNOP();\r\n\r\n return fBound;\r\n }\r\n\r\n return {\r\n /**\r\n * Gets the current window width.\r\n * @returns {Number|number} The current window width in pixel.\r\n */\r\n wW: bind(windowSize, 0, true),\r\n\r\n /**\r\n * Gets the current window height.\r\n * @returns {Number|number} The current window height in pixel.\r\n */\r\n wH: bind(windowSize, 0),\r\n\r\n /**\r\n * Gets the MutationObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined.\r\n */\r\n mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true),\r\n\r\n /**\r\n * Gets the ResizeObserver Object or undefined if not supported.\r\n * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined.\r\n */\r\n rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true),\r\n\r\n /**\r\n * Gets the RequestAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill.\r\n */\r\n rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }),\r\n\r\n /**\r\n * Gets the CancelAnimationFrame method or it's corresponding polyfill.\r\n * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill.\r\n */\r\n cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }),\r\n\r\n /**\r\n * Gets the current time.\r\n * @returns {number} The current time.\r\n */\r\n now: function () {\r\n return Date.now && Date.now() || new Date().getTime();\r\n },\r\n\r\n /**\r\n * Stops the propagation of the given event.\r\n * @param event The event of which the propagation shall be stoped.\r\n */\r\n stpP: function (event) {\r\n if (event.stopPropagation)\r\n event.stopPropagation();\r\n else\r\n event.cancelBubble = true;\r\n },\r\n\r\n /**\r\n * Prevents the default action of the given event.\r\n * @param event The event of which the default action shall be prevented.\r\n */\r\n prvD: function (event) {\r\n if (event.preventDefault && event.cancelable)\r\n event.preventDefault();\r\n else\r\n event.returnValue = false;\r\n },\r\n\r\n /**\r\n * Gets the pageX and pageY values of the given mouse event.\r\n * @param event The mouse event of which the pageX and pageX shall be got.\r\n * @returns {{x: number, y: number}} x = pageX value, y = pageY value.\r\n */\r\n page: function (event) {\r\n event = event.originalEvent || event;\r\n\r\n var strPage = 'page';\r\n var strClient = 'client';\r\n var strX = 'X';\r\n var strY = 'Y';\r\n var target = event.target || event.srcElement || document;\r\n var eventDoc = target.ownerDocument || document;\r\n var doc = eventDoc.documentElement;\r\n var body = eventDoc.body;\r\n\r\n //if touch event return return pageX/Y of it\r\n if (event.touches !== undefined) {\r\n var touch = event.touches[0];\r\n return {\r\n x: touch[strPage + strX],\r\n y: touch[strPage + strY]\r\n }\r\n }\r\n\r\n // Calculate pageX/Y if not native supported\r\n if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) {\r\n\r\n return {\r\n x: event[strClient + strX] +\r\n (doc && doc.scrollLeft || body && body.scrollLeft || 0) -\r\n (doc && doc.clientLeft || body && body.clientLeft || 0),\r\n y: event[strClient + strY] +\r\n (doc && doc.scrollTop || body && body.scrollTop || 0) -\r\n (doc && doc.clientTop || body && body.clientTop || 0)\r\n }\r\n }\r\n return {\r\n x: event[strPage + strX],\r\n y: event[strPage + strY]\r\n };\r\n },\r\n\r\n /**\r\n * Gets the clicked mouse button of the given mouse event.\r\n * @param event The mouse event of which the clicked button shal be got.\r\n * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton)\r\n */\r\n mBtn: function (event) {\r\n var button = event.button;\r\n if (!event.which && button !== undefined)\r\n return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));\r\n else\r\n return event.which;\r\n },\r\n\r\n /**\r\n * Checks whether a item is in the given array and returns its index.\r\n * @param item The item of which the position in the array shall be determined.\r\n * @param arr The array.\r\n * @returns {number} The zero based index of the item or -1 if the item isn't in the array.\r\n */\r\n inA: function (item, arr) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++)\r\n //Sometiems in IE a \"SCRIPT70\" Permission denied error occurs if HTML elements in a iFrame are compared\r\n try {\r\n if (arr[i] === item)\r\n return i;\r\n }\r\n catch (e) { }\r\n return -1;\r\n },\r\n\r\n /**\r\n * Returns true if the given value is a array.\r\n * @param arr The potential array.\r\n * @returns {boolean} True if the given value is a array, false otherwise.\r\n */\r\n isA: function (arr) {\r\n var def = Array.isArray;\r\n return def ? def(arr) : this.type(arr) == TYPES.a;\r\n },\r\n\r\n /**\r\n * Determine the internal JavaScript [[Class]] of the given object.\r\n * @param obj The object of which the type shall be determined.\r\n * @returns {string} The type of the given object.\r\n */\r\n type: function (obj) {\r\n if (obj === undefined)\r\n return obj + '';\r\n if (obj === null)\r\n return obj + '';\r\n return Object[LEXICON.p].toString.call(obj).replace(/^\\[object (.+)\\]$/, '$1').toLowerCase();\r\n },\r\n\r\n\r\n bind: bind\r\n\r\n /**\r\n * Gets the vendor-prefixed CSS property by the given name.\r\n * For example the given name is \"transform\" and you're using a old Firefox browser then the returned value would be \"-moz-transform\".\r\n * If the browser doesn't need a vendor-prefix, then the returned string is the given name.\r\n * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null.\r\n * @param propName The unprefixed CSS property name.\r\n * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property.\r\n\r\n cssProp: function(propName) {\r\n return VENDORS._cssProperty(propName);\r\n }\r\n */\r\n }\r\n })();\r\n\r\n\r\n var MATH = Math;\r\n var JQUERY = window.jQuery;\r\n var EASING = (function () {\r\n var _easingsMath = {\r\n p: MATH.PI,\r\n c: MATH.cos,\r\n s: MATH.sin,\r\n w: MATH.pow,\r\n t: MATH.sqrt,\r\n n: MATH.asin,\r\n a: MATH.abs,\r\n o: 1.70158\r\n };\r\n\r\n /*\r\n x : current percent (0 - 1),\r\n t : current time (duration * percent),\r\n b : start value (from),\r\n c : end value (to),\r\n d : duration\r\n\r\n easingName : function(x, t, b, c, d) { return easedValue; }\r\n */\r\n\r\n return {\r\n swing: function (x, t, b, c, d) {\r\n return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2;\r\n },\r\n linear: function (x, t, b, c, d) {\r\n return x;\r\n },\r\n easeInQuad: function (x, t, b, c, d) {\r\n return c * (t /= d) * t + b;\r\n },\r\n easeOutQuad: function (x, t, b, c, d) {\r\n return -c * (t /= d) * (t - 2) + b;\r\n },\r\n easeInOutQuad: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b;\r\n },\r\n easeInCubic: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t + b;\r\n },\r\n easeOutCubic: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t + 1) + b;\r\n },\r\n easeInOutCubic: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b;\r\n },\r\n easeInQuart: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t + b;\r\n },\r\n easeOutQuart: function (x, t, b, c, d) {\r\n return -c * ((t = t / d - 1) * t * t * t - 1) + b;\r\n },\r\n easeInOutQuart: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b;\r\n },\r\n easeInQuint: function (x, t, b, c, d) {\r\n return c * (t /= d) * t * t * t * t + b;\r\n },\r\n easeOutQuint: function (x, t, b, c, d) {\r\n return c * ((t = t / d - 1) * t * t * t * t + 1) + b;\r\n },\r\n easeInOutQuint: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b;\r\n },\r\n easeInSine: function (x, t, b, c, d) {\r\n return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b;\r\n },\r\n easeOutSine: function (x, t, b, c, d) {\r\n return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b;\r\n },\r\n easeInOutSine: function (x, t, b, c, d) {\r\n return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b;\r\n },\r\n easeInExpo: function (x, t, b, c, d) {\r\n return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b;\r\n },\r\n easeOutExpo: function (x, t, b, c, d) {\r\n return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b;\r\n },\r\n easeInOutExpo: function (x, t, b, c, d) {\r\n if (t == 0) return b;\r\n if (t == d) return b + c;\r\n if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b;\r\n return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b;\r\n },\r\n easeInCirc: function (x, t, b, c, d) {\r\n return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b;\r\n },\r\n easeOutCirc: function (x, t, b, c, d) {\r\n return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b;\r\n },\r\n easeInOutCirc: function (x, t, b, c, d) {\r\n return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b;\r\n },\r\n easeInElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n },\r\n easeOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d) == 1) return b + c;\r\n if (!p) p = d * .3;\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b;\r\n },\r\n easeInOutElastic: function (x, t, b, c, d) {\r\n var s = _easingsMath.o; var p = 0; var a = c;\r\n if (t == 0) return b;\r\n if ((t /= d / 2) == 2) return b + c;\r\n if (!p) p = d * (.3 * 1.5);\r\n if (a < _easingsMath.a(c)) { a = c; s = p / 4; }\r\n else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a);\r\n if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b;\r\n return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b;\r\n },\r\n easeInBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * (t /= d) * t * ((s + 1) * t - s) + b;\r\n },\r\n easeOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\r\n },\r\n easeInOutBack: function (x, t, b, c, d, s) {\r\n s = s || _easingsMath.o;\r\n return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;\r\n },\r\n easeInBounce: function (x, t, b, c, d) {\r\n return c - this.easeOutBounce(x, d - t, 0, c, d) + b;\r\n },\r\n easeOutBounce: function (x, t, b, c, d) {\r\n var o = 7.5625;\r\n if ((t /= d) < (1 / 2.75)) {\r\n return c * (o * t * t) + b;\r\n } else if (t < (2 / 2.75)) {\r\n return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b;\r\n } else if (t < (2.5 / 2.75)) {\r\n return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b;\r\n } else {\r\n return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b;\r\n }\r\n },\r\n easeInOutBounce: function (x, t, b, c, d) {\r\n return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;\r\n }\r\n };\r\n /*\r\n *\r\n * TERMS OF USE - EASING EQUATIONS\r\n * \r\n * Open source under the BSD License. \r\n * \r\n * Copyright © 2001 Robert Penner\r\n * All rights reserved.\r\n * \r\n * Redistribution and use in source and binary forms, with or without modification, \r\n * are permitted provided that the following conditions are met:\r\n * \r\n * Redistributions of source code must retain the above copyright notice, this list of \r\n * conditions and the following disclaimer.\r\n * Redistributions in binary form must reproduce the above copyright notice, this list \r\n * of conditions and the following disclaimer in the documentation and/or other materials \r\n * provided with the distribution.\r\n * \r\n * Neither the name of the author nor the names of contributors may be used to endorse \r\n * or promote products derived from this software without specific prior written permission.\r\n * \r\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY \r\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r\n * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\r\n * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \r\n * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r\n * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED \r\n * OF THE POSSIBILITY OF SUCH DAMAGE. \r\n *\r\n */\r\n })();\r\n var FRAMEWORK = (function () {\r\n var _rnothtmlwhite = (/[^\\x20\\t\\r\\n\\f]+/g);\r\n var _strSpace = ' ';\r\n var _strEmpty = '';\r\n var _strScrollLeft = 'scrollLeft';\r\n var _strScrollTop = 'scrollTop';\r\n var _animations = [];\r\n var _type = COMPATIBILITY.type;\r\n var _cssNumber = {\r\n animationIterationCount: true,\r\n columnCount: true,\r\n fillOpacity: true,\r\n flexGrow: true,\r\n flexShrink: true,\r\n fontWeight: true,\r\n lineHeight: true,\r\n opacity: true,\r\n order: true,\r\n orphans: true,\r\n widows: true,\r\n zIndex: true,\r\n zoom: true\r\n };\r\n\r\n function extend() {\r\n var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {},\r\n i = 1,\r\n length = arguments[LEXICON.l],\r\n deep = false;\r\n\r\n // Handle a deep copy situation\r\n if (_type(target) == TYPES.b) {\r\n deep = target;\r\n target = arguments[1] || {};\r\n // skip the boolean and the target\r\n i = 2;\r\n }\r\n\r\n // Handle case when target is a string or something (possible in deep copy)\r\n if (_type(target) != TYPES.o && !_type(target) == TYPES.f) {\r\n target = {};\r\n }\r\n\r\n // extend jQuery itself if only one argument is passed\r\n if (length === i) {\r\n target = FakejQuery;\r\n --i;\r\n }\r\n\r\n for (; i < length; i++) {\r\n // Only deal with non-null/undefined values\r\n if ((options = arguments[i]) != null) {\r\n // Extend the base object\r\n for (name in options) {\r\n src = target[name];\r\n copy = options[name];\r\n\r\n // Prevent never-ending loop\r\n if (target === copy) {\r\n continue;\r\n }\r\n\r\n // Recurse if we're merging plain objects or arrays\r\n if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) {\r\n if (copyIsArray) {\r\n copyIsArray = false;\r\n clone = src && COMPATIBILITY.isA(src) ? src : [];\r\n\r\n } else {\r\n clone = src && isPlainObject(src) ? src : {};\r\n }\r\n\r\n // Never move original objects, clone them\r\n target[name] = extend(deep, clone, copy);\r\n\r\n // Don't bring in undefined values\r\n } else if (copy !== undefined) {\r\n target[name] = copy;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Return the modified object\r\n return target;\r\n };\r\n\r\n function inArray(item, arr, fromIndex) {\r\n for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++)\r\n if (arr[i] === item)\r\n return i;\r\n return -1;\r\n }\r\n\r\n function isFunction(obj) {\r\n return _type(obj) == TYPES.f;\r\n };\r\n\r\n function isEmptyObject(obj) {\r\n for (var name in obj)\r\n return false;\r\n return true;\r\n };\r\n\r\n function isPlainObject(obj) {\r\n if (!obj || _type(obj) != TYPES.o)\r\n return false;\r\n\r\n var key;\r\n var proto = LEXICON.p;\r\n var hasOwnProperty = Object[proto].hasOwnProperty;\r\n var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor');\r\n var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf');\r\n\r\n if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\r\n return false;\r\n }\r\n\r\n\r\n for (key in obj) { /**/ }\r\n\r\n return _type(key) == TYPES.u || hasOwnProperty.call(obj, key);\r\n };\r\n\r\n function each(obj, callback) {\r\n var i = 0;\r\n\r\n if (isArrayLike(obj)) {\r\n for (; i < obj[LEXICON.l]; i++) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n else {\r\n for (i in obj) {\r\n if (callback.call(obj[i], i, obj[i]) === false)\r\n break;\r\n }\r\n }\r\n\r\n return obj;\r\n };\r\n\r\n function isArrayLike(obj) {\r\n var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l];\r\n var t = _type(obj);\r\n return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj);\r\n }\r\n\r\n function stripAndCollapse(value) {\r\n var tokens = value.match(_rnothtmlwhite) || [];\r\n return tokens.join(_strSpace);\r\n }\r\n\r\n function matches(elem, selector) {\r\n var nodeList = (elem.parentNode || document).querySelectorAll(selector) || [];\r\n var i = nodeList[LEXICON.l];\r\n\r\n while (i--)\r\n if (nodeList[i] == elem)\r\n return true;\r\n\r\n return false;\r\n }\r\n\r\n function insertAdjacentElement(el, strategy, child) {\r\n if (COMPATIBILITY.isA(child)) {\r\n for (var i = 0; i < child[LEXICON.l]; i++)\r\n insertAdjacentElement(el, strategy, child[i]);\r\n }\r\n else if (_type(child) == TYPES.s)\r\n el.insertAdjacentHTML(strategy, child);\r\n else\r\n el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]);\r\n }\r\n\r\n function setCSSVal(el, prop, val) {\r\n try {\r\n if (el[LEXICON.s][prop] !== undefined)\r\n el[LEXICON.s][prop] = parseCSSVal(prop, val);\r\n } catch (e) { }\r\n }\r\n\r\n function parseCSSVal(prop, val) {\r\n if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n)\r\n val += 'px';\r\n return val;\r\n }\r\n\r\n function startNextAnimationInQ(animObj, removeFromQ) {\r\n var index;\r\n var nextAnim;\r\n if (removeFromQ !== false)\r\n animObj.q.splice(0, 1);\r\n if (animObj.q[LEXICON.l] > 0) {\r\n nextAnim = animObj.q[0];\r\n animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true);\r\n }\r\n else {\r\n index = inArray(animObj, _animations);\r\n if (index > -1)\r\n _animations.splice(index, 1);\r\n }\r\n }\r\n\r\n function setAnimationValue(el, prop, value) {\r\n if (prop === _strScrollLeft || prop === _strScrollTop)\r\n el[prop] = value;\r\n else\r\n setCSSVal(el, prop, value);\r\n }\r\n\r\n function animate(el, props, options, easing, complete, guaranteedNext) {\r\n var hasOptions = isPlainObject(options);\r\n var from = {};\r\n var to = {};\r\n var i = 0;\r\n var key;\r\n var animObj;\r\n var start;\r\n var progress;\r\n var step;\r\n var specialEasing;\r\n var duration;\r\n if (hasOptions) {\r\n easing = options.easing;\r\n start = options.start;\r\n progress = options.progress;\r\n step = options.step;\r\n specialEasing = options.specialEasing;\r\n complete = options.complete;\r\n duration = options.duration;\r\n }\r\n else\r\n duration = options;\r\n specialEasing = specialEasing || {};\r\n duration = duration || 400;\r\n easing = easing || 'swing';\r\n guaranteedNext = guaranteedNext || false;\r\n\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n if (_animations[i].el === el) {\r\n animObj = _animations[i];\r\n break;\r\n }\r\n }\r\n\r\n if (!animObj) {\r\n animObj = {\r\n el: el,\r\n q: []\r\n };\r\n _animations.push(animObj);\r\n }\r\n\r\n for (key in props) {\r\n if (key === _strScrollLeft || key === _strScrollTop)\r\n from[key] = el[key];\r\n else\r\n from[key] = FakejQuery(el).css(key);\r\n }\r\n\r\n for (key in from) {\r\n if (from[key] !== props[key] && props[key] !== undefined)\r\n to[key] = props[key];\r\n }\r\n\r\n if (!isEmptyObject(to)) {\r\n var timeNow;\r\n var end;\r\n var percent;\r\n var fromVal;\r\n var toVal;\r\n var easedVal;\r\n var timeStart;\r\n var frame;\r\n var elapsed;\r\n var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q);\r\n var qObj = {\r\n props: to,\r\n duration: hasOptions ? options : duration,\r\n easing: easing,\r\n complete: complete\r\n };\r\n if (qPos === -1) {\r\n qPos = animObj.q[LEXICON.l];\r\n animObj.q.push(qObj);\r\n }\r\n\r\n if (qPos === 0) {\r\n if (duration > 0) {\r\n timeStart = COMPATIBILITY.now();\r\n frame = function () {\r\n timeNow = COMPATIBILITY.now();\r\n elapsed = (timeNow - timeStart);\r\n end = qObj.stop || elapsed >= duration;\r\n percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0);\r\n\r\n for (key in to) {\r\n fromVal = parseFloat(from[key]);\r\n toVal = parseFloat(to[key]);\r\n easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal;\r\n setAnimationValue(el, key, easedVal);\r\n if (isFunction(step)) {\r\n step(easedVal, {\r\n elem: el,\r\n prop: key,\r\n start: fromVal,\r\n now: easedVal,\r\n end: toVal,\r\n pos: percent,\r\n options: {\r\n easing: easing,\r\n speacialEasing: specialEasing,\r\n duration: duration,\r\n complete: complete,\r\n step: step\r\n },\r\n startTime: timeStart\r\n });\r\n }\r\n }\r\n\r\n if (isFunction(progress))\r\n progress({}, percent, MATH.max(0, duration - elapsed));\r\n\r\n if (end) {\r\n startNextAnimationInQ(animObj);\r\n if (isFunction(complete))\r\n complete();\r\n }\r\n else\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n };\r\n qObj.frame = COMPATIBILITY.rAF()(frame);\r\n }\r\n else {\r\n for (key in to)\r\n setAnimationValue(el, key, to[key]);\r\n startNextAnimationInQ(animObj);\r\n }\r\n }\r\n }\r\n else if (guaranteedNext)\r\n startNextAnimationInQ(animObj);\r\n }\r\n\r\n function stop(el, clearQ, jumpToEnd) {\r\n var animObj;\r\n var qObj;\r\n var key;\r\n var i = 0;\r\n for (; i < _animations[LEXICON.l]; i++) {\r\n animObj = _animations[i];\r\n if (animObj.el === el) {\r\n if (animObj.q[LEXICON.l] > 0) {\r\n qObj = animObj.q[0];\r\n qObj.stop = true;\r\n COMPATIBILITY.cAF()(qObj.frame);\r\n animObj.q.splice(0, 1);\r\n\r\n if (jumpToEnd)\r\n for (key in qObj.props)\r\n setAnimationValue(el, key, qObj.props[key]);\r\n\r\n if (clearQ)\r\n animObj.q = [];\r\n else\r\n startNextAnimationInQ(animObj, false);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function elementIsVisible(el) {\r\n return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]);\r\n }\r\n\r\n function FakejQuery(selector) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var base = new FakejQuery();\r\n var elements = selector;\r\n var i = 0;\r\n var elms;\r\n var el;\r\n\r\n if (_type(selector) == TYPES.s) {\r\n elements = [];\r\n if (selector.charAt(0) === '<') {\r\n el = document.createElement('div');\r\n el.innerHTML = selector;\r\n elms = el.children;\r\n }\r\n else {\r\n elms = document.querySelectorAll(selector);\r\n }\r\n\r\n for (; i < elms[LEXICON.l]; i++)\r\n elements.push(elms[i]);\r\n }\r\n\r\n if (elements) {\r\n if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self))\r\n elements = [elements];\r\n\r\n for (i = 0; i < elements[LEXICON.l]; i++)\r\n base[i] = elements[i];\r\n\r\n base[LEXICON.l] = elements[LEXICON.l];\r\n }\r\n\r\n return base;\r\n };\r\n\r\n FakejQuery[LEXICON.p] = {\r\n\r\n //EVENTS:\r\n\r\n on: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.addEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.addEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.attachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n off: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n\r\n var eventNameLength = eventName[LEXICON.l];\r\n var i = 0;\r\n var el;\r\n return this.each(function () {\r\n el = this;\r\n try {\r\n if (el.removeEventListener) {\r\n for (; i < eventNameLength; i++)\r\n el.removeEventListener(eventName[i], handler);\r\n }\r\n else if (el.detachEvent) {\r\n for (; i < eventNameLength; i++)\r\n el.detachEvent('on' + eventName[i], handler);\r\n }\r\n } catch (e) { }\r\n });\r\n },\r\n\r\n one: function (eventName, handler) {\r\n eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty];\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n FakejQuery.each(eventName, function (i, oneEventName) {\r\n var oneHandler = function (e) {\r\n handler.call(this, e);\r\n el.off(oneEventName, oneHandler);\r\n };\r\n el.on(oneEventName, oneHandler);\r\n });\r\n });\r\n },\r\n\r\n trigger: function (eventName) {\r\n var el;\r\n var event;\r\n return this.each(function () {\r\n el = this;\r\n if (document.createEvent) {\r\n event = document.createEvent('HTMLEvents');\r\n event.initEvent(eventName, true, false);\r\n el.dispatchEvent(event);\r\n }\r\n else {\r\n el.fireEvent('on' + eventName);\r\n }\r\n });\r\n },\r\n\r\n //DOM NODE INSERTING / REMOVING:\r\n\r\n append: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforeend', child); });\r\n },\r\n\r\n prepend: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); });\r\n },\r\n\r\n before: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); });\r\n },\r\n\r\n after: function (child) {\r\n return this.each(function () { insertAdjacentElement(this, 'afterend', child); });\r\n },\r\n\r\n remove: function () {\r\n return this.each(function () {\r\n var el = this;\r\n var parentNode = el.parentNode;\r\n if (parentNode != null)\r\n parentNode.removeChild(el);\r\n });\r\n },\r\n\r\n unwrap: function () {\r\n var parents = [];\r\n var i;\r\n var el;\r\n var parent;\r\n\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (inArray(parent, parents) === - 1)\r\n parents.push(parent);\r\n });\r\n\r\n for (i = 0; i < parents[LEXICON.l]; i++) {\r\n el = parents[i];\r\n parent = el.parentNode;\r\n while (el.firstChild)\r\n parent.insertBefore(el.firstChild, el);\r\n parent.removeChild(el);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n wrapAll: function (wrapperHTML) {\r\n var i;\r\n var nodes = this;\r\n var wrapper = FakejQuery(wrapperHTML)[0];\r\n var deepest = wrapper;\r\n var parent = nodes[0].parentNode;\r\n var previousSibling = nodes[0].previousSibling;\r\n while (deepest.childNodes[LEXICON.l] > 0)\r\n deepest = deepest.childNodes[0];\r\n\r\n for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++)\r\n deepest.appendChild(nodes[i]);\r\n\r\n var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild;\r\n parent.insertBefore(wrapper, nextSibling);\r\n\r\n return this;\r\n },\r\n\r\n wrapInner: function (wrapperHTML) {\r\n return this.each(function () {\r\n var el = FakejQuery(this);\r\n var contents = el.contents();\r\n\r\n if (contents[LEXICON.l])\r\n contents.wrapAll(wrapperHTML);\r\n else\r\n el.append(wrapperHTML);\r\n });\r\n },\r\n\r\n wrap: function (wrapperHTML) {\r\n return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); });\r\n },\r\n\r\n\r\n //DOM NODE MANIPULATION / INFORMATION:\r\n\r\n css: function (styles, val) {\r\n var el;\r\n var key;\r\n var cptStyle;\r\n var getCptStyle = window.getComputedStyle;\r\n if (_type(styles) == TYPES.s) {\r\n if (val === undefined) {\r\n el = this[0];\r\n cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles];\r\n\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!)\r\n return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle;\r\n }\r\n else {\r\n return this.each(function () {\r\n setCSSVal(this, styles, val);\r\n });\r\n }\r\n }\r\n else {\r\n return this.each(function () {\r\n for (key in styles)\r\n setCSSVal(this, key, styles[key]);\r\n });\r\n }\r\n },\r\n\r\n hasClass: function (className) {\r\n var elem, i = 0;\r\n var classNamePrepared = _strSpace + className + _strSpace;\r\n var classList;\r\n\r\n while ((elem = this[i++])) {\r\n classList = elem.classList;\r\n if (classList && classList.contains(className))\r\n return true;\r\n else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1)\r\n return true;\r\n }\r\n\r\n return false;\r\n },\r\n\r\n addClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.add(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n if (cur.indexOf(_strSpace + clazz + _strSpace) < 0)\r\n cur += clazz + _strSpace;\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n removeClass: function (className) {\r\n var classes;\r\n var elem;\r\n var cur;\r\n var curValue;\r\n var clazz;\r\n var finalValue;\r\n var supportClassList;\r\n var elmClassList;\r\n var i = 0;\r\n var v = 0;\r\n\r\n if (className) {\r\n classes = className.match(_rnothtmlwhite) || [];\r\n\r\n while ((elem = this[i++])) {\r\n elmClassList = elem.classList;\r\n if (supportClassList === undefined)\r\n supportClassList = elmClassList !== undefined;\r\n\r\n if (supportClassList) {\r\n while ((clazz = classes[v++]))\r\n elmClassList.remove(clazz);\r\n }\r\n else {\r\n curValue = elem.className + _strEmpty;\r\n cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace);\r\n\r\n if (cur) {\r\n while ((clazz = classes[v++]))\r\n while (cur.indexOf(_strSpace + clazz + _strSpace) > -1)\r\n cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace);\r\n\r\n finalValue = stripAndCollapse(cur);\r\n if (curValue !== finalValue)\r\n elem.className = finalValue;\r\n }\r\n }\r\n }\r\n }\r\n\r\n return this;\r\n },\r\n\r\n hide: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'none'; });\r\n },\r\n\r\n show: function () {\r\n return this.each(function () { this[LEXICON.s].display = 'block'; });\r\n },\r\n\r\n attr: function (attrName, value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el.getAttribute(attrName);\r\n el.setAttribute(attrName, value);\r\n }\r\n return this;\r\n },\r\n\r\n removeAttr: function (attrName) {\r\n return this.each(function () { this.removeAttribute(attrName); });\r\n },\r\n\r\n offset: function () {\r\n var el = this[0];\r\n var rect = el[LEXICON.bCR]();\r\n var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft];\r\n var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop];\r\n return {\r\n top: rect.top + scrollTop,\r\n left: rect.left + scrollLeft\r\n };\r\n },\r\n\r\n position: function () {\r\n var el = this[0];\r\n return {\r\n top: el.offsetTop,\r\n left: el.offsetLeft\r\n };\r\n },\r\n\r\n scrollLeft: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollLeft];\r\n el[_strScrollLeft] = value;\r\n }\r\n return this;\r\n },\r\n\r\n scrollTop: function (value) {\r\n var i = 0;\r\n var el;\r\n while (el = this[i++]) {\r\n if (value === undefined)\r\n return el[_strScrollTop];\r\n el[_strScrollTop] = value;\r\n }\r\n return this;\r\n },\r\n\r\n val: function (value) {\r\n var el = this[0];\r\n if (!value)\r\n return el.value;\r\n el.value = value;\r\n return this;\r\n },\r\n\r\n\r\n //DOM TRAVERSAL / FILTERING:\r\n\r\n first: function () {\r\n return this.eq(0);\r\n },\r\n\r\n last: function () {\r\n return this.eq(-1);\r\n },\r\n\r\n eq: function (index) {\r\n return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]);\r\n },\r\n\r\n find: function (selector) {\r\n var children = [];\r\n var i;\r\n this.each(function () {\r\n var el = this;\r\n var ch = el.querySelectorAll(selector);\r\n for (i = 0; i < ch[LEXICON.l]; i++)\r\n children.push(ch[i]);\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n children: function (selector) {\r\n var children = [];\r\n var el;\r\n var ch;\r\n var i;\r\n\r\n this.each(function () {\r\n ch = this.children;\r\n for (i = 0; i < ch[LEXICON.l]; i++) {\r\n el = ch[i];\r\n if (selector) {\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n children.push(el);\r\n }\r\n else\r\n children.push(el);\r\n }\r\n });\r\n return FakejQuery(children);\r\n },\r\n\r\n parent: function (selector) {\r\n var parents = [];\r\n var parent;\r\n this.each(function () {\r\n parent = this.parentNode;\r\n if (selector ? FakejQuery(parent).is(selector) : true)\r\n parents.push(parent);\r\n });\r\n return FakejQuery(parents);\r\n },\r\n\r\n is: function (selector) {\r\n\r\n var el;\r\n var i;\r\n for (i = 0; i < this[LEXICON.l]; i++) {\r\n el = this[i];\r\n if (selector === ':visible')\r\n return elementIsVisible(el);\r\n if (selector === ':hidden')\r\n return !elementIsVisible(el);\r\n if ((el.matches && el.matches(selector)) || matches(el, selector))\r\n return true;\r\n }\r\n return false;\r\n },\r\n\r\n contents: function () {\r\n var contents = [];\r\n var childs;\r\n var i;\r\n\r\n this.each(function () {\r\n childs = this.childNodes;\r\n for (i = 0; i < childs[LEXICON.l]; i++)\r\n contents.push(childs[i]);\r\n });\r\n\r\n return FakejQuery(contents);\r\n },\r\n\r\n each: function (callback) {\r\n return each(this, callback);\r\n },\r\n\r\n\r\n //ANIMATION:\r\n\r\n animate: function (props, duration, easing, complete) {\r\n return this.each(function () { animate(this, props, duration, easing, complete); });\r\n },\r\n\r\n stop: function (clearQ, jump) {\r\n return this.each(function () { stop(this, clearQ, jump); });\r\n }\r\n };\r\n\r\n extend(FakejQuery, {\r\n extend: extend,\r\n inArray: inArray,\r\n isEmptyObject: isEmptyObject,\r\n isPlainObject: isPlainObject,\r\n each: each\r\n });\r\n\r\n return FakejQuery;\r\n })();\r\n var INSTANCES = (function () {\r\n var _targets = [];\r\n var _instancePropertyString = '__overlayScrollbars__';\r\n\r\n /**\r\n * Register, unregister or get a certain (or all) instances.\r\n * Register: Pass the target and the instance.\r\n * Unregister: Pass the target and null.\r\n * Get Instance: Pass the target from which the instance shall be got.\r\n * Get Targets: Pass no arguments.\r\n * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got\r\n * @param instance The instance.\r\n * @returns {*|void} Returns the instance from the given target.\r\n */\r\n return function (target, instance) {\r\n var argLen = arguments[LEXICON.l];\r\n if (argLen < 1) {\r\n //return all targets\r\n return _targets;\r\n }\r\n else {\r\n if (instance) {\r\n //register instance\r\n target[_instancePropertyString] = instance;\r\n _targets.push(target);\r\n }\r\n else {\r\n var index = COMPATIBILITY.inA(target, _targets);\r\n if (index > -1) {\r\n if (argLen > 1) {\r\n //unregister instance\r\n delete target[_instancePropertyString];\r\n _targets.splice(index, 1);\r\n }\r\n else {\r\n //get instance from target\r\n return _targets[index][_instancePropertyString];\r\n }\r\n }\r\n }\r\n }\r\n }\r\n })();\r\n var PLUGIN = (function () {\r\n var _plugin;\r\n var _pluginsGlobals;\r\n var _pluginsAutoUpdateLoop;\r\n var _pluginsExtensions = [];\r\n var _pluginsOptions = (function () {\r\n var type = COMPATIBILITY.type;\r\n var possibleTemplateTypes = [\r\n TYPES.b, //boolean\r\n TYPES.n, //number\r\n TYPES.s, //string\r\n TYPES.a, //array\r\n TYPES.o, //object\r\n TYPES.f, //function\r\n TYPES.z //null\r\n ];\r\n var restrictedStringsSplit = ' ';\r\n var restrictedStringsPossibilitiesSplit = ':';\r\n var classNameAllowedValues = [TYPES.z, TYPES.s];\r\n var numberAllowedValues = TYPES.n;\r\n var booleanNullAllowedValues = [TYPES.z, TYPES.b];\r\n var booleanTrueTemplate = [true, TYPES.b];\r\n var booleanFalseTemplate = [false, TYPES.b];\r\n var callbackTemplate = [null, [TYPES.z, TYPES.f]];\r\n var updateOnLoadTemplate = [['img'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]];\r\n var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical';\r\n var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden';\r\n var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto';\r\n var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move';\r\n var optionsDefaultsAndTemplate = {\r\n className: ['os-theme-dark', classNameAllowedValues], //null || string\r\n resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v\r\n sizeAutoCapable: booleanTrueTemplate, //true || false\r\n clipAlways: booleanTrueTemplate, //true || false\r\n normalizeRTL: booleanTrueTemplate, //true || false\r\n paddingAbsolute: booleanFalseTemplate, //true || false\r\n autoUpdate: [null, booleanNullAllowedValues], //true || false || null\r\n autoUpdateInterval: [33, numberAllowedValues], //number\r\n updateOnLoad: updateOnLoadTemplate, //string || array || null\r\n nativeScrollbarsOverlaid: {\r\n showNativeScrollbars: booleanFalseTemplate, //true || false\r\n initialize: booleanTrueTemplate //true || false\r\n },\r\n overflowBehavior: {\r\n x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s\r\n },\r\n scrollbars: {\r\n visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a\r\n autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m\r\n autoHideDelay: [800, numberAllowedValues], //number\r\n dragScrolling: booleanTrueTemplate, //true || false\r\n clickScrolling: booleanFalseTemplate, //true || false\r\n touchSupport: booleanTrueTemplate, //true || false\r\n snapHandle: booleanFalseTemplate //true || false\r\n },\r\n textarea: {\r\n dynWidth: booleanFalseTemplate, //true || false\r\n dynHeight: booleanFalseTemplate, //true || false\r\n inheritedAttrs: inheritedAttrsTemplate //string || array || null\r\n },\r\n callbacks: {\r\n onInitialized: callbackTemplate, //null || function\r\n onInitializationWithdrawn: callbackTemplate, //null || function\r\n onDestroyed: callbackTemplate, //null || function\r\n onScrollStart: callbackTemplate, //null || function\r\n onScroll: callbackTemplate, //null || function\r\n onScrollStop: callbackTemplate, //null || function\r\n onOverflowChanged: callbackTemplate, //null || function\r\n onOverflowAmountChanged: callbackTemplate, //null || function\r\n onDirectionChanged: callbackTemplate, //null || function\r\n onContentSizeChanged: callbackTemplate, //null || function\r\n onHostSizeChanged: callbackTemplate, //null || function\r\n onUpdated: callbackTemplate //null || function\r\n }\r\n };\r\n var convert = function (template) {\r\n var recursive = function (obj) {\r\n var key;\r\n var val;\r\n var valType;\r\n for (key in obj) {\r\n if (!obj[LEXICON.hOP](key))\r\n continue;\r\n val = obj[key];\r\n valType = type(val);\r\n if (valType == TYPES.a)\r\n obj[key] = val[template ? 1 : 0];\r\n else if (valType == TYPES.o)\r\n obj[key] = recursive(val);\r\n }\r\n return obj;\r\n };\r\n return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate));\r\n };\r\n\r\n return {\r\n _defaults: convert(),\r\n\r\n _template: convert(true),\r\n\r\n /**\r\n * Validates the passed object by the passed template.\r\n * @param obj The object which shall be validated.\r\n * @param template The template which defines the allowed values and types.\r\n * @param writeErrors True if errors shall be logged to the console.\r\n * @param diffObj If a object is passed then only valid differences to this object will be returned.\r\n * @returns {{}} A object which contains two objects called \"default\" and \"prepared\" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj.\r\n */\r\n _validate: function (obj, template, writeErrors, diffObj) {\r\n var validatedOptions = {};\r\n var validatedOptionsPrepared = {};\r\n var objectCopy = FRAMEWORK.extend(true, {}, obj);\r\n var inArray = FRAMEWORK.inArray;\r\n var isEmptyObj = FRAMEWORK.isEmptyObject;\r\n var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) {\r\n for (var prop in template) {\r\n if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) {\r\n var isValid = false;\r\n var isDiff = false;\r\n var templateValue = template[prop];\r\n var templateValueType = type(templateValue);\r\n var templateIsComplex = templateValueType == TYPES.o;\r\n var templateTypes = !COMPATIBILITY.isA(templateValue) ? [templateValue] : templateValue;\r\n var dataDiffValue = diffData[prop];\r\n var dataValue = data[prop];\r\n var dataValueType = type(dataValue);\r\n var propPrefix = prevPropName ? prevPropName + '.' : '';\r\n var error = \"The option \\\"\" + propPrefix + prop + \"\\\" wasn't set, because\";\r\n var errorPossibleTypes = [];\r\n var errorRestrictedStrings = [];\r\n var restrictedStringValuesSplit;\r\n var restrictedStringValuesPossibilitiesSplit;\r\n var isRestrictedValue;\r\n var mainPossibility;\r\n var currType;\r\n var i;\r\n var v;\r\n var j;\r\n\r\n dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue;\r\n\r\n //if the template has a object as value, it means that the options are complex (verschachtelt)\r\n if (templateIsComplex && dataValueType == TYPES.o) {\r\n validatedOptions[prop] = {};\r\n validatedOptionsPrepared[prop] = {};\r\n checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop);\r\n FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) {\r\n if (isEmptyObj(value[prop])) {\r\n delete value[prop];\r\n }\r\n });\r\n }\r\n else if (!templateIsComplex) {\r\n for (i = 0; i < templateTypes[LEXICON.l]; i++) {\r\n currType = templateTypes[i];\r\n templateValueType = type(currType);\r\n //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix\r\n isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1;\r\n if (isRestrictedValue) {\r\n errorPossibleTypes.push(TYPES.s);\r\n\r\n //split it into a array which contains all possible values for example: [\"y:yes\", \"n:no\", \"m:maybe\"]\r\n restrictedStringValuesSplit = currType.split(restrictedStringsSplit);\r\n errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit);\r\n for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) {\r\n //split the possible values into their possibiliteis for example: [\"y\", \"yes\"] -> the first is always the mainPossibility\r\n restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit);\r\n mainPossibility = restrictedStringValuesPossibilitiesSplit[0];\r\n for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) {\r\n //if any possibility matches with the dataValue, its valid\r\n if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n if (isValid)\r\n break;\r\n }\r\n }\r\n else {\r\n errorPossibleTypes.push(currType);\r\n\r\n if (dataValueType === currType) {\r\n isValid = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (isValid) {\r\n isDiff = dataValue !== dataDiffValue;\r\n\r\n if (isDiff)\r\n validatedOptions[prop] = dataValue;\r\n\r\n if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff)\r\n validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue;\r\n }\r\n else if (writeErrors) {\r\n console.warn(error + \" it doesn't accept the type [ \" + dataValueType.toUpperCase() + \" ] with the value of \\\"\" + dataValue + \"\\\".\\r\\n\" +\r\n \"Accepted types are: [ \" + errorPossibleTypes.join(', ').toUpperCase() + \" ].\" +\r\n (errorRestrictedStrings[length] > 0 ? \"\\r\\nValid strings are: [ \" + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + \" ].\" : ''));\r\n }\r\n delete data[prop];\r\n }\r\n }\r\n }\r\n };\r\n checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared);\r\n\r\n //add values which aren't specified in the template to the finished validated object to prevent them from being discarded\r\n /*\r\n if(keepForeignProps) {\r\n FRAMEWORK.extend(true, validatedOptions, objectCopy);\r\n FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy);\r\n }\r\n */\r\n\r\n if (!isEmptyObj(objectCopy) && writeErrors)\r\n console.warn('The following options are discarded due to invalidity:\\r\\n' + window.JSON.stringify(objectCopy, null, 2));\r\n\r\n return {\r\n _default: validatedOptions,\r\n _prepared: validatedOptionsPrepared\r\n };\r\n }\r\n }\r\n }());\r\n\r\n /**\r\n * Initializes the object which contains global information about the plugin and each instance of it.\r\n */\r\n function initOverlayScrollbarsStatics() {\r\n if (!_pluginsGlobals)\r\n _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults);\r\n if (!_pluginsAutoUpdateLoop)\r\n _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals);\r\n }\r\n\r\n /**\r\n * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @param defaultOptions\r\n * @constructor\r\n */\r\n function OverlayScrollbarsGlobals(defaultOptions) {\r\n var _base = this;\r\n var strOverflow = 'overflow';\r\n var strHidden = 'hidden';\r\n var strScroll = 'scroll';\r\n var bodyElement = FRAMEWORK('body');\r\n var scrollbarDummyElement = FRAMEWORK('<div id=\"os-dummy-scrollbar-size\"><div></div></div>');\r\n var scrollbarDummyElement0 = scrollbarDummyElement[0];\r\n var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0));\r\n\r\n bodyElement.append(scrollbarDummyElement);\r\n scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring)\r\n\r\n var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0);\r\n var nativeScrollbarIsOverlaid = {\r\n x: nativeScrollbarSize.x === 0,\r\n y: nativeScrollbarSize.y === 0\r\n };\r\n var msie = (function () {\r\n var ua = window.navigator.userAgent;\r\n var strIndexOf = 'indexOf';\r\n var strSubString = 'substring';\r\n var msie = ua[strIndexOf]('MSIE ');\r\n var trident = ua[strIndexOf]('Trident/');\r\n var edge = ua[strIndexOf]('Edge/');\r\n var rv = ua[strIndexOf]('rv:');\r\n var result;\r\n var parseIntFunc = parseInt;\r\n\r\n // IE 10 or older => return version number\r\n if (msie > 0)\r\n result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10);\r\n\r\n // IE 11 => return version number\r\n else if (trident > 0)\r\n result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10);\r\n\r\n // Edge (IE 12+) => return version number\r\n else if (edge > 0)\r\n result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10);\r\n\r\n // other browser\r\n return result;\r\n })();\r\n\r\n FRAMEWORK.extend(_base, {\r\n defaultOptions: defaultOptions,\r\n msie: msie,\r\n autoUpdateLoop: false,\r\n autoUpdateRecommended: !COMPATIBILITY.mO(),\r\n nativeScrollbarSize: nativeScrollbarSize,\r\n nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid,\r\n nativeScrollbarStyling: (function () {\r\n var result = false;\r\n scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible');\r\n try {\r\n result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none';\r\n } catch (ex) { }\r\n\r\n //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style.\r\n //and set overflow to scroll\r\n //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show();\r\n //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0;\r\n\r\n return result;\r\n })(),\r\n overlayScrollbarDummySize: { x: 30, y: 30 },\r\n cssCalc: VENDORS._cssPropertyValue('width', 'calc', '(1px)') || null,\r\n restrictedMeasuring: (function () {\r\n //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305\r\n //since 1.11.0 always false -> fixed via CSS (hopefully)\r\n scrollbarDummyElement.css(strOverflow, strHidden);\r\n var scrollSize = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n scrollbarDummyElement.css(strOverflow, 'visible');\r\n var scrollSize2 = {\r\n w: scrollbarDummyElement0[LEXICON.sW],\r\n h: scrollbarDummyElement0[LEXICON.sH]\r\n };\r\n return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0;\r\n })(),\r\n rtlScrollBehavior: (function () {\r\n scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0);\r\n var dummyContainerOffset = scrollbarDummyElement.offset();\r\n var dummyContainerChildOffset = dummyContainerChild.offset();\r\n //https://github.com/KingSora/OverlayScrollbars/issues/187\r\n scrollbarDummyElement.scrollLeft(-999);\r\n var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset();\r\n return {\r\n //origin direction = determines if the zero scroll position is on the left or right side\r\n //'i' means 'invert' (i === true means that the axis must be inverted to be correct)\r\n //true = on the left side\r\n //false = on the right side\r\n i: dummyContainerOffset.left === dummyContainerChildOffset.left,\r\n //negative = determines if the maximum scroll is positive or negative\r\n //'n' means 'negate' (n === true means that the axis must be negated to be correct)\r\n //true = negative\r\n //false = positive\r\n n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left\r\n };\r\n })(),\r\n supportTransform: !!VENDORS._cssProperty('transform'),\r\n supportTransition: !!VENDORS._cssProperty('transition'),\r\n supportPassiveEvents: (function () {\r\n var supportsPassive = false;\r\n try {\r\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\r\n get: function () {\r\n supportsPassive = true;\r\n }\r\n }));\r\n } catch (e) { }\r\n return supportsPassive;\r\n })(),\r\n supportResizeObserver: !!COMPATIBILITY.rO(),\r\n supportMutationObserver: !!COMPATIBILITY.mO()\r\n });\r\n\r\n scrollbarDummyElement.removeAttr(LEXICON.s).remove();\r\n\r\n //Catch zoom event:\r\n (function () {\r\n if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y)\r\n return;\r\n\r\n var abs = MATH.abs;\r\n var windowWidth = COMPATIBILITY.wW();\r\n var windowHeight = COMPATIBILITY.wH();\r\n var windowDpr = getWindowDPR();\r\n var onResize = function () {\r\n if (INSTANCES().length > 0) {\r\n var newW = COMPATIBILITY.wW();\r\n var newH = COMPATIBILITY.wH();\r\n var deltaW = newW - windowWidth;\r\n var deltaH = newH - windowHeight;\r\n\r\n if (deltaW === 0 && deltaH === 0)\r\n return;\r\n\r\n var deltaWRatio = MATH.round(newW / (windowWidth / 100.0));\r\n var deltaHRatio = MATH.round(newH / (windowHeight / 100.0));\r\n var absDeltaW = abs(deltaW);\r\n var absDeltaH = abs(deltaH);\r\n var absDeltaWRatio = abs(deltaWRatio);\r\n var absDeltaHRatio = abs(deltaHRatio);\r\n var newDPR = getWindowDPR();\r\n\r\n var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2;\r\n var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio);\r\n var dprChanged = newDPR !== windowDpr && windowDpr > 0;\r\n var isZoom = deltaIsBigger && difference && dprChanged;\r\n var oldScrollbarSize = _base.nativeScrollbarSize;\r\n var newScrollbarSize;\r\n\r\n if (isZoom) {\r\n bodyElement.append(scrollbarDummyElement);\r\n newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]);\r\n scrollbarDummyElement.remove();\r\n if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) {\r\n FRAMEWORK.each(INSTANCES(), function () {\r\n if (INSTANCES(this))\r\n INSTANCES(this).update('zoom');\r\n });\r\n }\r\n }\r\n\r\n windowWidth = newW;\r\n windowHeight = newH;\r\n windowDpr = newDPR;\r\n }\r\n };\r\n\r\n function differenceIsBiggerThanOne(valOne, valTwo) {\r\n var absValOne = abs(valOne);\r\n var absValTwo = abs(valTwo);\r\n return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo);\r\n }\r\n\r\n function getWindowDPR() {\r\n var dDPI = window.screen.deviceXDPI || 0;\r\n var sDPI = window.screen.logicalXDPI || 1;\r\n return window.devicePixelRatio || (dDPI / sDPI);\r\n }\r\n\r\n FRAMEWORK(window).on('resize', onResize);\r\n })();\r\n\r\n function calcNativeScrollbarSize(measureElement) {\r\n return {\r\n x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH],\r\n y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW]\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized.\r\n * @constructor\r\n */\r\n function OverlayScrollbarsAutoUpdateLoop(globals) {\r\n var _base = this;\r\n var _inArray = FRAMEWORK.inArray;\r\n var _getNow = COMPATIBILITY.now;\r\n var _strAutoUpdate = 'autoUpdate';\r\n var _strAutoUpdateInterval = _strAutoUpdate + 'Interval';\r\n var _strLength = LEXICON.l;\r\n var _loopingInstances = [];\r\n var _loopingInstancesIntervalCache = [];\r\n var _loopIsActive = false;\r\n var _loopIntervalDefault = 33;\r\n var _loopInterval = _loopIntervalDefault;\r\n var _loopTimeOld = _getNow();\r\n var _loopID;\r\n\r\n\r\n /**\r\n * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds.\r\n */\r\n var loop = function () {\r\n if (_loopingInstances[_strLength] > 0 && _loopIsActive) {\r\n _loopID = COMPATIBILITY.rAF()(function () {\r\n loop();\r\n });\r\n var timeNew = _getNow();\r\n var timeDelta = timeNew - _loopTimeOld;\r\n var lowestInterval;\r\n var instance;\r\n var instanceOptions;\r\n var instanceAutoUpdateAllowed;\r\n var instanceAutoUpdateInterval;\r\n var now;\r\n\r\n if (timeDelta > _loopInterval) {\r\n _loopTimeOld = timeNew - (timeDelta % _loopInterval);\r\n lowestInterval = _loopIntervalDefault;\r\n for (var i = 0; i < _loopingInstances[_strLength]; i++) {\r\n instance = _loopingInstances[i];\r\n if (instance !== undefined) {\r\n instanceOptions = instance.options();\r\n instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate];\r\n instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]);\r\n now = _getNow();\r\n\r\n if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) {\r\n instance.update('auto');\r\n _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval);\r\n }\r\n\r\n lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval));\r\n }\r\n }\r\n _loopInterval = lowestInterval;\r\n }\r\n } else {\r\n _loopInterval = _loopIntervalDefault;\r\n }\r\n };\r\n\r\n /**\r\n * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.add = function (instance) {\r\n if (_inArray(instance, _loopingInstances) === -1) {\r\n _loopingInstances.push(instance);\r\n _loopingInstancesIntervalCache.push(_getNow());\r\n if (_loopingInstances[_strLength] > 0 && !_loopIsActive) {\r\n _loopIsActive = true;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n loop();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before.\r\n * @param instance The instance which shall be updated in a loop automatically.\r\n */\r\n _base.remove = function (instance) {\r\n var index = _inArray(instance, _loopingInstances);\r\n if (index > -1) {\r\n //remove from loopingInstances list\r\n _loopingInstancesIntervalCache.splice(index, 1);\r\n _loopingInstances.splice(index, 1);\r\n\r\n //correct update loop behavior\r\n if (_loopingInstances[_strLength] === 0 && _loopIsActive) {\r\n _loopIsActive = false;\r\n globals.autoUpdateLoop = _loopIsActive;\r\n if (_loopID !== undefined) {\r\n COMPATIBILITY.cAF()(_loopID);\r\n _loopID = -1;\r\n }\r\n }\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * A object which manages the scrollbars visibility of the target element.\r\n * @param pluginTargetElement The element from which the scrollbars shall be hidden.\r\n * @param options The custom options.\r\n * @param extensions The custom extensions.\r\n * @param globals\r\n * @param autoUpdateLoop\r\n * @returns {*}\r\n * @constructor\r\n */\r\n function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) {\r\n //shortcuts\r\n var type = COMPATIBILITY.type;\r\n var inArray = FRAMEWORK.inArray;\r\n var each = FRAMEWORK.each;\r\n\r\n //make correct instanceof\r\n var _base = new _plugin();\r\n var _frameworkProto = FRAMEWORK[LEXICON.p];\r\n\r\n //if passed element is no HTML element: skip and return\r\n if (!isHTMLElement(pluginTargetElement))\r\n return;\r\n\r\n //if passed element is already initialized: set passed options if there are any and return its instance\r\n if (INSTANCES(pluginTargetElement)) {\r\n var inst = INSTANCES(pluginTargetElement);\r\n inst.options(options);\r\n return inst;\r\n }\r\n\r\n //globals:\r\n var _nativeScrollbarIsOverlaid;\r\n var _overlayScrollbarDummySize;\r\n var _rtlScrollBehavior;\r\n var _autoUpdateRecommended;\r\n var _msieVersion;\r\n var _nativeScrollbarStyling;\r\n var _cssCalc;\r\n var _nativeScrollbarSize;\r\n var _supportTransition;\r\n var _supportTransform;\r\n var _supportPassiveEvents;\r\n var _supportResizeObserver;\r\n var _supportMutationObserver;\r\n var _restrictedMeasuring;\r\n\r\n //general readonly:\r\n var _initialized;\r\n var _destroyed;\r\n var _isTextarea;\r\n var _isBody;\r\n var _documentMixed;\r\n var _domExists;\r\n\r\n //general:\r\n var _isBorderBox;\r\n var _sizeAutoObserverAdded;\r\n var _paddingX;\r\n var _paddingY;\r\n var _borderX;\r\n var _borderY;\r\n var _marginX;\r\n var _marginY;\r\n var _isRTL;\r\n var _sleeping;\r\n var _contentBorderSize = {};\r\n var _scrollHorizontalInfo = {};\r\n var _scrollVerticalInfo = {};\r\n var _viewportSize = {};\r\n var _nativeScrollbarMinSize = {};\r\n\r\n //naming:\t\r\n var _strMinusHidden = '-hidden';\r\n var _strMarginMinus = 'margin-';\r\n var _strPaddingMinus = 'padding-';\r\n var _strBorderMinus = 'border-';\r\n var _strTop = 'top';\r\n var _strRight = 'right';\r\n var _strBottom = 'bottom';\r\n var _strLeft = 'left';\r\n var _strMinMinus = 'min-';\r\n var _strMaxMinus = 'max-';\r\n var _strWidth = 'width';\r\n var _strHeight = 'height';\r\n var _strFloat = 'float';\r\n var _strEmpty = '';\r\n var _strAuto = 'auto';\r\n var _strSync = 'sync';\r\n var _strScroll = 'scroll';\r\n var _strHundredPercent = '100%';\r\n var _strX = 'x';\r\n var _strY = 'y';\r\n var _strDot = '.';\r\n var _strSpace = ' ';\r\n var _strScrollbar = 'scrollbar';\r\n var _strMinusHorizontal = '-horizontal';\r\n var _strMinusVertical = '-vertical';\r\n var _strScrollLeft = _strScroll + 'Left';\r\n var _strScrollTop = _strScroll + 'Top';\r\n var _strMouseTouchDownEvent = 'mousedown touchstart';\r\n var _strMouseTouchUpEvent = 'mouseup touchend touchcancel';\r\n var _strMouseTouchMoveEvent = 'mousemove touchmove';\r\n var _strMouseEnter = 'mouseenter';\r\n var _strMouseLeave = 'mouseleave';\r\n var _strKeyDownEvent = 'keydown';\r\n var _strKeyUpEvent = 'keyup';\r\n var _strSelectStartEvent = 'selectstart';\r\n var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd';\r\n var _strResizeObserverProperty = '__overlayScrollbarsRO__';\r\n\r\n //class names:\t\r\n var _cassNamesPrefix = 'os-';\r\n var _classNameHTMLElement = _cassNamesPrefix + 'html';\r\n var _classNameHostElement = _cassNamesPrefix + 'host';\r\n var _classNameHostElementForeign = _classNameHostElement + '-foreign';\r\n var _classNameHostTextareaElement = _classNameHostElement + '-textarea';\r\n var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden;\r\n var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden;\r\n var _classNameHostTransition = _classNameHostElement + '-transition';\r\n var _classNameHostRTL = _classNameHostElement + '-rtl';\r\n var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled';\r\n var _classNameHostScrolling = _classNameHostElement + '-scrolling';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflow = _classNameHostElement + '-overflow';\r\n var _classNameHostOverflowX = _classNameHostOverflow + '-x';\r\n var _classNameHostOverflowY = _classNameHostOverflow + '-y';\r\n var _classNameTextareaElement = _cassNamesPrefix + 'textarea';\r\n var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover';\r\n var _classNamePaddingElement = _cassNamesPrefix + 'padding';\r\n var _classNameViewportElement = _cassNamesPrefix + 'viewport';\r\n var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible';\r\n var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid';\r\n var _classNameContentElement = _cassNamesPrefix + 'content';\r\n var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange';\r\n var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue';\r\n var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer';\r\n var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer';\r\n var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item';\r\n var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final';\r\n var _classNameTextInherit = _cassNamesPrefix + 'text-inherit';\r\n var _classNameScrollbar = _cassNamesPrefix + _strScrollbar;\r\n var _classNameScrollbarTrack = _classNameScrollbar + '-track';\r\n var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off';\r\n var _classNameScrollbarHandle = _classNameScrollbar + '-handle';\r\n var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off';\r\n var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable';\r\n var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden;\r\n var _classNameScrollbarCorner = _classNameScrollbar + '-corner';\r\n var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize';\r\n var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both';\r\n var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal;\r\n var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical;\r\n var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal;\r\n var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical;\r\n var _classNameDragging = _cassNamesPrefix + 'dragging';\r\n var _classNameThemeNone = _cassNamesPrefix + 'theme-none';\r\n var _classNamesDynamicDestroy = [\r\n _classNameViewportNativeScrollbarsInvisible,\r\n _classNameViewportNativeScrollbarsOverlaid,\r\n _classNameScrollbarTrackOff,\r\n _classNameScrollbarHandleOff,\r\n _classNameScrollbarUnusable,\r\n _classNameScrollbarAutoHidden,\r\n _classNameScrollbarCornerResize,\r\n _classNameScrollbarCornerResizeB,\r\n _classNameScrollbarCornerResizeH,\r\n _classNameScrollbarCornerResizeV,\r\n _classNameDragging].join(_strSpace);\r\n\r\n //callbacks:\t\r\n var _callbacksInitQeueue = [];\r\n\r\n //attrs viewport shall inherit from target\t\r\n var _viewportAttrsFromTarget = [LEXICON.ti];\r\n\r\n //options:\t\r\n var _defaultOptions;\r\n var _currentOptions;\r\n var _currentPreparedOptions;\r\n\r\n //extensions:\t\r\n var _extensions = {};\r\n var _extensionsPrivateMethods = 'added removed on contract';\r\n\r\n //update\t\r\n var _lastUpdateTime;\r\n var _swallowedUpdateHints = {};\r\n var _swallowedUpdateTimeout;\r\n var _swallowUpdateLag = 42;\r\n var _updateOnLoadEventName = 'load';\r\n var _updateOnLoadElms = [];\r\n\r\n //DOM elements:\t\r\n var _windowElement;\r\n var _documentElement;\r\n var _htmlElement;\r\n var _bodyElement;\r\n var _targetElement; //the target element of this OverlayScrollbars object\t\r\n var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement\t\r\n var _sizeAutoObserverElement; //observes size auto changes\t\r\n var _sizeObserverElement; //observes size and padding changes\t\r\n var _paddingElement; //manages the padding\t\r\n var _viewportElement; //is the viewport of our scrollbar model\t\r\n var _contentElement; //the element which holds the content\t\r\n var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays)\t\r\n var _contentGlueElement; //has always the size of the content element\t\r\n var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling\t\r\n var _scrollbarCornerElement;\r\n var _scrollbarHorizontalElement;\r\n var _scrollbarHorizontalTrackElement;\r\n var _scrollbarHorizontalHandleElement;\r\n var _scrollbarVerticalElement;\r\n var _scrollbarVerticalTrackElement;\r\n var _scrollbarVerticalHandleElement;\r\n var _windowElementNative;\r\n var _documentElementNative;\r\n var _targetElementNative;\r\n var _hostElementNative;\r\n var _sizeAutoObserverElementNative;\r\n var _sizeObserverElementNative;\r\n var _paddingElementNative;\r\n var _viewportElementNative;\r\n var _contentElementNative;\r\n\r\n //Cache:\t\r\n var _hostSizeCache;\r\n var _contentScrollSizeCache;\r\n var _arrangeContentSizeCache;\r\n var _hasOverflowCache;\r\n var _hideOverflowCache;\r\n var _widthAutoCache;\r\n var _heightAutoCache;\r\n var _cssBoxSizingCache;\r\n var _cssPaddingCache;\r\n var _cssBorderCache;\r\n var _cssMarginCache;\r\n var _cssDirectionCache;\r\n var _cssDirectionDetectedCache;\r\n var _paddingAbsoluteCache;\r\n var _clipAlwaysCache;\r\n var _contentGlueSizeCache;\r\n var _overflowBehaviorCache;\r\n var _overflowAmountCache;\r\n var _ignoreOverlayScrollbarHidingCache;\r\n var _autoUpdateCache;\r\n var _sizeAutoCapableCache;\r\n var _contentElementScrollSizeChangeDetectedCache;\r\n var _hostElementSizeChangeDetectedCache;\r\n var _scrollbarsVisibilityCache;\r\n var _scrollbarsAutoHideCache;\r\n var _scrollbarsClickScrollingCache;\r\n var _scrollbarsDragScrollingCache;\r\n var _resizeCache;\r\n var _normalizeRTLCache;\r\n var _classNameCache;\r\n var _oldClassName;\r\n var _textareaAutoWrappingCache;\r\n var _textareaInfoCache;\r\n var _textareaSizeCache;\r\n var _textareaDynHeightCache;\r\n var _textareaDynWidthCache;\r\n var _bodyMinSizeCache;\r\n var _updateAutoCache = {};\r\n\r\n //MutationObserver:\t\r\n var _mutationObserverHost;\r\n var _mutationObserverContent;\r\n var _mutationObserverHostCallback;\r\n var _mutationObserverContentCallback;\r\n var _mutationObserversConnected;\r\n var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows'];\r\n var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget);\r\n\r\n //events:\t\r\n var _destroyEvents = [];\r\n\r\n //textarea:\t\r\n var _textareaHasFocus;\r\n\r\n //scrollbars:\t\r\n var _scrollbarsAutoHideTimeoutId;\r\n var _scrollbarsAutoHideMoveTimeoutId;\r\n var _scrollbarsAutoHideDelay;\r\n var _scrollbarsAutoHideNever;\r\n var _scrollbarsAutoHideScroll;\r\n var _scrollbarsAutoHideMove;\r\n var _scrollbarsAutoHideLeave;\r\n var _scrollbarsHandleHovered;\r\n var _scrollbarsHandlesDefineScrollPos;\r\n\r\n //resize\t\r\n var _resizeNone;\r\n var _resizeBoth;\r\n var _resizeHorizontal;\r\n var _resizeVertical;\r\n\r\n\r\n //==== Event Listener ====//\t\r\n\r\n /**\t\r\n * Adds or removes a event listener from the given element. \t\r\n * @param element The element to which the event listener shall be applied or removed.\t\r\n * @param eventNames The name(s) of the events.\t\r\n * @param listener The method which shall be called.\t\r\n * @param remove True if the handler shall be removed, false or undefined if the handler shall be added.\t\r\n * @param passiveOrOptions The options for the event.\r\n */\r\n function setupResponsiveEventListener(element, eventNames, listener, remove, passiveOrOptions) {\r\n var collected = COMPATIBILITY.isA(eventNames) && COMPATIBILITY.isA(listener);\r\n var method = remove ? 'removeEventListener' : 'addEventListener';\r\n var onOff = remove ? 'off' : 'on';\r\n var events = collected ? false : eventNames.split(_strSpace)\r\n var i = 0;\r\n\r\n var passiveOrOptionsIsObj = FRAMEWORK.isPlainObject(passiveOrOptions);\r\n var passive = (_supportPassiveEvents && (passiveOrOptionsIsObj ? (passiveOrOptions._passive) : passiveOrOptions)) || false;\r\n var capture = passiveOrOptionsIsObj && (passiveOrOptions._capture || false);\r\n var nativeParam = _supportPassiveEvents ? {\r\n passive: passive,\r\n capture: capture,\r\n } : capture;\r\n\r\n if (collected) {\r\n for (; i < eventNames[LEXICON.l]; i++)\r\n setupResponsiveEventListener(element, eventNames[i], listener[i], remove, passiveOrOptions);\r\n }\r\n else {\r\n for (; i < events[LEXICON.l]; i++) {\r\n if(_supportPassiveEvents) {\r\n element[0][method](events[i], listener, nativeParam);\r\n }\r\n else {\r\n element[onOff](events[i], listener);\r\n } \r\n }\r\n }\r\n }\r\n\r\n\r\n function addDestroyEventListener(element, eventNames, listener, passive) {\r\n setupResponsiveEventListener(element, eventNames, listener, false, passive);\r\n _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive));\r\n }\r\n\r\n //==== Resize Observer ====//\r\n\r\n /**\r\n * Adds or removes a resize observer from the given element.\r\n * @param targetElement The element to which the resize observer shall be added or removed.\r\n * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed.\r\n */\r\n function setupResizeObserver(targetElement, onElementResizedCallback) {\r\n if (targetElement) {\r\n var resizeObserver = COMPATIBILITY.rO();\r\n var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart';\r\n var strChildNodes = 'childNodes';\r\n var constScroll = 3333333;\r\n var callback = function () {\r\n targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll);\r\n onElementResizedCallback();\r\n };\r\n //add resize observer:\r\n if (onElementResizedCallback) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0];\r\n var observer = element[_strResizeObserverProperty] = new resizeObserver(callback);\r\n observer.observe(element);\r\n }\r\n else {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n targetElement.prepend(\r\n generateDiv(_classNameResizeObserverElement,\r\n generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' },\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv(_classNameResizeObserverItemFinalElement)\r\n ) +\r\n generateDiv(_classNameResizeObserverItemElement,\r\n generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' })\r\n )\r\n )\r\n )\r\n );\r\n\r\n var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0];\r\n var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]);\r\n var expandElement = FRAMEWORK(observerElement[strChildNodes][0]);\r\n var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]);\r\n var widthCache = observerElement[LEXICON.oW];\r\n var heightCache = observerElement[LEXICON.oH];\r\n var isDirty;\r\n var rAFId;\r\n var currWidth;\r\n var currHeight;\r\n var factor = 2;\r\n var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!!\r\n var reset = function () {\r\n /*\r\n var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y;\r\n var expandChildCSS = {};\r\n expandChildCSS[_strWidth] = sizeResetWidth;\r\n expandChildCSS[_strHeight] = sizeResetHeight;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n\r\n expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight);\r\n */\r\n expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll);\r\n };\r\n var onResized = function () {\r\n rAFId = 0;\r\n if (!isDirty)\r\n return;\r\n\r\n widthCache = currWidth;\r\n heightCache = currHeight;\r\n callback();\r\n };\r\n var onScroll = function (event) {\r\n currWidth = observerElement[LEXICON.oW];\r\n currHeight = observerElement[LEXICON.oH];\r\n isDirty = currWidth != widthCache || currHeight != heightCache;\r\n\r\n if (event && isDirty && !rAFId) {\r\n COMPATIBILITY.cAF()(rAFId);\r\n rAFId = COMPATIBILITY.rAF()(onResized);\r\n }\r\n else if (!event)\r\n onResized();\r\n\r\n reset();\r\n if (event) {\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n return false;\r\n };\r\n var expandChildCSS = {};\r\n var observerElementCSS = {};\r\n\r\n setTopRightBottomLeft(observerElementCSS, _strEmpty, [\r\n -((nativeScrollbarSize.y + 1) * factor),\r\n nativeScrollbarSize.x * -factor,\r\n nativeScrollbarSize.y * -factor,\r\n -((nativeScrollbarSize.x + 1) * factor)\r\n ]);\r\n\r\n FRAMEWORK(observerElement).css(observerElementCSS);\r\n expandElement.on(_strScroll, onScroll);\r\n shrinkElement.on(_strScroll, onScroll);\r\n targetElement.on(strAnimationStartEvent, function () {\r\n onScroll(false);\r\n });\r\n //lets assume that the divs will never be that large and a constant value is enough\r\n expandChildCSS[_strWidth] = constScroll;\r\n expandChildCSS[_strHeight] = constScroll;\r\n expandElementChild.css(expandChildCSS);\r\n\r\n reset();\r\n }\r\n else {\r\n var attachEvent = _documentElementNative.attachEvent;\r\n var isIE = _msieVersion !== undefined;\r\n if (attachEvent) {\r\n targetElement.prepend(generateDiv(_classNameResizeObserverElement));\r\n findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback);\r\n }\r\n else {\r\n var obj = _documentElementNative.createElement(TYPES.o);\r\n obj.setAttribute(LEXICON.ti, '-1');\r\n obj.setAttribute(LEXICON.c, _classNameResizeObserverElement);\r\n obj.onload = function () {\r\n var wnd = this.contentDocument.defaultView;\r\n wnd.addEventListener('resize', callback);\r\n wnd.document.documentElement.style.display = 'none';\r\n };\r\n obj.type = 'text/html';\r\n if (isIE)\r\n targetElement.prepend(obj);\r\n obj.data = 'about:blank';\r\n if (!isIE)\r\n targetElement.prepend(obj);\r\n targetElement.on(strAnimationStartEvent, callback);\r\n }\r\n }\r\n }\r\n\r\n if (targetElement[0] === _sizeObserverElementNative) {\r\n var directionChanged = function () {\r\n var dir = _hostElement.css('direction');\r\n var css = {};\r\n var scrollLeftValue = 0;\r\n var result = false;\r\n if (dir !== _cssDirectionDetectedCache) {\r\n if (dir === 'ltr') {\r\n css[_strLeft] = 0;\r\n css[_strRight] = _strAuto;\r\n scrollLeftValue = constScroll;\r\n }\r\n else {\r\n css[_strLeft] = _strAuto;\r\n css[_strRight] = 0;\r\n scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll;\r\n }\r\n //execution order is important for IE!!!\r\n _sizeObserverElement.children().eq(0).css(css);\r\n _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll);\r\n _cssDirectionDetectedCache = dir;\r\n result = true;\r\n }\r\n return result;\r\n };\r\n directionChanged();\r\n addDestroyEventListener(targetElement, _strScroll, function (event) {\r\n if (directionChanged())\r\n update();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n });\r\n }\r\n }\r\n //remove resize observer:\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n var resizeObserverObj = element[_strResizeObserverProperty];\r\n if (resizeObserverObj) {\r\n resizeObserverObj.disconnect();\r\n delete element[_strResizeObserverProperty];\r\n }\r\n }\r\n else {\r\n remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0));\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Freezes or unfreezes the given resize observer.\r\n * @param targetElement The element to which the target resize observer is applied.\r\n * @param freeze True if the resize observer shall be frozen, false otherwise.\r\n \r\n function freezeResizeObserver(targetElement, freeze) {\r\n if (targetElement !== undefined) {\r\n if(freeze) {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].unobserve(element);\r\n }\r\n else {\r\n targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0);\r\n var w = targetElement.css(_strWidth);\r\n var h = targetElement.css(_strHeight);\r\n var css = {};\r\n css[_strWidth] = w;\r\n css[_strHeight] = h;\r\n targetElement.css(css);\r\n }\r\n }\r\n else {\r\n if (_supportResizeObserver) {\r\n var element = targetElement.contents()[0];\r\n element[_strResizeObserverProperty].observe(element);\r\n }\r\n else {\r\n var css = { };\r\n css[_strHeight] = _strEmpty;\r\n css[_strWidth] = _strEmpty;\r\n targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css);\r\n }\r\n }\r\n }\r\n }\r\n */\r\n\r\n\r\n //==== Mutation Observers ====//\r\n\r\n /**\r\n * Creates MutationObservers for the host and content Element if they are supported.\r\n */\r\n function createMutationObservers() {\r\n if (_supportMutationObserver) {\r\n var mutationObserverContentLag = 11;\r\n var mutationObserver = COMPATIBILITY.mO();\r\n var contentLastUpdate = COMPATIBILITY.now();\r\n var mutationTarget;\r\n var mutationAttrName;\r\n var mutationIsClass;\r\n var oldMutationVal;\r\n var newClassVal;\r\n var hostClassNameRegex;\r\n var contentTimeout;\r\n var now;\r\n var sizeAuto;\r\n var action;\r\n\r\n _mutationObserverHostCallback = function (mutations) {\r\n\r\n var doUpdate = false;\r\n var doUpdateForce = false;\r\n var mutation;\r\n var mutatedAttrs = [];\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n mutationTarget = mutation.target;\r\n mutationAttrName = mutation.attributeName;\r\n mutationIsClass = mutationAttrName === LEXICON.c;\r\n oldMutationVal = mutation.oldValue;\r\n newClassVal = mutationTarget.className;\r\n\r\n if (_domExists && mutationIsClass && !doUpdateForce) {\r\n // if old class value contains _classNameHostElementForeign and new class value doesn't\r\n if (oldMutationVal.indexOf(_classNameHostElementForeign) > -1 && newClassVal.indexOf(_classNameHostElementForeign) < 0) {\r\n hostClassNameRegex = createHostClassNameRegExp(true);\r\n _hostElementNative.className = newClassVal.split(_strSpace).concat(oldMutationVal.split(_strSpace).filter(function (name) {\r\n return name.match(hostClassNameRegex);\r\n })).join(_strSpace);\r\n doUpdate = doUpdateForce = true;\r\n }\r\n }\r\n\r\n if (!doUpdate) {\r\n doUpdate = mutationIsClass\r\n ? hostClassNamesChanged(oldMutationVal, newClassVal)\r\n : mutationAttrName === LEXICON.s\r\n ? oldMutationVal !== mutationTarget[LEXICON.s].cssText\r\n : true;\r\n }\r\n\r\n mutatedAttrs.push(mutationAttrName);\r\n });\r\n\r\n updateViewportAttrsFromTarget(mutatedAttrs);\r\n\r\n if (doUpdate)\r\n _base.update(doUpdateForce || _strAuto);\r\n }\r\n return doUpdate;\r\n };\r\n _mutationObserverContentCallback = function (mutations) {\r\n var doUpdate = false;\r\n var mutation;\r\n\r\n if (_initialized && !_sleeping) {\r\n each(mutations, function () {\r\n mutation = this;\r\n doUpdate = isUnknownMutation(mutation);\r\n return !doUpdate;\r\n });\r\n\r\n if (doUpdate) {\r\n now = COMPATIBILITY.now();\r\n sizeAuto = (_heightAutoCache || _widthAutoCache);\r\n action = function () {\r\n if (!_destroyed) {\r\n contentLastUpdate = now;\r\n\r\n //if cols, rows or wrap attr was changed\r\n if (_isTextarea)\r\n textareaUpdate();\r\n\r\n if (sizeAuto)\r\n update();\r\n else\r\n _base.update(_strAuto);\r\n }\r\n };\r\n clearTimeout(contentTimeout);\r\n if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto)\r\n action();\r\n else\r\n contentTimeout = setTimeout(action, mutationObserverContentLag);\r\n }\r\n }\r\n return doUpdate;\r\n }\r\n\r\n _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback);\r\n _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Connects the MutationObservers if they are supported.\r\n */\r\n function connectMutationObservers() {\r\n if (_supportMutationObserver && !_mutationObserversConnected) {\r\n _mutationObserverHost.observe(_hostElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n attributeFilter: _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, {\r\n attributes: true,\r\n attributeOldValue: true,\r\n subtree: !_isTextarea,\r\n childList: !_isTextarea,\r\n characterData: !_isTextarea,\r\n attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost\r\n });\r\n\r\n _mutationObserversConnected = true;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnects the MutationObservers if they are supported.\r\n */\r\n function disconnectMutationObservers() {\r\n if (_supportMutationObserver && _mutationObserversConnected) {\r\n _mutationObserverHost.disconnect();\r\n _mutationObserverContent.disconnect();\r\n\r\n _mutationObserversConnected = false;\r\n }\r\n }\r\n\r\n\r\n //==== Events of elements ====//\r\n\r\n /**\r\n * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!!\r\n * It refreshes the hostResizedEventArgs and the hostSizeResizeCache.\r\n * If there are any size changes, the update method gets called.\r\n */\r\n function hostOnResized() {\r\n if (!_sleeping) {\r\n var changed;\r\n var hostSize = {\r\n w: _sizeObserverElementNative[LEXICON.sW],\r\n h: _sizeObserverElementNative[LEXICON.sH]\r\n };\r\n\r\n changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache);\r\n _hostElementSizeChangeDetectedCache = hostSize;\r\n if (changed)\r\n update({ _hostSizeChanged: true });\r\n }\r\n }\r\n\r\n /**\r\n * The mouse enter event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseEnter() {\r\n if (_scrollbarsAutoHideLeave)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n\r\n /**\r\n * The mouse leave event of the host element. This event is only needed for the autoHide feature.\r\n */\r\n function hostOnMouseLeave() {\r\n if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging))\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n\r\n /**\r\n * The mouse move event of the host element. This event is only needed for the autoHide \"move\" feature.\r\n */\r\n function hostOnMouseMove() {\r\n if (_scrollbarsAutoHideMove) {\r\n refreshScrollbarsAutoHide(true);\r\n clearTimeout(_scrollbarsAutoHideMoveTimeoutId);\r\n _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () {\r\n if (_scrollbarsAutoHideMove && !_destroyed)\r\n refreshScrollbarsAutoHide(false);\r\n }, 100);\r\n }\r\n }\r\n\r\n /**\r\n * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element.\r\n * @param event The select start event.\r\n */\r\n function documentOnSelectStart(event) {\r\n COMPATIBILITY.prvD(event);\r\n return false;\r\n }\r\n\r\n /**\t\r\n * A callback which will be called after a element has loaded.\t\r\n */\r\n function updateOnLoadCallback(event) {\r\n var elm = FRAMEWORK(event.target);\r\n\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n if (elm.is(updateOnLoadSelector)) {\r\n update({ _contentSizeChanged: true });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars)\r\n * @param destroy Indicates whether the events shall be added or removed.\r\n */\r\n function setupHostMouseTouchEvents(destroy) {\r\n if (!destroy)\r\n setupHostMouseTouchEvents(true);\r\n\r\n setupResponsiveEventListener(_hostElement,\r\n _strMouseTouchMoveEvent.split(_strSpace)[0],\r\n hostOnMouseMove,\r\n (!_scrollbarsAutoHideMove || destroy), true);\r\n setupResponsiveEventListener(_hostElement,\r\n [_strMouseEnter, _strMouseLeave],\r\n [hostOnMouseEnter, hostOnMouseLeave],\r\n (!_scrollbarsAutoHideLeave || destroy), true);\r\n\r\n //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible\r\n if (!_initialized && !destroy)\r\n _hostElement.one('mouseover', hostOnMouseEnter);\r\n }\r\n\r\n\r\n //==== Update Detection ====//\r\n\r\n /**\r\n * Measures the min width and min height of the body element and refreshes the related cache.\r\n * @returns {boolean} True if the min width or min height has changed, false otherwise.\r\n */\r\n function bodyMinSizeChanged() {\r\n var bodyMinSize = {};\r\n if (_isBody && _contentArrangeElement) {\r\n bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth));\r\n bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight));\r\n bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache);\r\n bodyMinSize.f = true; //flag for \"measured at least once\"\r\n }\r\n _bodyMinSizeCache = bodyMinSize;\r\n return !!bodyMinSize.c;\r\n }\r\n\r\n /**\r\n * Returns true if the class names really changed (new class without plugin host prefix)\r\n * @param oldClassNames The old ClassName string or array.\r\n * @param newClassNames The new ClassName string or array.\r\n * @returns {boolean} True if the class names has really changed, false otherwise.\r\n */\r\n function hostClassNamesChanged(oldClassNames, newClassNames) {\r\n var currClasses = typeof newClassNames == TYPES.s ? newClassNames.split(_strSpace) : [];\r\n var oldClasses = typeof oldClassNames == TYPES.s ? oldClassNames.split(_strSpace) : [];\r\n var diff = getArrayDifferences(oldClasses, currClasses);\r\n\r\n // remove none theme from diff list to prevent update\r\n var idx = inArray(_classNameThemeNone, diff);\r\n var i;\r\n var regex;\r\n\r\n if (idx > -1)\r\n diff.splice(idx, 1);\r\n\r\n if (diff[LEXICON.l] > 0) {\r\n regex = createHostClassNameRegExp(true, true);\r\n for (i = 0; i < diff.length; i++) {\r\n if (!diff[i].match(regex)) {\r\n return true;\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown.\r\n * @param mutation The mutation which shall be checked.\r\n * @returns {boolean} True if the mutation is from a unknown element, false otherwise.\r\n */\r\n function isUnknownMutation(mutation) {\r\n var attributeName = mutation.attributeName;\r\n var mutationTarget = mutation.target;\r\n var mutationType = mutation.type;\r\n var strClosest = 'closest';\r\n\r\n if (mutationTarget === _contentElementNative)\r\n return attributeName === null;\r\n if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) {\r\n //ignore className changes by the plugin\t\r\n if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement))\r\n return hostClassNamesChanged(mutation.oldValue, mutationTarget.className);\r\n\r\n //only do it of browser support it natively\t\r\n if (typeof mutationTarget[strClosest] != TYPES.f)\r\n return true;\r\n if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null ||\r\n mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null)\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Returns true if the content size was changed since the last time this method was called.\r\n * @returns {boolean} True if the content size was changed, false otherwise.\r\n */\r\n function updateAutoContentSizeChanged() {\r\n if (_sleeping)\r\n return false;\r\n\r\n var contentMeasureElement = getContentMeasureElement();\r\n var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0;\r\n var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea;\r\n var css = {};\r\n var float;\r\n var bodyMinSizeC;\r\n var changed;\r\n var contentElementScrollSize;\r\n\r\n if (setCSS) {\r\n float = _contentElement.css(_strFloat);\r\n css[_strFloat] = _isRTL ? _strRight : _strLeft;\r\n css[_strWidth] = _strAuto;\r\n _contentElement.css(css);\r\n }\r\n contentElementScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW] + textareaValueLength,\r\n h: contentMeasureElement[LEXICON.sH] + textareaValueLength\r\n };\r\n if (setCSS) {\r\n css[_strFloat] = float;\r\n css[_strWidth] = _strHundredPercent;\r\n _contentElement.css(css);\r\n }\r\n\r\n bodyMinSizeC = bodyMinSizeChanged();\r\n changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache);\r\n\r\n _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize;\r\n\r\n return changed || bodyMinSizeC;\r\n }\r\n\r\n /**\r\n * Returns true when a attribute which the MutationObserver would observe has changed. \r\n * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise.\r\n */\r\n function meaningfulAttrsChanged() {\r\n if (_sleeping || _mutationObserversConnected)\r\n return;\r\n\r\n var elem;\r\n var curr;\r\n var cache;\r\n var changedAttrs = [];\r\n var checks = [\r\n {\r\n _elem: _hostElement,\r\n _attrs: _mutationObserverAttrsHost.concat(':visible')\r\n },\r\n {\r\n _elem: _isTextarea ? _targetElement : undefined,\r\n _attrs: _mutationObserverAttrsTextarea\r\n }\r\n ];\r\n\r\n each(checks, function (index, check) {\r\n elem = check._elem;\r\n if (elem) {\r\n each(check._attrs, function (index, attr) {\r\n curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr);\r\n cache = _updateAutoCache[attr];\r\n\r\n if (checkCache(curr, cache)) {\r\n changedAttrs.push(attr);\r\n }\r\n\r\n _updateAutoCache[attr] = curr;\r\n });\r\n }\r\n });\r\n\r\n updateViewportAttrsFromTarget(changedAttrs);\r\n\r\n return changedAttrs[LEXICON.l] > 0;\r\n }\r\n\r\n /**\r\n * Checks is a CSS Property of a child element is affecting the scroll size of the content.\r\n * @param propertyName The CSS property name.\r\n * @returns {boolean} True if the property is affecting the content scroll size, false otherwise.\r\n */\r\n function isSizeAffectingCSSProperty(propertyName) {\r\n if (!_initialized)\r\n return true;\r\n var flexGrow = 'flex-grow';\r\n var flexShrink = 'flex-shrink';\r\n var flexBasis = 'flex-basis';\r\n var affectingPropsX = [\r\n _strWidth,\r\n _strMinMinus + _strWidth,\r\n _strMaxMinus + _strWidth,\r\n _strMarginMinus + _strLeft,\r\n _strMarginMinus + _strRight,\r\n _strLeft,\r\n _strRight,\r\n 'font-weight',\r\n 'word-spacing',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsXContentBox = [\r\n _strPaddingMinus + _strLeft,\r\n _strPaddingMinus + _strRight,\r\n _strBorderMinus + _strLeft + _strWidth,\r\n _strBorderMinus + _strRight + _strWidth\r\n ];\r\n var affectingPropsY = [\r\n _strHeight,\r\n _strMinMinus + _strHeight,\r\n _strMaxMinus + _strHeight,\r\n _strMarginMinus + _strTop,\r\n _strMarginMinus + _strBottom,\r\n _strTop,\r\n _strBottom,\r\n 'line-height',\r\n flexGrow,\r\n flexShrink,\r\n flexBasis\r\n ];\r\n var affectingPropsYContentBox = [\r\n _strPaddingMinus + _strTop,\r\n _strPaddingMinus + _strBottom,\r\n _strBorderMinus + _strTop + _strWidth,\r\n _strBorderMinus + _strBottom + _strWidth\r\n ];\r\n var _strS = 's';\r\n var _strVS = 'v-s';\r\n var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS;\r\n var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS;\r\n var sizeIsAffected = false;\r\n var checkPropertyName = function (arr, name) {\r\n for (var i = 0; i < arr[LEXICON.l]; i++) {\r\n if (arr[i] === name)\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n if (checkY) {\r\n sizeIsAffected = checkPropertyName(affectingPropsY, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName);\r\n }\r\n if (checkX && !sizeIsAffected) {\r\n sizeIsAffected = checkPropertyName(affectingPropsX, propertyName);\r\n if (!sizeIsAffected && !_isBorderBox)\r\n sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName);\r\n }\r\n return sizeIsAffected;\r\n }\r\n\r\n\r\n //==== Update ====//\r\n\r\n /**\r\n * Sets the attribute values of the viewport element to the values from the target element.\r\n * The value of a attribute is only set if the attribute is whitelisted.\r\n * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set.\r\n */\r\n function updateViewportAttrsFromTarget(attrs) {\r\n attrs = attrs || _viewportAttrsFromTarget;\r\n each(attrs, function (index, attr) {\r\n if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) {\r\n var targetAttr = _targetElement.attr(attr);\r\n if (type(targetAttr) == TYPES.s) {\r\n _viewportElement.attr(attr, targetAttr);\r\n }\r\n else {\r\n _viewportElement.removeAttr(attr);\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Updates the variables and size of the textarea element, and manages the scroll on new line or new character.\r\n */\r\n function textareaUpdate() {\r\n if (!_sleeping) {\r\n var wrapAttrOff = !_textareaAutoWrappingCache;\r\n var minWidth = _viewportSize.w;\r\n var minHeight = _viewportSize.h;\r\n var css = {};\r\n var doMeasure = _widthAutoCache || wrapAttrOff;\r\n var origWidth;\r\n var width;\r\n var origHeight;\r\n var height;\r\n\r\n //reset min size\r\n css[_strMinMinus + _strWidth] = _strEmpty;\r\n css[_strMinMinus + _strHeight] = _strEmpty;\r\n\r\n //set width auto\r\n css[_strWidth] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure width\r\n origWidth = _targetElementNative[LEXICON.oW];\r\n width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1;\r\n /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/\r\n\r\n //set measured width\r\n css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent;\r\n css[_strMinMinus + _strWidth] = _strHundredPercent;\r\n\r\n //set height auto\r\n css[_strHeight] = _strAuto;\r\n _targetElement.css(css);\r\n\r\n //measure height\r\n origHeight = _targetElementNative[LEXICON.oH];\r\n height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1);\r\n\r\n //append correct size values\r\n css[_strWidth] = width;\r\n css[_strHeight] = height;\r\n _textareaCoverElement.css(css);\r\n\r\n //apply min width / min height to prevent textarea collapsing\r\n css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/;\r\n css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/;\r\n _targetElement.css(css);\r\n\r\n return {\r\n _originalWidth: origWidth,\r\n _originalHeight: origHeight,\r\n _dynamicWidth: width,\r\n _dynamicHeight: height\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param updateHints A objects which contains hints for this update:\r\n * {\r\n * _hostSizeChanged : boolean,\r\n * _contentSizeChanged : boolean,\r\n * _force : boolean, == preventSwallowing\r\n * _changedOptions : { }, == preventSwallowing && preventSleep\r\n * }\r\n */\r\n function update(updateHints) {\r\n clearTimeout(_swallowedUpdateTimeout);\r\n updateHints = updateHints || {};\r\n _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged;\r\n _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged;\r\n _swallowedUpdateHints._force |= updateHints._force;\r\n\r\n var now = COMPATIBILITY.now();\r\n var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged;\r\n var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged;\r\n var force = !!_swallowedUpdateHints._force;\r\n var changedOptions = updateHints._changedOptions;\r\n var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache);\r\n var displayIsHidden;\r\n\r\n if (swallow)\r\n _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag);\r\n\r\n //abort update due to:\r\n //destroyed\r\n //swallowing\r\n //sleeping\r\n //host is hidden or has false display\r\n if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline')\r\n return;\r\n\r\n _lastUpdateTime = now;\r\n _swallowedUpdateHints = {};\r\n\r\n //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely.\r\n if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n //native scrollbars are hidden, so change the values to zero\r\n _nativeScrollbarSize.x = 0;\r\n _nativeScrollbarSize.y = 0;\r\n }\r\n else {\r\n //refresh native scrollbar size (in case of zoom)\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n }\r\n\r\n // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small.\r\n // The calculation: [scrollbar size +3 *3]\r\n // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar)\r\n // (*3 because (1)increase / (2)decrease -button and (3)resize handle)\r\n _nativeScrollbarMinSize = {\r\n x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3,\r\n y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3\r\n };\r\n\r\n changedOptions = changedOptions || {};\r\n //freezeResizeObserver(_sizeObserverElement, true);\r\n //freezeResizeObserver(_sizeAutoObserverElement, true);\r\n\r\n var checkCacheAutoForce = function () {\r\n return checkCache.apply(this, [].slice.call(arguments).concat([force]));\r\n };\r\n\r\n //save current scroll offset\r\n var currScroll = {\r\n x: _viewportElement[_strScrollLeft](),\r\n y: _viewportElement[_strScrollTop]()\r\n };\r\n\r\n var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars;\r\n var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea;\r\n\r\n //scrollbars visibility:\r\n var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility;\r\n var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache);\r\n\r\n //scrollbars autoHide:\r\n var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide;\r\n var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache);\r\n\r\n //scrollbars click scrolling\r\n var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling;\r\n var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache);\r\n\r\n //scrollbars drag scrolling\r\n var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling;\r\n var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache);\r\n\r\n //className\r\n var className = _currentPreparedOptions.className;\r\n var classNameChanged = checkCacheAutoForce(className, _classNameCache);\r\n\r\n //resize\r\n var resize = _currentPreparedOptions.resize;\r\n var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility.\r\n\r\n //paddingAbsolute\r\n var paddingAbsolute = _currentPreparedOptions.paddingAbsolute;\r\n var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache);\r\n\r\n //clipAlways\r\n var clipAlways = _currentPreparedOptions.clipAlways;\r\n var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache);\r\n\r\n //sizeAutoCapable\r\n var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport.\r\n var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache);\r\n\r\n //showNativeScrollbars\r\n var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars;\r\n var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache);\r\n\r\n //autoUpdate\r\n var autoUpdate = _currentPreparedOptions.autoUpdate;\r\n var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache);\r\n\r\n //overflowBehavior\r\n var overflowBehavior = _currentPreparedOptions.overflowBehavior;\r\n var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force);\r\n\r\n //dynWidth:\r\n var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth;\r\n var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth);\r\n\r\n //dynHeight:\r\n var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight;\r\n var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight);\r\n\r\n //scrollbars visibility\r\n _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n';\r\n _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's';\r\n _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm';\r\n _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l';\r\n\r\n //scrollbars autoHideDelay\r\n _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay;\r\n\r\n //old className\r\n _oldClassName = _classNameCache;\r\n\r\n //resize\r\n _resizeNone = resize === 'n';\r\n _resizeBoth = resize === 'b';\r\n _resizeHorizontal = resize === 'h';\r\n _resizeVertical = resize === 'v';\r\n\r\n //normalizeRTL\r\n _normalizeRTLCache = _currentPreparedOptions.normalizeRTL;\r\n\r\n //ignore overlay scrollbar hiding\r\n ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y);\r\n\r\n //refresh options cache\r\n _scrollbarsVisibilityCache = scrollbarsVisibility;\r\n _scrollbarsAutoHideCache = scrollbarsAutoHide;\r\n _scrollbarsClickScrollingCache = scrollbarsClickScrolling;\r\n _scrollbarsDragScrollingCache = scrollbarsDragScrolling;\r\n _classNameCache = className;\r\n _resizeCache = resize;\r\n _paddingAbsoluteCache = paddingAbsolute;\r\n _clipAlwaysCache = clipAlways;\r\n _sizeAutoCapableCache = sizeAutoCapable;\r\n _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding;\r\n _autoUpdateCache = autoUpdate;\r\n _overflowBehaviorCache = extendDeep({}, overflowBehavior);\r\n _textareaDynWidthCache = textareaDynWidth;\r\n _textareaDynHeightCache = textareaDynHeight;\r\n _hasOverflowCache = _hasOverflowCache || { x: false, y: false };\r\n\r\n //set correct class name to the host element\r\n if (classNameChanged) {\r\n removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone);\r\n addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone);\r\n }\r\n\r\n //set correct auto Update\r\n if (autoUpdateChanged) {\r\n if (autoUpdate === true || (autoUpdate === null && _autoUpdateRecommended)) {\r\n disconnectMutationObservers();\r\n autoUpdateLoop.add(_base);\r\n }\r\n else {\r\n autoUpdateLoop.remove(_base);\r\n connectMutationObservers();\r\n }\r\n }\r\n\r\n //activate or deactivate size auto capability\r\n if (sizeAutoCapableChanged) {\r\n if (sizeAutoCapable) {\r\n if (_contentGlueElement) {\r\n _contentGlueElement.show();\r\n }\r\n else {\r\n _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement));\r\n _paddingElement.before(_contentGlueElement);\r\n }\r\n if (_sizeAutoObserverAdded) {\r\n _sizeAutoObserverElement.show();\r\n }\r\n else {\r\n _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement));\r\n _sizeAutoObserverElementNative = _sizeAutoObserverElement[0];\r\n\r\n _contentGlueElement.before(_sizeAutoObserverElement);\r\n var oldSize = { w: -1, h: -1 };\r\n setupResizeObserver(_sizeAutoObserverElement, function () {\r\n var newSize = {\r\n w: _sizeAutoObserverElementNative[LEXICON.oW],\r\n h: _sizeAutoObserverElementNative[LEXICON.oH]\r\n };\r\n if (checkCache(newSize, oldSize)) {\r\n if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) {\r\n update();\r\n }\r\n else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) {\r\n update();\r\n }\r\n }\r\n oldSize = newSize;\r\n });\r\n _sizeAutoObserverAdded = true;\r\n //fix heightAuto detector bug if height is fixed but contentHeight is 0.\r\n //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8.\r\n if (_cssCalc !== null)\r\n _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)');\r\n }\r\n }\r\n else {\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.hide();\r\n if (_contentGlueElement)\r\n _contentGlueElement.hide();\r\n }\r\n }\r\n\r\n //if force, update all resizeObservers too\r\n if (force) {\r\n _sizeObserverElement.find('*').trigger(_strScroll);\r\n if (_sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.find('*').trigger(_strScroll);\r\n }\r\n\r\n //display hidden:\r\n displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden;\r\n\r\n //textarea AutoWrapping:\r\n var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false;\r\n var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache);\r\n\r\n //detect direction:\r\n var cssDirection = _hostElement.css('direction');\r\n var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache);\r\n\r\n //detect box-sizing:\r\n var boxSizing = _hostElement.css('box-sizing');\r\n var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache);\r\n\r\n //detect padding:\r\n var padding = getTopRightBottomLeftHost(_strPaddingMinus);\r\n\r\n //width + height auto detecting var:\r\n var sizeAutoObserverElementBCRect;\r\n //exception occurs in IE8 sometimes (unknown exception)\r\n try {\r\n sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null;\r\n } catch (ex) {\r\n return;\r\n }\r\n\r\n _isRTL = cssDirection === 'rtl';\r\n _isBorderBox = (boxSizing === 'border-box');\r\n var isRTLLeft = _isRTL ? _strLeft : _strRight;\r\n var isRTLRight = _isRTL ? _strRight : _strLeft;\r\n\r\n //detect width auto:\r\n var widthAutoResizeDetection = false;\r\n var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false;\r\n if (sizeAutoCapable && !widthAutoObserverDetection) {\r\n var tmpCurrHostWidth = _hostElementNative[LEXICON.oW];\r\n var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth);\r\n _contentGlueElement.css(_strWidth, _strAuto);\r\n\r\n var tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n if (!widthAutoResizeDetection) {\r\n _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1);\r\n tmpNewHostWidth = _hostElementNative[LEXICON.oW];\r\n _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth);\r\n widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth;\r\n }\r\n }\r\n var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden;\r\n var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache);\r\n var wasWidthAuto = !widthAuto && _widthAutoCache;\r\n\r\n //detect height auto:\r\n var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false;\r\n var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache);\r\n var wasHeightAuto = !heightAuto && _heightAutoCache;\r\n\r\n //detect border:\r\n //we need the border only if border box and auto size\r\n var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox;\r\n var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox;\r\n var border = getTopRightBottomLeftHost(_strBorderMinus, '-' + _strWidth, !updateBorderX, !updateBorderY)\r\n\r\n //detect margin:\r\n var margin = getTopRightBottomLeftHost(_strMarginMinus);\r\n\r\n //vars to apply correct css\r\n var contentElementCSS = {};\r\n var contentGlueElementCSS = {};\r\n\r\n //funcs\r\n var getHostSize = function () {\r\n //has to be clientSize because offsetSize respect borders\r\n return {\r\n w: _hostElementNative[LEXICON.cW],\r\n h: _hostElementNative[LEXICON.cH]\r\n };\r\n };\r\n var getViewportSize = function () {\r\n //viewport size is padding container because it never has padding, margin and a border\r\n //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height\r\n //if this happens add the difference to the viewportSize to compensate the rounding error\r\n return {\r\n w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]),\r\n h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH])\r\n };\r\n };\r\n\r\n //set info for padding\r\n var paddingAbsoluteX = _paddingX = padding.l + padding.r;\r\n var paddingAbsoluteY = _paddingY = padding.t + padding.b;\r\n paddingAbsoluteX *= paddingAbsolute ? 1 : 0;\r\n paddingAbsoluteY *= paddingAbsolute ? 1 : 0;\r\n padding.c = checkCacheAutoForce(padding, _cssPaddingCache);\r\n\r\n //set info for border\r\n _borderX = border.l + border.r;\r\n _borderY = border.t + border.b;\r\n border.c = checkCacheAutoForce(border, _cssBorderCache);\r\n\r\n //set info for margin\r\n _marginX = margin.l + margin.r;\r\n _marginY = margin.t + margin.b;\r\n margin.c = checkCacheAutoForce(margin, _cssMarginCache);\r\n\r\n //refresh cache\r\n _textareaAutoWrappingCache = textareaAutoWrapping;\r\n _cssDirectionCache = cssDirection;\r\n _cssBoxSizingCache = boxSizing;\r\n _widthAutoCache = widthAuto;\r\n _heightAutoCache = heightAuto;\r\n _cssPaddingCache = padding;\r\n _cssBorderCache = border;\r\n _cssMarginCache = margin;\r\n\r\n //IEFix direction changed\r\n if (cssDirectionChanged && _sizeAutoObserverAdded)\r\n _sizeAutoObserverElement.css(_strFloat, isRTLRight);\r\n\r\n //apply padding:\r\n if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) {\r\n var paddingElementCSS = {};\r\n var textareaCSS = {};\r\n var paddingValues = [padding.t, padding.r, padding.b, padding.l];\r\n\r\n setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]);\r\n if (paddingAbsolute) {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty, paddingValues);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus);\r\n }\r\n else {\r\n setTopRightBottomLeft(paddingElementCSS, _strEmpty);\r\n setTopRightBottomLeft(_isTextarea ? textareaCSS : contentElementCSS, _strPaddingMinus, paddingValues);\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _targetElement.css(textareaCSS);\r\n }\r\n\r\n //viewport size is padding container because it never has padding, margin and a border.\r\n _viewportSize = getViewportSize();\r\n\r\n //update Textarea\r\n var textareaSize = _isTextarea ? textareaUpdate() : false;\r\n var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache);\r\n var textareaDynOrigSize = _isTextarea && textareaSize ? {\r\n w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth,\r\n h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight\r\n } : {};\r\n _textareaSizeCache = textareaSize;\r\n\r\n //fix height auto / width auto in cooperation with current padding & boxSizing behavior:\r\n if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c)) {\r\n contentElementCSS[_strHeight] = _strAuto;\r\n }\r\n else if (heightAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strHeight] = _strHundredPercent;\r\n }\r\n if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || padding.c || border.c || cssDirectionChanged)) {\r\n contentElementCSS[_strWidth] = _strAuto;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix\r\n }\r\n else if (widthAutoChanged || paddingAbsoluteChanged) {\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n contentElementCSS[_strFloat] = _strEmpty;\r\n contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix\r\n }\r\n if (widthAuto) {\r\n //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width\r\n contentGlueElementCSS[_strWidth] = _strAuto;\r\n\r\n contentElementCSS[_strWidth] = VENDORS._cssPropertyValue(_strWidth, 'max-content intrinsic') || _strAuto;\r\n contentElementCSS[_strFloat] = isRTLRight;\r\n }\r\n else {\r\n contentGlueElementCSS[_strWidth] = _strEmpty;\r\n }\r\n if (heightAuto) {\r\n //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping\r\n contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH];\r\n }\r\n else {\r\n contentGlueElementCSS[_strHeight] = _strEmpty;\r\n }\r\n if (sizeAutoCapable)\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n _contentElement.css(contentElementCSS);\r\n\r\n //CHECKPOINT HERE ~\r\n contentElementCSS = {};\r\n contentGlueElementCSS = {};\r\n\r\n //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true\r\n if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) {\r\n var strOverflow = 'overflow';\r\n var strOverflowX = strOverflow + '-x';\r\n var strOverflowY = strOverflow + '-y';\r\n var strHidden = 'hidden';\r\n var strVisible = 'visible';\r\n\r\n //Reset the viewport (very important for natively overlaid scrollbars and zoom change\r\n //don't change the overflow prop as it is very expensive and affects performance !A LOT!\r\n if (!_nativeScrollbarStyling) {\r\n var viewportElementResetCSS = {};\r\n var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0;\r\n var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0;\r\n setTopRightBottomLeft(viewportElementResetCSS, _strEmpty);\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n\r\n //measure several sizes:\r\n var contentMeasureElement = getContentMeasureElement();\r\n //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid\r\n var contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW],\r\n h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH]\r\n };\r\n var scrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH]\r\n };\r\n\r\n //apply the correct viewport style and measure viewport size\r\n if (!_nativeScrollbarStyling) {\r\n viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp;\r\n viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp;\r\n _viewportElement.css(viewportElementResetCSS);\r\n }\r\n _viewportSize = getViewportSize();\r\n\r\n //measure and correct several sizes\r\n var hostSize = getHostSize();\r\n var hostAbsoluteRectSize = {\r\n w: hostSize.w - _marginX - _borderX - (_isBorderBox ? 0 : _paddingX),\r\n h: hostSize.h - _marginY - _borderY - (_isBorderBox ? 0 : _paddingY)\r\n };\r\n var contentGlueSize = {\r\n //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually\r\n //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding\r\n w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostAbsoluteRectSize.w),\r\n h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostAbsoluteRectSize.h)\r\n };\r\n contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache);\r\n _contentGlueSizeCache = contentGlueSize;\r\n\r\n //apply correct contentGlue size\r\n if (sizeAutoCapable) {\r\n //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto\r\n if (contentGlueSize.c || (heightAuto || widthAuto)) {\r\n contentGlueElementCSS[_strWidth] = contentGlueSize.w;\r\n contentGlueElementCSS[_strHeight] = contentGlueSize.h;\r\n\r\n //textarea-sizes are already calculated correctly at this point\r\n if (!_isTextarea) {\r\n contentSize = {\r\n //use clientSize because natively overlaidScrollbars add borders\r\n w: contentMeasureElement[LEXICON.cW],\r\n h: contentMeasureElement[LEXICON.cH]\r\n };\r\n }\r\n }\r\n var textareaCoverCSS = {};\r\n var setContentGlueElementCSSfunction = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var wh = scrollbarVars._w_h;\r\n var strWH = scrollbarVars._width_height;\r\n var autoSize = horizontal ? widthAuto : heightAuto;\r\n var borderSize = horizontal ? _borderX : _borderY;\r\n var paddingSize = horizontal ? _paddingX : _paddingY;\r\n var marginSize = horizontal ? _marginX : _marginY;\r\n var viewportSize = _viewportSize[wh] - borderSize - marginSize - (_isBorderBox ? 0 : paddingSize);\r\n\r\n //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks\r\n if (!autoSize || (!autoSize && border.c))\r\n contentGlueElementCSS[strWH] = hostAbsoluteRectSize[wh] - 1;\r\n\r\n //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0)\r\n if (autoSize && (contentSize[wh] < viewportSize) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) {\r\n if (_isTextarea)\r\n textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1;\r\n contentGlueElementCSS[strWH] -= 1;\r\n }\r\n\r\n //make sure content glue size is at least 1\r\n if (contentSize[wh] > 0)\r\n contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]);\r\n };\r\n setContentGlueElementCSSfunction(true);\r\n setContentGlueElementCSSfunction(false);\r\n\r\n if (_isTextarea)\r\n _textareaCoverElement.css(textareaCoverCSS);\r\n _contentGlueElement.css(contentGlueElementCSS);\r\n }\r\n if (widthAuto)\r\n contentElementCSS[_strWidth] = _strHundredPercent;\r\n if (widthAuto && !_isBorderBox && !_mutationObserversConnected)\r\n contentElementCSS[_strFloat] = 'none';\r\n\r\n //apply and reset content style\r\n _contentElement.css(contentElementCSS);\r\n contentElementCSS = {};\r\n\r\n //measure again, but this time all correct sizes:\r\n var contentScrollSize = {\r\n w: contentMeasureElement[LEXICON.sW],\r\n h: contentMeasureElement[LEXICON.sH],\r\n };\r\n contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache);\r\n _contentScrollSizeCache = contentScrollSize;\r\n\r\n //refresh viewport size after correct measuring\r\n _viewportSize = getViewportSize();\r\n\r\n hostSize = getHostSize();\r\n hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache);\r\n _hostSizeCache = hostSize;\r\n\r\n var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0);\r\n var previousOverflowAmount = _overflowAmountCache;\r\n var overflowBehaviorIsVS = {};\r\n var overflowBehaviorIsVH = {};\r\n var overflowBehaviorIsS = {};\r\n var overflowAmount = {};\r\n var hasOverflow = {};\r\n var hideOverflow = {};\r\n var canScroll = {};\r\n var viewportRect = _paddingElementNative[LEXICON.bCR]();\r\n var setOverflowVariables = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xyI = scrollbarVarsInverted._x_y;\r\n var xy = scrollbarVars._x_y;\r\n var wh = scrollbarVars._w_h;\r\n var widthHeight = scrollbarVars._width_height;\r\n var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max';\r\n var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0;\r\n var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0;\r\n overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s';\r\n overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h';\r\n overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's';\r\n overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100);\r\n overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1;\r\n hasOverflow[xy] = overflowAmount[xy] > 0;\r\n\r\n //hideOverflow:\r\n //x || y : true === overflow is hidden by \"overflow: scroll\" OR \"overflow: hidden\"\r\n //xs || ys : true === overflow is hidden by \"overflow: scroll\"\r\n hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy];\r\n hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false;\r\n\r\n canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's'];\r\n };\r\n setOverflowVariables(true);\r\n setOverflowVariables(false);\r\n\r\n overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache);\r\n _overflowAmountCache = overflowAmount;\r\n hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache);\r\n _hasOverflowCache = hasOverflow;\r\n hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache);\r\n _hideOverflowCache = hideOverflow;\r\n\r\n //if native scrollbar is overlay at x OR y axis, prepare DOM\r\n if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) {\r\n var borderDesign = 'px solid transparent';\r\n var contentArrangeElementCSS = {};\r\n var arrangeContent = {};\r\n var arrangeChanged = force;\r\n var setContentElementCSS;\r\n\r\n if (hasOverflow.x || hasOverflow.y) {\r\n arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty;\r\n arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty;\r\n arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache);\r\n _arrangeContentSizeCache = arrangeContent;\r\n }\r\n\r\n if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) {\r\n contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty;\r\n setContentElementCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n var invertedAutoSize = horizontal ? heightAuto : widthAuto;\r\n\r\n if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty;\r\n contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty;\r\n }\r\n else {\r\n arrangeContent[scrollbarVarsInverted._w_h] =\r\n contentElementCSS[_strMarginMinus + strDirection] =\r\n contentElementCSS[_strBorderMinus + strDirection] = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n };\r\n\r\n if (_nativeScrollbarStyling) {\r\n addRemoveClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible, !ignoreOverlayScrollbarHiding)\r\n }\r\n else {\r\n setContentElementCSS(true);\r\n setContentElementCSS(false);\r\n }\r\n }\r\n if (ignoreOverlayScrollbarHiding) {\r\n arrangeContent.w = arrangeContent.h = _strEmpty;\r\n arrangeChanged = true;\r\n }\r\n if (arrangeChanged && !_nativeScrollbarStyling) {\r\n contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty;\r\n contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty;\r\n\r\n if (!_contentArrangeElement) {\r\n _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement));\r\n _viewportElement.prepend(_contentArrangeElement);\r\n }\r\n _contentArrangeElement.css(contentArrangeElementCSS);\r\n }\r\n _contentElement.css(contentElementCSS);\r\n }\r\n\r\n var viewportElementCSS = {};\r\n var paddingElementCSS = {};\r\n var setViewportCSS;\r\n if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) {\r\n viewportElementCSS[isRTLRight] = _strEmpty;\r\n setViewportCSS = function (horizontal) {\r\n var scrollbarVars = getScrollbarVars(horizontal);\r\n var scrollbarVarsInverted = getScrollbarVars(!horizontal);\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var strDirection = horizontal ? _strBottom : isRTLLeft;\r\n\r\n var reset = function () {\r\n viewportElementCSS[strDirection] = _strEmpty;\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = 0;\r\n };\r\n if (hasOverflow[xy] && hideOverflow[xy + 's']) {\r\n viewportElementCSS[strOverflow + XY] = _strScroll;\r\n if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) {\r\n reset();\r\n }\r\n else {\r\n viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]);\r\n _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0;\r\n }\r\n } else {\r\n viewportElementCSS[strOverflow + XY] = _strEmpty;\r\n reset();\r\n }\r\n };\r\n setViewportCSS(true);\r\n setViewportCSS(false);\r\n\r\n // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), \r\n // make viewport element greater in size (Firefox hide Scrollbars fix)\r\n // because firefox starts hiding scrollbars on too small elements\r\n // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly\r\n // https://bugzilla.mozilla.org/show_bug.cgi?id=292284\r\n if (!_nativeScrollbarStyling\r\n && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y)\r\n && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) {\r\n viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x;\r\n viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x;\r\n\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y;\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y;\r\n }\r\n else {\r\n viewportElementCSS[_strPaddingMinus + _strTop] =\r\n viewportElementCSS[_strMarginMinus + _strTop] =\r\n viewportElementCSS[_strPaddingMinus + isRTLRight] =\r\n viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty;\r\n }\r\n viewportElementCSS[_strPaddingMinus + isRTLLeft] =\r\n viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty;\r\n\r\n //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible\r\n if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) {\r\n //only hide if is Textarea\r\n if (_isTextarea && hideOverflowForceTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = strHidden;\r\n }\r\n }\r\n else {\r\n if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) {\r\n //only un-hide if Textarea\r\n if (_isTextarea) {\r\n paddingElementCSS[strOverflowX] =\r\n paddingElementCSS[strOverflowY] = _strEmpty;\r\n }\r\n viewportElementCSS[strOverflowX] =\r\n viewportElementCSS[strOverflowY] = strVisible;\r\n }\r\n }\r\n\r\n _paddingElement.css(paddingElementCSS);\r\n _viewportElement.css(viewportElementCSS);\r\n viewportElementCSS = {};\r\n\r\n //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions\r\n if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) {\r\n var elementStyle = _contentElementNative[LEXICON.s];\r\n var dump;\r\n elementStyle.webkitTransform = 'scale(1)';\r\n elementStyle.display = 'run-in';\r\n dump = _contentElementNative[LEXICON.oH];\r\n elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify\r\n elementStyle.webkitTransform = _strEmpty;\r\n }\r\n /*\r\n //force hard redraw in webkit if native overlaid scrollbars shall appear\r\n if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) {\r\n _hostElement.hide();\r\n var dump = _hostElementNative[LEXICON.oH];\r\n _hostElement.show();\r\n }\r\n */\r\n }\r\n\r\n //change to direction RTL and width auto Bugfix in Webkit\r\n //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left\r\n contentElementCSS = {};\r\n if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) {\r\n if (_isRTL && widthAuto) {\r\n var floatTmp = _contentElement.css(_strFloat);\r\n var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left);\r\n _contentElement.css(_strFloat, floatTmp);\r\n var posLeftWithFloat = MATH.round(_contentElement.position().left);\r\n\r\n if (posLeftWithoutFloat !== posLeftWithFloat)\r\n contentElementCSS[_strLeft] = posLeftWithoutFloat;\r\n }\r\n else {\r\n contentElementCSS[_strLeft] = _strEmpty;\r\n }\r\n }\r\n _contentElement.css(contentElementCSS);\r\n\r\n //handle scroll position\r\n if (_isTextarea && contentSizeChanged) {\r\n var textareaInfo = getTextareaInfo();\r\n if (textareaInfo) {\r\n var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows;\r\n var cursorRow = textareaInfo._cursorRow;\r\n var cursorCol = textareaInfo._cursorColumn;\r\n var widestRow = textareaInfo._widestRow;\r\n var lastRow = textareaInfo._rows;\r\n var lastCol = textareaInfo._columns;\r\n var cursorPos = textareaInfo._cursorPosition;\r\n var cursorMax = textareaInfo._cursorMax;\r\n var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus);\r\n var textareaScrollAmount = {\r\n x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1,\r\n y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1\r\n };\r\n currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset.\r\n currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y;\r\n }\r\n _textareaInfoCache = textareaInfo;\r\n }\r\n if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache)\r\n currScroll.x += _contentBorderSize.w || 0;\r\n if (widthAuto)\r\n _hostElement[_strScrollLeft](0);\r\n if (heightAuto)\r\n _hostElement[_strScrollTop](0);\r\n _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y);\r\n\r\n //scrollbars management:\r\n var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v';\r\n var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h';\r\n var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a';\r\n var refreshScrollbarsVisibility = function (showX, showY) {\r\n showY = showY === undefined ? showX : showY;\r\n refreshScrollbarAppearance(true, showX, canScroll.x)\r\n refreshScrollbarAppearance(false, showY, canScroll.y)\r\n };\r\n\r\n //manage class name which indicates scrollable overflow\r\n addRemoveClass(_hostElement, _classNameHostOverflow, hideOverflow.x || hideOverflow.y);\r\n addRemoveClass(_hostElement, _classNameHostOverflowX, hideOverflow.x);\r\n addRemoveClass(_hostElement, _classNameHostOverflowY, hideOverflow.y);\r\n\r\n //add or remove rtl class name for styling purposes except when its body, then the scrollbar stays\r\n if (cssDirectionChanged && !_isBody) {\r\n addRemoveClass(_hostElement, _classNameHostRTL, _isRTL);\r\n }\r\n\r\n //manage the resize feature (CSS3 resize \"polyfill\" for this plugin)\r\n if (_isBody)\r\n addClass(_hostElement, _classNameHostResizeDisabled);\r\n if (resizeChanged) {\r\n addRemoveClass(_hostElement, _classNameHostResizeDisabled, _resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResize, !_resizeNone);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB, _resizeBoth);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH, _resizeHorizontal);\r\n addRemoveClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV, _resizeVertical);\r\n }\r\n\r\n //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name)\r\n if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) {\r\n if (ignoreOverlayScrollbarHiding) {\r\n if (ignoreOverlayScrollbarHidingChanged) {\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n if (ignoreOverlayScrollbarHiding) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n }\r\n else if (scrollbarsVisibilityAuto) {\r\n refreshScrollbarsVisibility(canScroll.x, canScroll.y);\r\n }\r\n else if (scrollbarsVisibilityVisible) {\r\n refreshScrollbarsVisibility(true);\r\n }\r\n else if (scrollbarsVisibilityHidden) {\r\n refreshScrollbarsVisibility(false);\r\n }\r\n }\r\n\r\n //manage the scrollbars auto hide feature (auto hide them after specific actions)\r\n if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) {\r\n setupHostMouseTouchEvents(!_scrollbarsAutoHideLeave && !_scrollbarsAutoHideMove);\r\n refreshScrollbarsAutoHide(_scrollbarsAutoHideNever, !_scrollbarsAutoHideNever);\r\n }\r\n\r\n //manage scrollbars handle length & offset - don't remove!\r\n if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) {\r\n refreshScrollbarHandleLength(true);\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleLength(false);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n\r\n //manage interactivity\r\n if (scrollbarsClickScrollingChanged)\r\n refreshScrollbarsInteractive(true, scrollbarsClickScrolling);\r\n if (scrollbarsDragScrollingChanged)\r\n refreshScrollbarsInteractive(false, scrollbarsDragScrolling);\r\n\r\n //callbacks:\r\n dispatchCallback('onDirectionChanged', {\r\n isRTL: _isRTL,\r\n dir: cssDirection\r\n }, cssDirectionChanged);\r\n dispatchCallback('onHostSizeChanged', {\r\n width: _hostSizeCache.w,\r\n height: _hostSizeCache.h\r\n }, hostSizeChanged);\r\n dispatchCallback('onContentSizeChanged', {\r\n width: _contentScrollSizeCache.w,\r\n height: _contentScrollSizeCache.h\r\n }, contentSizeChanged);\r\n dispatchCallback('onOverflowChanged', {\r\n x: hasOverflow.x,\r\n y: hasOverflow.y,\r\n xScrollable: hideOverflow.xs,\r\n yScrollable: hideOverflow.ys,\r\n clipped: hideOverflow.x || hideOverflow.y\r\n }, hasOverflow.c || hideOverflow.c);\r\n dispatchCallback('onOverflowAmountChanged', {\r\n x: overflowAmount.x,\r\n y: overflowAmount.y\r\n }, overflowAmount.c);\r\n }\r\n\r\n //fix body min size\r\n if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) {\r\n //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size.\r\n if (!_bodyMinSizeCache.f)\r\n bodyMinSizeChanged();\r\n if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x)\r\n _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y);\r\n if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y)\r\n _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x);\r\n _bodyMinSizeCache.c = false;\r\n }\r\n\r\n if (_initialized && changedOptions.updateOnLoad) {\r\n updateElementsOnLoad();\r\n }\r\n\r\n //freezeResizeObserver(_sizeObserverElement, false);\r\n //freezeResizeObserver(_sizeAutoObserverElement, false);\r\n\r\n dispatchCallback('onUpdated', { forced: force });\r\n }\r\n\r\n /**\r\n * Updates the found elements of which the load event shall be handled.\r\n */\r\n function updateElementsOnLoad() {\r\n if (!_isTextarea) {\r\n eachUpdateOnLoad(function (i, updateOnLoadSelector) {\r\n _contentElement.find(updateOnLoadSelector).each(function (i, el) {\r\n // if element doesn't have a updateOnLoadCallback applied\r\n if (COMPATIBILITY.inA(el, _updateOnLoadElms) < 0) {\r\n _updateOnLoadElms.push(el);\r\n FRAMEWORK(el)\r\n .off(_updateOnLoadEventName, updateOnLoadCallback)\r\n .on(_updateOnLoadEventName, updateOnLoadCallback);\r\n }\r\n });\r\n });\r\n }\r\n }\r\n\r\n //==== Options ====//\r\n\r\n /**\r\n * Sets new options but doesn't call the update method.\r\n * @param newOptions The object which contains the new options.\r\n * @returns {*} A object which contains the changed options.\r\n */\r\n function setOptions(newOptions) {\r\n var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions)\r\n\r\n _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default);\r\n _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared);\r\n\r\n return validatedOpts._prepared;\r\n }\r\n\r\n\r\n //==== Structure ====//\r\n\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n /**\r\n * Builds or destroys the wrapper and helper DOM elements.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupStructureDOM(destroy) {\r\n var strParent = 'parent';\r\n var classNameResizeObserverHost = 'os-resize-observer-host';\r\n var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit;\r\n var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty;\r\n var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs;\r\n var adoptAttrsMap = {};\r\n var applyAdoptedAttrs = function () {\r\n var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement;\r\n each(adoptAttrsMap, function (key, value) {\r\n if (type(value) == TYPES.s) {\r\n if (key == LEXICON.c)\r\n applyAdoptedAttrsElm.addClass(value);\r\n else\r\n applyAdoptedAttrsElm.attr(key, value);\r\n }\r\n });\r\n };\r\n var hostElementClassNames = [\r\n _classNameHostElement,\r\n _classNameHostElementForeign,\r\n _classNameHostTextareaElement,\r\n _classNameHostResizeDisabled,\r\n _classNameHostRTL,\r\n _classNameHostScrollbarHorizontalHidden,\r\n _classNameHostScrollbarVerticalHidden,\r\n _classNameHostTransition,\r\n _classNameHostScrolling,\r\n _classNameHostOverflow,\r\n _classNameHostOverflowX,\r\n _classNameHostOverflowY,\r\n _classNameThemeNone,\r\n _classNameTextareaElement,\r\n _classNameTextInherit,\r\n _classNameCache].join(_strSpace);\r\n var hostElementCSS = {};\r\n\r\n //get host element as first element, because that's the most upper element and required for the other elements\r\n _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement);\r\n _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass);\r\n _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass);\r\n _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass);\r\n _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost);\r\n _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined);\r\n\r\n //add this class to workaround class changing issues with UI frameworks especially Vue\r\n if (_domExists)\r\n addClass(_hostElement, _classNameHostElementForeign);\r\n\r\n //on destroy, remove all generated class names from the host element before collecting the adopted attributes \r\n //to prevent adopting generated class names\r\n if (destroy)\r\n removeClass(_hostElement, hostElementClassNames);\r\n\r\n //collect all adopted attributes\r\n adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs;\r\n if (COMPATIBILITY.isA(adoptAttrs) && _isTextarea) {\r\n each(adoptAttrs, function (i, v) {\r\n if (type(v) == TYPES.s) {\r\n adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v);\r\n }\r\n });\r\n }\r\n\r\n if (!destroy) {\r\n if (_isTextarea) {\r\n if (!_currentPreparedOptions.sizeAutoCapable) {\r\n hostElementCSS[_strWidth] = _targetElement.css(_strWidth);\r\n hostElementCSS[_strHeight] = _targetElement.css(_strHeight);\r\n }\r\n\r\n if (!_domExists)\r\n _targetElement.addClass(_classNameTextInherit).wrap(_hostElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _hostElement = _targetElement[strParent]().css(hostElementCSS);\r\n }\r\n\r\n if (!_domExists) {\r\n //add the correct class to the target element\r\n addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement);\r\n\r\n //wrap the content into the generated elements to create the required DOM\r\n _hostElement.wrapInner(_contentElement)\r\n .wrapInner(_viewportElement)\r\n .wrapInner(_paddingElement)\r\n .prepend(_sizeObserverElement);\r\n\r\n //jQuery clones elements in wrap functions, so we have to select them again\r\n _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement);\r\n _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement);\r\n _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement);\r\n\r\n if (_isTextarea) {\r\n _contentElement.prepend(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_nativeScrollbarStyling)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible);\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)\r\n addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid);\r\n if (_isBody)\r\n addClass(_htmlElement, _classNameHTMLElement);\r\n\r\n _sizeObserverElementNative = _sizeObserverElement[0];\r\n _hostElementNative = _hostElement[0];\r\n _paddingElementNative = _paddingElement[0];\r\n _viewportElementNative = _viewportElement[0];\r\n _contentElementNative = _contentElement[0];\r\n\r\n updateViewportAttrsFromTarget();\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n //clear size observer\r\n _sizeObserverElement.children().remove();\r\n\r\n //remove the style property and classes from already generated elements\r\n each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) {\r\n if (elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n });\r\n\r\n //add classes to the host element which was removed previously to match the expected DOM\r\n addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement);\r\n }\r\n else {\r\n //remove size observer\r\n remove(_sizeObserverElement);\r\n\r\n //unwrap the content to restore DOM\r\n _contentElement.contents()\r\n .unwrap()\r\n .unwrap()\r\n .unwrap();\r\n\r\n if (_isTextarea) {\r\n _targetElement.unwrap();\r\n remove(_hostElement);\r\n remove(_textareaCoverElement);\r\n applyAdoptedAttrs();\r\n }\r\n }\r\n\r\n if (_isTextarea)\r\n _targetElement.removeAttr(LEXICON.s);\r\n\r\n if (_isBody)\r\n removeClass(_htmlElement, _classNameHTMLElement);\r\n }\r\n }\r\n\r\n /**\r\n * Adds or removes all wrapper elements interactivity events.\r\n * @param destroy Indicates whether the Events shall be added or removed.\r\n */\r\n function setupStructureEvents() {\r\n var textareaKeyDownRestrictedKeyCodes = [\r\n 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12\r\n 33, 34, //page up, page down\r\n 37, 38, 39, 40, //left, up, right, down arrows\r\n 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock\r\n ];\r\n var textareaKeyDownKeyCodesList = [];\r\n var textareaUpdateIntervalID;\r\n var scrollStopTimeoutId;\r\n var scrollStopDelay = 175;\r\n var strFocus = 'focus';\r\n\r\n function updateTextarea(doClearInterval) {\r\n textareaUpdate();\r\n _base.update(_strAuto);\r\n if (doClearInterval && _autoUpdateRecommended)\r\n clearInterval(textareaUpdateIntervalID);\r\n }\r\n function textareaOnScroll(event) {\r\n _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0);\r\n _targetElement[_strScrollTop](0);\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n return false;\r\n }\r\n function textareaOnDrop(event) {\r\n setTimeout(function () {\r\n if (!_destroyed)\r\n updateTextarea();\r\n }, 50);\r\n }\r\n function textareaOnFocus() {\r\n _textareaHasFocus = true;\r\n addClass(_hostElement, strFocus);\r\n }\r\n function textareaOnFocusout() {\r\n _textareaHasFocus = false;\r\n textareaKeyDownKeyCodesList = [];\r\n removeClass(_hostElement, strFocus);\r\n updateTextarea(true);\r\n }\r\n function textareaOnKeyDown(event) {\r\n var keyCode = event.keyCode;\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l]) {\r\n updateTextarea();\r\n textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60);\r\n }\r\n if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0)\r\n textareaKeyDownKeyCodesList.push(keyCode);\r\n }\r\n }\r\n function textareaOnKeyUp(event) {\r\n var keyCode = event.keyCode;\r\n var index = inArray(keyCode, textareaKeyDownKeyCodesList);\r\n\r\n if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) {\r\n if (index > -1)\r\n textareaKeyDownKeyCodesList.splice(index, 1);\r\n if (!textareaKeyDownKeyCodesList[LEXICON.l])\r\n updateTextarea(true);\r\n }\r\n }\r\n function contentOnTransitionEnd(event) {\r\n if (_autoUpdateCache === true)\r\n return;\r\n event = event.originalEvent || event;\r\n if (isSizeAffectingCSSProperty(event.propertyName))\r\n _base.update(_strAuto);\r\n }\r\n function viewportOnScroll(event) {\r\n if (!_sleeping) {\r\n if (scrollStopTimeoutId !== undefined)\r\n clearTimeout(scrollStopTimeoutId);\r\n else {\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n addClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStart', event);\r\n }\r\n\r\n //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset\r\n //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point\r\n //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove\r\n if (!_scrollbarsHandlesDefineScrollPos) {\r\n refreshScrollbarHandleOffset(true);\r\n refreshScrollbarHandleOffset(false);\r\n }\r\n dispatchCallback('onScroll', event);\r\n\r\n scrollStopTimeoutId = setTimeout(function () {\r\n if (!_destroyed) {\r\n //OnScrollStop:\r\n clearTimeout(scrollStopTimeoutId);\r\n scrollStopTimeoutId = undefined;\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n removeClass(_hostElement, _classNameHostScrolling);\r\n\r\n dispatchCallback('onScrollStop', event);\r\n }\r\n }, scrollStopDelay);\r\n }\r\n }\r\n\r\n\r\n if (_isTextarea) {\r\n if (_msieVersion > 9 || !_autoUpdateRecommended) {\r\n addDestroyEventListener(_targetElement, 'input', updateTextarea);\r\n }\r\n else {\r\n addDestroyEventListener(_targetElement,\r\n [_strKeyDownEvent, _strKeyUpEvent],\r\n [textareaOnKeyDown, textareaOnKeyUp]);\r\n }\r\n\r\n addDestroyEventListener(_targetElement,\r\n [_strScroll, 'drop', strFocus, strFocus + 'out'],\r\n [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]);\r\n }\r\n else {\r\n addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd);\r\n }\r\n addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true);\r\n }\r\n\r\n\r\n //==== Scrollbars ====//\r\n\r\n /**\r\n * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle)\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarsDOM(destroy) {\r\n var selectOrGenerateScrollbarDOM = function (isHorizontal) {\r\n var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical;\r\n var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true);\r\n var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar);\r\n var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar);\r\n\r\n if (!_domExists && !destroy) {\r\n scrollbar.append(track);\r\n track.append(handle);\r\n }\r\n\r\n return {\r\n _scrollbar: scrollbar,\r\n _track: track,\r\n _handle: handle\r\n };\r\n };\r\n function resetScrollbarDOM(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbar = scrollbarVars._scrollbar;\r\n var track = scrollbarVars._track;\r\n var handle = scrollbarVars._handle;\r\n\r\n if (_domExists && _initialized) {\r\n each([scrollbar, track, handle], function (i, elm) {\r\n removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n });\r\n }\r\n else {\r\n remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar);\r\n }\r\n }\r\n var horizontalElements;\r\n var verticalElements;\r\n\r\n if (!destroy) {\r\n horizontalElements = selectOrGenerateScrollbarDOM(true);\r\n verticalElements = selectOrGenerateScrollbarDOM();\r\n\r\n _scrollbarHorizontalElement = horizontalElements._scrollbar;\r\n _scrollbarHorizontalTrackElement = horizontalElements._track;\r\n _scrollbarHorizontalHandleElement = horizontalElements._handle;\r\n _scrollbarVerticalElement = verticalElements._scrollbar;\r\n _scrollbarVerticalTrackElement = verticalElements._track;\r\n _scrollbarVerticalHandleElement = verticalElements._handle;\r\n\r\n if (!_domExists) {\r\n _paddingElement.after(_scrollbarVerticalElement);\r\n _paddingElement.after(_scrollbarHorizontalElement);\r\n }\r\n }\r\n else {\r\n resetScrollbarDOM(true);\r\n resetScrollbarDOM();\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling)\r\n * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar.\r\n */\r\n function setupScrollbarEvents(isHorizontal) {\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var xy = scrollbarVars._x_y;\r\n var XY = scrollbarVars._X_Y;\r\n var scroll = _strScroll + scrollbarVars._Left_Top;\r\n var strActive = 'active';\r\n var strSnapHandle = 'snapHandle';\r\n var strClickEvent = 'click';\r\n var scrollDurationFactor = 1;\r\n var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl\r\n var trackTimeout;\r\n var mouseDownScroll;\r\n var mouseDownOffset;\r\n var mouseDownInvertedScale;\r\n\r\n function getPointerPosition(event) {\r\n return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames.\r\n }\r\n function getPreparedScrollbarsOption(name) {\r\n return _currentPreparedOptions.scrollbars[name];\r\n }\r\n function increaseTrackScrollAmount() {\r\n scrollDurationFactor = 0.5;\r\n }\r\n function decreaseTrackScrollAmount() {\r\n scrollDurationFactor = 1;\r\n }\r\n function stopClickEventPropagation(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function documentKeyDown(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n increaseTrackScrollAmount();\r\n }\r\n function documentKeyUp(event) {\r\n if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1)\r\n decreaseTrackScrollAmount();\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale;\r\n var scrollDeltaPercent = scrollRaw / (trackLength - handleLength);\r\n var scrollDelta = (scrollRange * scrollDeltaPercent);\r\n scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.i)\r\n scrollDelta *= -1;\r\n\r\n _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta));\r\n\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta);\r\n\r\n if (!_supportPassiveEvents)\r\n COMPATIBILITY.prvD(event);\r\n }\r\n else\r\n documentMouseTouchUp(event);\r\n }\r\n function documentMouseTouchUp(event) {\r\n event = event || event.originalEvent;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart],\r\n true);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, true, { _capture: true });\r\n });\r\n \r\n \r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, true);\r\n\r\n _scrollbarsHandlesDefineScrollPos = false;\r\n removeClass(_bodyElement, _classNameDragging);\r\n removeClass(scrollbarVars._handle, strActive);\r\n removeClass(scrollbarVars._track, strActive);\r\n removeClass(scrollbarVars._scrollbar, strActive);\r\n\r\n mouseDownScroll = undefined;\r\n mouseDownOffset = undefined;\r\n mouseDownInvertedScale = 1;\r\n\r\n decreaseTrackScrollAmount();\r\n\r\n if (trackTimeout !== undefined) {\r\n _base.scrollStop();\r\n clearTimeout(trackTimeout);\r\n trackTimeout = undefined;\r\n }\r\n\r\n if (event) {\r\n var rect = _hostElementNative[LEXICON.bCR]();\r\n var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom;\r\n\r\n //if mouse is outside host element\r\n if (!mouseInsideHost)\r\n hostOnMouseLeave();\r\n\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n }\r\n function onHandleMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event))\r\n onHandleMouseTouchDownAction(event);\r\n }\r\n function onHandleMouseTouchDownAction(event) {\r\n mouseDownScroll = _viewportElement[scroll]();\r\n mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll;\r\n if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL)\r\n mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll;\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = getPointerPosition(event);\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._handle, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent],\r\n [documentDragMove, documentMouseTouchUp, documentOnSelectStart]);\r\n COMPATIBILITY.rAF()(function() {\r\n setupResponsiveEventListener(_documentElement, strClickEvent, stopClickEventPropagation, false, { _capture: true });\r\n });\r\n \r\n\r\n if (_msieVersion || !_documentMixed)\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n function onTrackMouseTouchDown(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var handleToViewportRatio = scrollbarVars._info._handleLength / Math.round(MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]) * scrollbarVars._info._trackLength);\r\n var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h] * handleToViewportRatio);\r\n var scrollBaseDuration = 270 * handleToViewportRatio;\r\n var scrollFirstIterationDelay = 400 * handleToViewportRatio;\r\n var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top];\r\n var ctrlKey = event.ctrlKey;\r\n var instantScroll = event.shiftKey;\r\n var instantScrollTransition = instantScroll && ctrlKey;\r\n var isFirstIteration = true;\r\n var easing = 'linear';\r\n var decreaseScroll;\r\n var finishedCondition;\r\n var scrollActionFinsished = function (transition) {\r\n if (_scrollbarsHandlesDefineScrollPos)\r\n refreshScrollbarHandleOffset(isHorizontal, transition);\r\n };\r\n var scrollActionInstantFinished = function () {\r\n scrollActionFinsished();\r\n onHandleMouseTouchDownAction(event);\r\n };\r\n var scrollAction = function () {\r\n if (!_destroyed) {\r\n var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale;\r\n var handleOffset = scrollbarVarsInfo._handleOffset;\r\n var trackLength = scrollbarVarsInfo._trackLength;\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var scrollRange = scrollbarVarsInfo._maxScroll;\r\n var currScroll = scrollbarVarsInfo._currentScroll;\r\n var scrollDuration = scrollBaseDuration * scrollDurationFactor;\r\n var timeoutDelay = isFirstIteration ? MATH.max(scrollFirstIterationDelay, scrollDuration) : scrollDuration;\r\n var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent\r\n var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache);\r\n var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset;\r\n var scrollObj = {};\r\n var animationObj = {\r\n easing: easing,\r\n step: function (now) {\r\n if (_scrollbarsHandlesDefineScrollPos) {\r\n _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340\r\n refreshScrollbarHandleOffset(isHorizontal, now);\r\n }\r\n }\r\n };\r\n instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0;\r\n instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n\r\n //_base.scrollStop();\r\n\r\n if (instantScroll) {\r\n _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position\r\n if (instantScrollTransition) {\r\n //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position\r\n //and the animation stops at the correct point\r\n instantScrollPosition = _viewportElement[scroll]();\r\n //scroll back to the position before instant scrolling so animation can be performed\r\n _viewportElement[scroll](currScroll);\r\n\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition;\r\n instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition;\r\n\r\n scrollObj[xy] = instantScrollPosition;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: 130,\r\n complete: scrollActionInstantFinished\r\n }));\r\n }\r\n else\r\n scrollActionInstantFinished();\r\n }\r\n else {\r\n decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll;\r\n finishedCondition = rtlIsNormal\r\n ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset)\r\n : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset);\r\n\r\n if (finishedCondition) {\r\n clearTimeout(trackTimeout);\r\n _base.scrollStop();\r\n trackTimeout = undefined;\r\n scrollActionFinsished(true);\r\n }\r\n else {\r\n trackTimeout = setTimeout(scrollAction, timeoutDelay);\r\n\r\n scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance;\r\n _base.scroll(scrollObj, extendDeep(animationObj, {\r\n duration: scrollDuration\r\n }));\r\n }\r\n isFirstIteration = false;\r\n }\r\n }\r\n };\r\n if (ctrlKey)\r\n increaseTrackScrollAmount();\r\n\r\n mouseDownInvertedScale = getHostElementInvertedScale()[xy];\r\n mouseDownOffset = COMPATIBILITY.page(event)[xy];\r\n\r\n _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle);\r\n addClass(_bodyElement, _classNameDragging);\r\n addClass(scrollbarVars._track, strActive);\r\n addClass(scrollbarVars._scrollbar, strActive);\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent],\r\n [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]);\r\n\r\n scrollAction();\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n }\r\n function onTrackMouseTouchEnter(event) {\r\n //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is \"scroll\" or \"move\".\r\n _scrollbarsHandleHovered = true;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(true);\r\n }\r\n function onTrackMouseTouchLeave(event) {\r\n _scrollbarsHandleHovered = false;\r\n if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove)\r\n refreshScrollbarsAutoHide(false);\r\n }\r\n function onScrollbarMouseTouchDown(event) {\r\n COMPATIBILITY.stpP(event);\r\n }\r\n\r\n addDestroyEventListener(scrollbarVars._handle,\r\n _strMouseTouchDownEvent,\r\n onHandleMouseTouchDown);\r\n addDestroyEventListener(scrollbarVars._track,\r\n [_strMouseTouchDownEvent, _strMouseEnter, _strMouseLeave],\r\n [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]);\r\n addDestroyEventListener(scrollbarVars._scrollbar,\r\n _strMouseTouchDownEvent,\r\n onScrollbarMouseTouchDown);\r\n\r\n if (_supportTransition) {\r\n addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) {\r\n if (event.target !== scrollbarVars._scrollbar[0])\r\n return;\r\n refreshScrollbarHandleLength(isHorizontal);\r\n refreshScrollbarHandleOffset(isHorizontal);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not.\r\n * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target.\r\n * @param shallBeVisible True if the scrollbar shall be shown, false if hidden.\r\n * @param canScroll True if the scrollbar is scrollable, false otherwise.\r\n */\r\n function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) {\r\n var scrollbarHiddenClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden;\r\n var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement;\r\n\r\n addRemoveClass(_hostElement, scrollbarHiddenClassName, !shallBeVisible);\r\n addRemoveClass(scrollbarElement, _classNameScrollbarUnusable, !canScroll);\r\n }\r\n\r\n /**\r\n * Autoshows / autohides both scrollbars with.\r\n * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden.\r\n * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise.\r\n */\r\n function refreshScrollbarsAutoHide(shallBeVisible, delayfree) {\r\n clearTimeout(_scrollbarsAutoHideTimeoutId);\r\n if (shallBeVisible) {\r\n //if(_hasOverflowCache.x && _hideOverflowCache.xs)\r\n removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n //if(_hasOverflowCache.y && _hideOverflowCache.ys)\r\n removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n else {\r\n var anyActive;\r\n var strActive = 'active';\r\n var hide = function () {\r\n if (!_scrollbarsHandleHovered && !_destroyed) {\r\n anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden);\r\n if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave))\r\n addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden);\r\n }\r\n };\r\n if (_scrollbarsAutoHideDelay > 0 && delayfree !== true)\r\n _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay);\r\n else\r\n hide();\r\n }\r\n }\r\n\r\n /**\r\n * Refreshes the handle length of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n */\r\n function refreshScrollbarHandleLength(isHorizontal) {\r\n var handleCSS = {};\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var digit = 1000000;\r\n //get and apply intended handle length\r\n var handleRatio = MATH.min(1, _viewportSize[scrollbarVars._w_h] / _contentScrollSizeCache[scrollbarVars._w_h]);\r\n handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit\r\n\r\n if (!nativeOverlayScrollbarsAreActive())\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //measure the handle length to respect min & max length\r\n scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height];\r\n scrollbarVarsInfo._handleLengthRatio = handleRatio;\r\n }\r\n\r\n /**\r\n * Refreshes the handle offset of the given scrollbar.\r\n * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed.\r\n * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop)\r\n */\r\n function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) {\r\n var transition = type(scrollOrTransition) == TYPES.b;\r\n var transitionDuration = 250;\r\n var isRTLisHorizontal = _isRTL && isHorizontal;\r\n var scrollbarVars = getScrollbarVars(isHorizontal);\r\n var scrollbarVarsInfo = scrollbarVars._info;\r\n var strTranslateBrace = 'translate(';\r\n var strTransform = VENDORS._cssProperty('transform');\r\n var strTransition = VENDORS._cssProperty('transition');\r\n var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop]();\r\n var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition;\r\n\r\n //measure the handle length to respect min & max length\r\n var handleLength = scrollbarVarsInfo._handleLength;\r\n var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height];\r\n var handleTrackDiff = trackLength - handleLength;\r\n var handleCSS = {};\r\n var transformOffset;\r\n var translateValue;\r\n\r\n //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]'\r\n // because its a bit behind during the small delay when content size updates\r\n //(delay = mutationObserverContentLag, if its 0 then this var could be used)\r\n var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative\r\n var getScrollRatio = function (base) {\r\n return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll));\r\n };\r\n var getHandleOffset = function (scrollRatio) {\r\n var offset = handleTrackDiff * scrollRatio;\r\n offset = isNaN(offset) ? 0 : offset;\r\n offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset;\r\n offset = MATH.max(0, offset);\r\n return offset;\r\n };\r\n var scrollRatio = getScrollRatio(nativeScroll);\r\n var unsnappedScrollRatio = getScrollRatio(currentScroll);\r\n var handleOffset = getHandleOffset(unsnappedScrollRatio);\r\n var snappedHandleOffset = getHandleOffset(scrollRatio);\r\n\r\n scrollbarVarsInfo._maxScroll = maxScroll;\r\n scrollbarVarsInfo._currentScroll = nativeScroll;\r\n scrollbarVarsInfo._currentScrollRatio = scrollRatio;\r\n\r\n if (_supportTransform) {\r\n transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px\r\n //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in %\r\n translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)';\r\n\r\n handleCSS[strTransform] = translateValue;\r\n\r\n //apply or clear up transition\r\n if (_supportTransition)\r\n handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty;\r\n }\r\n else\r\n handleCSS[scrollbarVars._left_top] = handleOffset;\r\n\r\n\r\n //only apply css if offset has changed and overflow exists.\r\n if (!nativeOverlayScrollbarsAreActive()) {\r\n scrollbarVars._handle.css(handleCSS);\r\n\r\n //clear up transition\r\n if (_supportTransform && _supportTransition && transition) {\r\n scrollbarVars._handle.one(_strTransitionEndEvent, function () {\r\n if (!_destroyed)\r\n scrollbarVars._handle.css(strTransition, _strEmpty);\r\n });\r\n }\r\n }\r\n\r\n scrollbarVarsInfo._handleOffset = handleOffset;\r\n scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset;\r\n scrollbarVarsInfo._trackLength = trackLength;\r\n }\r\n\r\n /**\r\n * Refreshes the interactivity of the given scrollbar element.\r\n * @param isTrack True if the track element is the target, false if the handle element is the target.\r\n * @param value True for interactivity false for no interactivity.\r\n */\r\n function refreshScrollbarsInteractive(isTrack, value) {\r\n var action = value ? 'removeClass' : 'addClass';\r\n var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement;\r\n var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement;\r\n var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff;\r\n\r\n element1[action](className);\r\n element2[action](className);\r\n }\r\n\r\n /**\r\n * Returns a object which is used for fast access for specific variables.\r\n * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed.\r\n * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}}\r\n */\r\n function getScrollbarVars(isHorizontal) {\r\n return {\r\n _width_height: isHorizontal ? _strWidth : _strHeight,\r\n _Width_Height: isHorizontal ? 'Width' : 'Height',\r\n _left_top: isHorizontal ? _strLeft : _strTop,\r\n _Left_Top: isHorizontal ? 'Left' : 'Top',\r\n _x_y: isHorizontal ? _strX : _strY,\r\n _X_Y: isHorizontal ? 'X' : 'Y',\r\n _w_h: isHorizontal ? 'w' : 'h',\r\n _l_t: isHorizontal ? 'l' : 't',\r\n _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement,\r\n _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement,\r\n _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement,\r\n _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo\r\n };\r\n }\r\n\r\n\r\n //==== Scrollbar Corner ====//\r\n\r\n /**\r\n * Builds or destroys the scrollbar corner DOM element.\r\n * @param destroy Indicates whether the DOM shall be build or destroyed.\r\n */\r\n function setupScrollbarCornerDOM(destroy) {\r\n _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true);\r\n\r\n if (!destroy) {\r\n if (!_domExists) {\r\n _hostElement.append(_scrollbarCornerElement);\r\n }\r\n }\r\n else {\r\n if (_domExists && _initialized) {\r\n removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy);\r\n }\r\n else {\r\n remove(_scrollbarCornerElement);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes all scrollbar corner interactivity events.\r\n */\r\n function setupScrollbarCornerEvents() {\r\n var insideIFrame = _windowElementNative.top !== _windowElementNative;\r\n var mouseDownPosition = {};\r\n var mouseDownSize = {};\r\n var mouseDownInvertedScale = {};\r\n var reconnectMutationObserver;\r\n\r\n function documentDragMove(event) {\r\n if (onMouseTouchDownContinue(event)) {\r\n var pageOffset = getCoordinates(event);\r\n var hostElementCSS = {};\r\n if (_resizeHorizontal || _resizeBoth)\r\n hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x);\r\n if (_resizeVertical || _resizeBoth)\r\n hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y);\r\n _hostElement.css(hostElementCSS);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n else {\r\n documentMouseTouchUp(event);\r\n }\r\n }\r\n function documentMouseTouchUp(event) {\r\n var eventIsTrusted = event !== undefined;\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp],\r\n true);\r\n\r\n removeClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.releaseCapture)\r\n _scrollbarCornerElement.releaseCapture();\r\n\r\n if (eventIsTrusted) {\r\n if (reconnectMutationObserver)\r\n connectMutationObservers();\r\n _base.update(_strAuto);\r\n }\r\n reconnectMutationObserver = false;\r\n }\r\n function onMouseTouchDownContinue(event) {\r\n var originalEvent = event.originalEvent || event;\r\n var isTouchEvent = originalEvent.touches !== undefined;\r\n return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent;\r\n }\r\n function getCoordinates(event) {\r\n return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event);\r\n }\r\n\r\n addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) {\r\n if (onMouseTouchDownContinue(event) && !_resizeNone) {\r\n if (_mutationObserversConnected) {\r\n reconnectMutationObserver = true;\r\n disconnectMutationObservers();\r\n }\r\n\r\n mouseDownPosition = getCoordinates(event);\r\n\r\n mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0);\r\n mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0);\r\n mouseDownInvertedScale = getHostElementInvertedScale();\r\n\r\n setupResponsiveEventListener(_documentElement,\r\n [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent],\r\n [documentOnSelectStart, documentDragMove, documentMouseTouchUp]);\r\n\r\n addClass(_bodyElement, _classNameDragging);\r\n if (_scrollbarCornerElement.setCapture)\r\n _scrollbarCornerElement.setCapture();\r\n\r\n COMPATIBILITY.prvD(event);\r\n COMPATIBILITY.stpP(event);\r\n }\r\n });\r\n }\r\n\r\n\r\n //==== Utils ====//\r\n\r\n /**\r\n * Calls the callback with the given name. The Context of this callback is always _base (this).\r\n * @param name The name of the target which shall be called.\r\n * @param args The args with which the callback shall be called.\r\n * @param dependent Boolean which decides whether the callback shall be fired, undefined is like a \"true\" value.\r\n */\r\n function dispatchCallback(name, args, dependent) {\r\n if (dependent === false)\r\n return;\r\n if (_initialized) {\r\n var callback = _currentPreparedOptions.callbacks[name];\r\n var extensionOnName = name;\r\n var ext;\r\n\r\n if (extensionOnName.substr(0, 2) === 'on')\r\n extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3);\r\n\r\n if (type(callback) == TYPES.f)\r\n callback.call(_base, args);\r\n\r\n each(_extensions, function () {\r\n ext = this;\r\n if (type(ext.on) == TYPES.f)\r\n ext.on(extensionOnName, args);\r\n });\r\n }\r\n else if (!_destroyed)\r\n _callbacksInitQeueue.push({ n: name, a: args });\r\n }\r\n\r\n /**\r\n * Sets the \"top, right, bottom, left\" properties, with a given prefix, of the given css object.\r\n * @param targetCSSObject The css object to which the values shall be applied.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param values A array of values which shall be applied to the \"top, right, bottom, left\" -properties. The array order is [top, right, bottom, left].\r\n * If this argument is undefined the value '' (empty string) will be applied to all properties.\r\n */\r\n function setTopRightBottomLeft(targetCSSObject, prefix, values) {\r\n prefix = prefix || _strEmpty;\r\n values = values || [_strEmpty, _strEmpty, _strEmpty, _strEmpty];\r\n\r\n targetCSSObject[prefix + _strTop] = values[0];\r\n targetCSSObject[prefix + _strRight] = values[1];\r\n targetCSSObject[prefix + _strBottom] = values[2];\r\n targetCSSObject[prefix + _strLeft] = values[3];\r\n }\r\n\r\n /**\r\n * Gets the \"top, right, bottom, left\" CSS properties of the CSS property with the given prefix from the host element.\r\n * @param prefix The prefix of the \"top, right, bottom, left\" css properties. (example: 'padding-' is a valid prefix)\r\n * @param suffix The suffix of the \"top, right, bottom, left\" css properties. (example: 'border-' is a valid prefix with '-width' is a valid suffix)\r\n * @param zeroX True if the x axis shall be 0.\r\n * @param zeroY True if the y axis shall be 0.\r\n * @returns {{}} The object which contains the numbers of the read CSS properties.\r\n */\r\n function getTopRightBottomLeftHost(prefix, suffix, zeroX, zeroY) {\r\n suffix = suffix || _strEmpty;\r\n prefix = prefix || _strEmpty;\r\n return {\r\n t: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strTop + suffix)),\r\n r: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strRight + suffix)),\r\n b: zeroY ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strBottom + suffix)),\r\n l: zeroX ? 0 : parseToZeroOrNumber(_hostElement.css(prefix + _strLeft + suffix))\r\n };\r\n }\r\n\r\n /**\r\n * Returns the computed CSS transition string from the given element.\r\n * @param element The element from which the transition string shall be returned.\r\n * @returns {string} The CSS transition string from the given element.\r\n */\r\n function getCSSTransitionString(element) {\r\n var transitionStr = VENDORS._cssProperty('transition');\r\n var assembledValue = element.css(transitionStr);\r\n if (assembledValue)\r\n return assembledValue;\r\n var regExpString = '\\\\s*(' + '([^,(]+(\\\\(.+?\\\\))?)+' + ')[\\\\s,]*';\r\n var regExpMain = new RegExp(regExpString);\r\n var regExpValidate = new RegExp('^(' + regExpString + ')+$');\r\n var properties = 'property duration timing-function delay'.split(' ');\r\n var result = [];\r\n var strResult;\r\n var valueArray;\r\n var i = 0;\r\n var j;\r\n var splitCssStyleByComma = function (str) {\r\n strResult = [];\r\n if (!str.match(regExpValidate))\r\n return str;\r\n while (str.match(regExpMain)) {\r\n strResult.push(RegExp.$1);\r\n str = str.replace(regExpMain, _strEmpty);\r\n }\r\n\r\n return strResult;\r\n };\r\n for (; i < properties[LEXICON.l]; i++) {\r\n valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i]));\r\n for (j = 0; j < valueArray[LEXICON.l]; j++)\r\n result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j];\r\n }\r\n return result.join(', ');\r\n }\r\n\r\n /**\r\n * Generates a Regular Expression which matches with a string which starts with 'os-host'.\r\n * @param {boolean} withCurrClassNameOption The Regular Expression also matches if the string is the current ClassName option (multiple values splitted by space possible).\r\n * @param {boolean} withOldClassNameOption The Regular Expression also matches if the string is the old ClassName option (multiple values splitted by space possible).\r\n */\r\n function createHostClassNameRegExp(withCurrClassNameOption, withOldClassNameOption) {\r\n var i;\r\n var split;\r\n var appendix;\r\n var appendClasses = function (classes, condition) {\r\n appendix = '';\r\n if (condition && typeof classes == TYPES.s) {\r\n split = classes.split(_strSpace);\r\n for (i = 0; i < split[LEXICON.l]; i++)\r\n appendix += '|' + split[i] + '$';\r\n // split[i].replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') for escaping regex characters\r\n }\r\n return appendix;\r\n };\r\n\r\n return new RegExp(\r\n '(^' + _classNameHostElement + '([-_].+|)$)' +\r\n appendClasses(_classNameCache, withCurrClassNameOption) +\r\n appendClasses(_oldClassName, withOldClassNameOption), 'g');\r\n }\r\n\r\n /**\r\n * Calculates the host-elements inverted scale. (invertedScale = 1 / scale)\r\n * @returns {{x: number, y: number}} The scale of the host-element.\r\n */\r\n function getHostElementInvertedScale() {\r\n var rect = _paddingElementNative[LEXICON.bCR]();\r\n return {\r\n x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1,\r\n y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1\r\n };\r\n }\r\n\r\n /**\r\n * Checks whether the given object is a HTMLElement.\r\n * @param o The object which shall be checked.\r\n * @returns {boolean} True the given object is a HTMLElement, false otherwise.\r\n */\r\n function isHTMLElement(o) {\r\n var strOwnerDocument = 'ownerDocument';\r\n var strHTMLElement = 'HTMLElement';\r\n var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window;\r\n return (\r\n typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2\r\n o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s\r\n );\r\n }\r\n\r\n /**\r\n * Compares 2 arrays and returns the differences between them as a array.\r\n * @param a1 The first array which shall be compared.\r\n * @param a2 The second array which shall be compared.\r\n * @returns {Array} The differences between the two arrays.\r\n */\r\n function getArrayDifferences(a1, a2) {\r\n var a = [];\r\n var diff = [];\r\n var i;\r\n var k;\r\n for (i = 0; i < a1.length; i++)\r\n a[a1[i]] = true;\r\n for (i = 0; i < a2.length; i++) {\r\n if (a[a2[i]])\r\n delete a[a2[i]];\r\n else\r\n a[a2[i]] = true;\r\n }\r\n for (k in a)\r\n diff.push(k);\r\n return diff;\r\n }\r\n\r\n /**\r\n * Returns Zero or the number to which the value can be parsed.\r\n * @param value The value which shall be parsed.\r\n * @param toFloat Indicates whether the number shall be parsed to a float.\r\n */\r\n function parseToZeroOrNumber(value, toFloat) {\r\n var num = toFloat ? parseFloat(value) : parseInt(value, 10);\r\n return isNaN(num) ? 0 : num;\r\n }\r\n\r\n /**\r\n * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it.\r\n * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported.\r\n */\r\n function getTextareaInfo() {\r\n //read needed values\r\n var textareaCursorPosition = _targetElementNative.selectionStart;\r\n if (textareaCursorPosition === undefined)\r\n return;\r\n\r\n var textareaValue = _targetElement.val();\r\n var textareaLength = textareaValue[LEXICON.l];\r\n var textareaRowSplit = textareaValue.split('\\n');\r\n var textareaLastRow = textareaRowSplit[LEXICON.l];\r\n var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\\n');\r\n var widestRow = 0;\r\n var textareaLastCol = 0;\r\n var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l];\r\n var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l];\r\n var rowCols;\r\n var i;\r\n\r\n //get widest Row and the last column of the textarea\r\n for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) {\r\n rowCols = textareaRowSplit[i][LEXICON.l];\r\n if (rowCols > textareaLastCol) {\r\n widestRow = i + 1;\r\n textareaLastCol = rowCols;\r\n }\r\n }\r\n\r\n return {\r\n _cursorRow: cursorRow, //cursorRow\r\n _cursorColumn: cursorCol, //cursorCol\r\n _rows: textareaLastRow, //rows\r\n _columns: textareaLastCol, //cols\r\n _widestRow: widestRow, //wRow\r\n _cursorPosition: textareaCursorPosition, //pos\r\n _cursorMax: textareaLength //max\r\n };\r\n }\r\n\r\n /**\r\n * Determines whether native overlay scrollbars are active.\r\n * @returns {boolean} True if native overlay scrollbars are active, false otherwise.\r\n */\r\n function nativeOverlayScrollbarsAreActive() {\r\n return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y));\r\n }\r\n\r\n /**\r\n * Gets the element which is used to measure the content size.\r\n * @returns {*} TextareaCover if target element is textarea else the ContentElement.\r\n */\r\n function getContentMeasureElement() {\r\n return _isTextarea ? _textareaCoverElement[0] : _contentElementNative;\r\n }\r\n\r\n /**\r\n * Generates a string which represents a HTML div with the given classes or attributes.\r\n * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as \"className\".)\r\n * @param content The content of the div as string.\r\n * @returns {string} The concated string which represents a HTML div and its content.\r\n */\r\n function generateDiv(classesOrAttrs, content) {\r\n return '<div ' + (classesOrAttrs ? type(classesOrAttrs) == TYPES.s ?\r\n 'class=\"' + classesOrAttrs + '\"' :\r\n (function () {\r\n var key;\r\n var attrs = _strEmpty;\r\n if (FRAMEWORK.isPlainObject(classesOrAttrs)) {\r\n for (key in classesOrAttrs)\r\n attrs += (key === 'c' ? 'class' : key) + '=\"' + classesOrAttrs[key] + '\" ';\r\n }\r\n return attrs;\r\n })() :\r\n _strEmpty) +\r\n '>' +\r\n (content || _strEmpty) +\r\n '</div>';\r\n }\r\n\r\n /**\r\n * Selects or generates a div with the given class attribute.\r\n * @param className The class names (divided by spaces) of the div which shall be selected or generated.\r\n * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement)\r\n * If its a boolean it decides whether only the children of the host element shall be selected.\r\n * @returns {*} The generated or selected element.\r\n */\r\n function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) {\r\n var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b;\r\n var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement);\r\n\r\n return (_domExists && !selectParent[LEXICON.l])\r\n ? null\r\n : _domExists\r\n ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\\s/g, _strDot)).eq(0)\r\n : FRAMEWORK(generateDiv(className))\r\n }\r\n\r\n /**\r\n * Gets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be got.\r\n * @param path The property of which the value shall be got.\r\n * @returns {*} Returns the value of the searched property or undefined of the property wasn't found.\r\n */\r\n function getObjectPropVal(obj, path) {\r\n var splits = path.split(_strDot);\r\n var i = 0;\r\n var val;\r\n for (; i < splits.length; i++) {\r\n if (!obj[LEXICON.hOP](splits[i]))\r\n return;\r\n val = obj[splits[i]];\r\n if (i < splits.length && type(val) == TYPES.o)\r\n obj = val;\r\n }\r\n return val;\r\n }\r\n\r\n /**\r\n * Sets the value of the given property from the given object.\r\n * @param obj The object from which the property value shall be set.\r\n * @param path The property of which the value shall be set.\r\n * @param val The value of the property which shall be set.\r\n */\r\n function setObjectPropVal(obj, path, val) {\r\n var splits = path.split(_strDot);\r\n var splitsLength = splits.length;\r\n var i = 0;\r\n var extendObj = {};\r\n var extendObjRoot = extendObj;\r\n for (; i < splitsLength; i++)\r\n extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val;\r\n FRAMEWORK.extend(obj, extendObjRoot, true);\r\n }\r\n\r\n /**\t\r\n * Runs a action for each selector inside the updateOnLoad option.\t\r\n * @param {Function} action The action for each updateOnLoad selector, the arguments the function takes is the index and the value (the selector).\t\r\n */\r\n function eachUpdateOnLoad(action) {\r\n var updateOnLoad = _currentPreparedOptions.updateOnLoad;\r\n updateOnLoad = type(updateOnLoad) == TYPES.s ? updateOnLoad.split(_strSpace) : updateOnLoad;\r\n\r\n if (COMPATIBILITY.isA(updateOnLoad) && !_destroyed) {\r\n each(updateOnLoad, action);\r\n }\r\n }\r\n\r\n\r\n //==== Utils Cache ====//\r\n\r\n /**\r\n * Compares two values or objects and returns true if they aren't equal.\r\n * @param current The first value or object which shall be compared.\r\n * @param cache The second value or object which shall be compared.\r\n * @param force If true the returned value is always true.\r\n * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise.\r\n */\r\n function checkCache(current, cache, force) {\r\n if (force)\r\n return force;\r\n if (type(current) == TYPES.o && type(cache) == TYPES.o) {\r\n for (var prop in current) {\r\n if (prop !== 'c') {\r\n if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) {\r\n if (checkCache(current[prop], cache[prop]))\r\n return true;\r\n }\r\n else {\r\n return true;\r\n }\r\n }\r\n }\r\n }\r\n else {\r\n return current !== cache;\r\n }\r\n return false;\r\n }\r\n\r\n\r\n //==== Shortcuts ====//\r\n\r\n /**\r\n * jQuery extend method shortcut with a appended \"true\" as first argument.\r\n */\r\n function extendDeep() {\r\n return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments)));\r\n }\r\n\r\n /**\r\n * jQuery addClass method shortcut.\r\n */\r\n function addClass(el, classes) {\r\n return _frameworkProto.addClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery removeClass method shortcut.\r\n */\r\n function removeClass(el, classes) {\r\n return _frameworkProto.removeClass.call(el, classes);\r\n }\r\n\r\n /**\r\n * Adds or removes the given classes dependent on the boolean value. True for add, false for remove.\r\n */\r\n function addRemoveClass(el, classes, doAdd) {\r\n return doAdd ? addClass(el, classes) : removeClass(el, classes);\r\n }\r\n\r\n /**\r\n * jQuery remove method shortcut.\r\n */\r\n function remove(el) {\r\n return _frameworkProto.remove.call(el);\r\n }\r\n\r\n /**\r\n * Finds the first child element with the given selector of the given element.\r\n * @param el The root element from which the selector shall be valid.\r\n * @param selector The selector of the searched element.\r\n * @returns {*} The first element which is a child of the given element and matches the givens selector.\r\n */\r\n function findFirst(el, selector) {\r\n return _frameworkProto.find.call(el, selector).eq(0);\r\n }\r\n\r\n\r\n //==== API ====//\r\n\r\n /**\r\n * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle.\r\n * This behavior can be reset by calling the update method.\r\n */\r\n _base.sleep = function () {\r\n _sleeping = true;\r\n };\r\n\r\n /**\r\n * Updates the plugin and DOM to the current options.\r\n * This method should only be called if a update is 100% required.\r\n * @param force True if every property shall be updated and the cache shall be ignored.\r\n * !INTERNAL USAGE! : force can be a string \"auto\", \"sync\" or \"zoom\" too\r\n * if \"auto\" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called.\r\n * if \"sync\" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes.\r\n * if \"zoom\" then a update takes place where it's assumed that content and host size changed\r\n * @returns {boolean|undefined} \r\n * If force is \"sync\" then a boolean is returned which indicates whether a update was needed due to pending changes.\r\n * If force is \"auto\" then a boolean is returned whether a update was needed due to attribute or size changes.\r\n * undefined otherwise.\r\n */\r\n _base.update = function (force) {\r\n if (_destroyed)\r\n return;\r\n\r\n var attrsChanged;\r\n var contentSizeC;\r\n var isString = type(force) == TYPES.s;\r\n var doUpdateAuto;\r\n var mutHost;\r\n var mutContent;\r\n\r\n if (isString) {\r\n if (force === _strAuto) {\r\n attrsChanged = meaningfulAttrsChanged();\r\n contentSizeC = updateAutoContentSizeChanged();\r\n doUpdateAuto = attrsChanged || contentSizeC;\r\n if (doUpdateAuto) {\r\n update({\r\n _contentSizeChanged: contentSizeC,\r\n _changedOptions: _initialized ? undefined : _currentPreparedOptions\r\n });\r\n }\r\n }\r\n else if (force === _strSync) {\r\n if (_mutationObserversConnected) {\r\n mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords());\r\n mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords());\r\n }\r\n else {\r\n mutHost = _base.update(_strAuto);\r\n }\r\n }\r\n else if (force === 'zoom') {\r\n update({\r\n _hostSizeChanged: true,\r\n _contentSizeChanged: true\r\n });\r\n }\r\n }\r\n else {\r\n force = _sleeping || force;\r\n _sleeping = false;\r\n if (!_base.update(_strSync) || force)\r\n update({ _force: force });\r\n }\r\n\r\n updateElementsOnLoad();\r\n\r\n return doUpdateAuto || mutHost || mutContent;\r\n };\r\n\r\n /**\r\n Gets or sets the current options. The update method will be called automatically if new options were set.\r\n * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned.\r\n * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads.\r\n * @returns {*}\r\n */\r\n _base.options = function (newOptions, value) {\r\n var option = {};\r\n var changedOps;\r\n\r\n //return current options if newOptions are undefined or empty\r\n if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) {\r\n if (type(newOptions) == TYPES.s) {\r\n if (arguments.length > 1) {\r\n setObjectPropVal(option, newOptions, value);\r\n changedOps = setOptions(option);\r\n }\r\n else\r\n return getObjectPropVal(_currentOptions, newOptions);\r\n }\r\n else\r\n return _currentOptions;\r\n }\r\n else {\r\n changedOps = setOptions(newOptions);\r\n }\r\n\r\n if (!FRAMEWORK.isEmptyObject(changedOps)) {\r\n update({ _changedOptions: changedOps });\r\n }\r\n };\r\n\r\n /**\r\n * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep.\r\n */\r\n _base.destroy = function () {\r\n if (_destroyed)\r\n return;\r\n\r\n //remove this instance from auto update loop\r\n autoUpdateLoop.remove(_base);\r\n\r\n //disconnect all mutation observers\r\n disconnectMutationObservers();\r\n\r\n //remove all resize observers\r\n setupResizeObserver(_sizeObserverElement);\r\n setupResizeObserver(_sizeAutoObserverElement);\r\n\r\n //remove all extensions\r\n for (var extName in _extensions)\r\n _base.removeExt(extName);\r\n\r\n //remove all 'destroy' events\r\n while (_destroyEvents[LEXICON.l] > 0)\r\n _destroyEvents.pop()();\r\n\r\n //remove all events from host element\r\n setupHostMouseTouchEvents(true);\r\n\r\n //remove all helper / detection elements\r\n if (_contentGlueElement)\r\n remove(_contentGlueElement);\r\n if (_contentArrangeElement)\r\n remove(_contentArrangeElement);\r\n if (_sizeAutoObserverAdded)\r\n remove(_sizeAutoObserverElement);\r\n\r\n //remove all generated DOM\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n setupStructureDOM(true);\r\n\r\n //remove all generated image load events\r\n for (var i = 0; i < _updateOnLoadElms[LEXICON.l]; i++)\r\n FRAMEWORK(_updateOnLoadElms[i]).off(_updateOnLoadEventName, updateOnLoadCallback);\r\n _updateOnLoadElms = undefined;\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n //remove this instance from the instances list\r\n INSTANCES(pluginTargetElement, 0);\r\n dispatchCallback('onDestroyed');\r\n\r\n //remove all properties and methods\r\n //for (var property in _base)\r\n // delete _base[property];\r\n //_base = undefined;\r\n };\r\n\r\n /**\r\n * Scrolls to a given position or element.\r\n * @param coordinates\r\n * 1. Can be \"coordinates\" which looks like:\r\n * { x : ?, y : ? } OR Object with x and y properties\r\n * { left : ?, top : ? } OR Object with left and top properties\r\n * { l : ?, t : ? } OR Object with l and t properties\r\n * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y)\r\n * ? A single value which stays for both axis\r\n * A value can be a number, a string or a calculation.\r\n *\r\n * Operators:\r\n * [NONE] The current scroll will be overwritten by the value.\r\n * '+=' The value will be added to the current scroll offset\r\n * '-=' The value will be subtracted from the current scroll offset\r\n * '*=' The current scroll wil be multiplicated by the value.\r\n * '/=' The current scroll wil be divided by the value.\r\n *\r\n * Units:\r\n * [NONE] The value is the final scroll amount. final = (value * 1)\r\n * 'px' Same as none\r\n * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value)\r\n * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth)\r\n * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight)\r\n *\r\n * example final values:\r\n * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%'\r\n *\r\n * 2. Can be a HTML or jQuery element:\r\n * The final scroll offset is the offset (without margin) of the given HTML / jQuery element.\r\n *\r\n * 3. Can be a object with a HTML or jQuery element with additional settings:\r\n * {\r\n * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid.\r\n * scroll : [string, array, object], Default value is 'always'.\r\n * block : [string, array, object], Default value is 'begin'.\r\n * margin : [number, boolean, array, object] Default value is false.\r\n * }\r\n *\r\n * Possible scroll settings are:\r\n * 'always' Scrolls always.\r\n * 'ifneeded' Scrolls only if the element isnt fully in view.\r\n * 'never' Scrolls never.\r\n *\r\n * Possible block settings are:\r\n * 'begin' Both axis shall be docked to the \"begin\" edge. - The element will be docked to the top and left edge of the viewport.\r\n * 'end' Both axis shall be docked to the \"end\" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.)\r\n * 'center' Both axis shall be docked to \"center\". - The element will be centered in the viewport.\r\n * 'nearest' The element will be docked to the nearest edge(s).\r\n *\r\n * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset.\r\n * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used.\r\n * [NUMBER] The margin will be used for all edges.\r\n *\r\n * @param duration The duration of the scroll animation, OR a jQuery animation configuration object.\r\n * @param easing The animation easing.\r\n * @param complete The animation complete callback.\r\n * @returns {{\r\n * position: {x: number, y: number},\r\n * ratio: {x: number, y: number},\r\n * max: {x: number, y: number},\r\n * handleOffset: {x: number, y: number},\r\n * handleLength: {x: number, y: number},\r\n * handleLengthRatio: {x: number, y: number}, t\r\n * rackLength: {x: number, y: number},\r\n * isRTL: boolean,\r\n * isRTLNormalized: boolean\r\n * }}\r\n */\r\n _base.scroll = function (coordinates, duration, easing, complete) {\r\n if (arguments.length === 0 || coordinates === undefined) {\r\n var infoX = _scrollHorizontalInfo;\r\n var infoY = _scrollVerticalInfo;\r\n var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i;\r\n var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n;\r\n var scrollX = infoX._currentScroll;\r\n var scrollXRatio = infoX._currentScrollRatio;\r\n var maxScrollX = infoX._maxScroll;\r\n scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio;\r\n scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX;\r\n scrollX *= normalizeNegate ? -1 : 1;\r\n maxScrollX *= normalizeNegate ? -1 : 1;\r\n\r\n return {\r\n position: {\r\n x: scrollX,\r\n y: infoY._currentScroll\r\n },\r\n ratio: {\r\n x: scrollXRatio,\r\n y: infoY._currentScrollRatio\r\n },\r\n max: {\r\n x: maxScrollX,\r\n y: infoY._maxScroll\r\n },\r\n handleOffset: {\r\n x: infoX._handleOffset,\r\n y: infoY._handleOffset\r\n },\r\n handleLength: {\r\n x: infoX._handleLength,\r\n y: infoY._handleLength\r\n },\r\n handleLengthRatio: {\r\n x: infoX._handleLengthRatio,\r\n y: infoY._handleLengthRatio\r\n },\r\n trackLength: {\r\n x: infoX._trackLength,\r\n y: infoY._trackLength\r\n },\r\n snappedHandleOffset: {\r\n x: infoX._snappedHandleOffset,\r\n y: infoY._snappedHandleOffset\r\n },\r\n isRTL: _isRTL,\r\n isRTLNormalized: _normalizeRTLCache\r\n };\r\n }\r\n\r\n _base.update(_strSync);\r\n\r\n var normalizeRTL = _normalizeRTLCache;\r\n var coordinatesXAxisProps = [_strX, _strLeft, 'l'];\r\n var coordinatesYAxisProps = [_strY, _strTop, 't'];\r\n var coordinatesOperators = ['+=', '-=', '*=', '/='];\r\n var durationIsObject = type(duration) == TYPES.o;\r\n var completeCallback = durationIsObject ? duration.complete : complete;\r\n var i;\r\n var finalScroll = {};\r\n var specialEasing = {};\r\n var doScrollLeft;\r\n var doScrollTop;\r\n var animationOptions;\r\n var strEnd = 'end';\r\n var strBegin = 'begin';\r\n var strCenter = 'center';\r\n var strNearest = 'nearest';\r\n var strAlways = 'always';\r\n var strNever = 'never';\r\n var strIfNeeded = 'ifneeded';\r\n var strLength = LEXICON.l;\r\n var settingsAxis;\r\n var settingsScroll;\r\n var settingsBlock;\r\n var settingsMargin;\r\n var finalElement;\r\n var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx'];\r\n var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest];\r\n var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded];\r\n var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el');\r\n var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates;\r\n var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false;\r\n var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement);\r\n var updateScrollbarInfos = function () {\r\n if (doScrollLeft)\r\n refreshScrollbarHandleOffset(true);\r\n if (doScrollTop)\r\n refreshScrollbarHandleOffset(false);\r\n };\r\n var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () {\r\n updateScrollbarInfos();\r\n completeCallback();\r\n };\r\n function checkSettingsStringValue(currValue, allowedValues) {\r\n for (i = 0; i < allowedValues[strLength]; i++) {\r\n if (currValue === allowedValues[i])\r\n return true;\r\n }\r\n return false;\r\n }\r\n function getRawScroll(isX, coordinates) {\r\n var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps;\r\n coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates;\r\n\r\n if (COMPATIBILITY.isA(coordinates))\r\n return isX ? coordinates[0] : coordinates[1];\r\n else if (type(coordinates) == TYPES.o) {\r\n //decides RTL normalization \"hack\" with .n\r\n //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; \r\n for (i = 0; i < coordinateProps[strLength]; i++)\r\n if (coordinateProps[i] in coordinates)\r\n return coordinates[coordinateProps[i]];\r\n }\r\n }\r\n function getFinalScroll(isX, rawScroll) {\r\n var isString = type(rawScroll) == TYPES.s;\r\n var operator;\r\n var amount;\r\n var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo;\r\n var currScroll = scrollInfo._currentScroll;\r\n var maxScroll = scrollInfo._maxScroll;\r\n var mult = ' * ';\r\n var finalValue;\r\n var isRTLisX = _isRTL && isX;\r\n var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL;\r\n var strReplace = 'replace';\r\n var evalFunc = eval;\r\n var possibleOperator;\r\n if (isString) {\r\n //check operator\r\n if (rawScroll[strLength] > 2) {\r\n possibleOperator = rawScroll.substr(0, 2);\r\n if (inArray(possibleOperator, coordinatesOperators) > -1)\r\n operator = possibleOperator;\r\n }\r\n\r\n //calculate units and shortcuts\r\n rawScroll = operator ? rawScroll.substr(2) : rawScroll;\r\n rawScroll = rawScroll\r\n [strReplace](/min/g, 0) //'min' = 0%\r\n [strReplace](/</g, 0) //'<' = 0%\r\n [strReplace](/max/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'max' = 100%\r\n [strReplace](/>/g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100%\r\n [strReplace](/px/g, _strEmpty)\r\n [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0))\r\n [strReplace](/vw/g, mult + _viewportSize.w)\r\n [strReplace](/vh/g, mult + _viewportSize.h);\r\n amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll);\r\n }\r\n else {\r\n amount = rawScroll;\r\n }\r\n\r\n if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) {\r\n var normalizeIsRTLisX = normalizeRTL && isRTLisX;\r\n var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1);\r\n var invert = normalizeIsRTLisX && _rtlScrollBehavior.i;\r\n var negate = normalizeIsRTLisX && _rtlScrollBehavior.n;\r\n operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll;\r\n switch (operator) {\r\n case '+=':\r\n finalValue = operatorCurrScroll + amount;\r\n break;\r\n case '-=':\r\n finalValue = operatorCurrScroll - amount;\r\n break;\r\n case '*=':\r\n finalValue = operatorCurrScroll * amount;\r\n break;\r\n case '/=':\r\n finalValue = operatorCurrScroll / amount;\r\n break;\r\n default:\r\n finalValue = amount;\r\n break;\r\n }\r\n finalValue = invert ? maxScroll - finalValue : finalValue;\r\n finalValue *= negate ? -1 : 1;\r\n finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue));\r\n }\r\n return finalValue === currScroll ? undefined : finalValue;\r\n }\r\n function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) {\r\n var resultDefault = [defaultValue, defaultValue];\r\n var valueType = type(value);\r\n var valueArrLength;\r\n var valueArrItem;\r\n\r\n //value can be [ string, or array of two strings ]\r\n if (valueType == valueInternalType) {\r\n value = [value, value];\r\n }\r\n else if (valueType == TYPES.a) {\r\n valueArrLength = value[strLength];\r\n if (valueArrLength > 2 || valueArrLength < 1)\r\n value = resultDefault;\r\n else {\r\n if (valueArrLength === 1)\r\n value[1] = defaultValue;\r\n for (i = 0; i < valueArrLength; i++) {\r\n valueArrItem = value[i];\r\n if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) {\r\n value = resultDefault;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n else if (valueType == TYPES.o)\r\n value = [value[_strX] || defaultValue, value[_strY] || defaultValue];\r\n else\r\n value = resultDefault;\r\n return { x: value[0], y: value[1] };\r\n }\r\n function generateMargin(marginTopRightBottomLeftArray) {\r\n var result = [];\r\n var currValue;\r\n var currValueType;\r\n var valueDirections = [_strTop, _strRight, _strBottom, _strLeft];\r\n for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) {\r\n if (i === valueDirections[strLength])\r\n break;\r\n currValue = marginTopRightBottomLeftArray[i];\r\n currValueType = type(currValue);\r\n if (currValueType == TYPES.b)\r\n result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0);\r\n else\r\n result.push(currValueType == TYPES.n ? currValue : 0);\r\n }\r\n return result;\r\n }\r\n\r\n if (possibleElementIsJQuery || possibleElementIsHTMLElement) {\r\n //get settings\r\n var margin = coordinatesIsElementObj ? coordinates.margin : 0;\r\n var axis = coordinatesIsElementObj ? coordinates.axis : 0;\r\n var scroll = coordinatesIsElementObj ? coordinates.scroll : 0;\r\n var block = coordinatesIsElementObj ? coordinates.block : 0;\r\n var marginDefault = [0, 0, 0, 0];\r\n var marginType = type(margin);\r\n var marginLength;\r\n finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement);\r\n\r\n if (finalElement[strLength] > 0) {\r\n //margin can be [ boolean, number, array of 2, array of 4, object ]\r\n if (marginType == TYPES.n || marginType == TYPES.b)\r\n margin = generateMargin([margin, margin, margin, margin]);\r\n else if (marginType == TYPES.a) {\r\n marginLength = margin[strLength];\r\n if (marginLength === 2)\r\n margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]);\r\n else if (marginLength >= 4)\r\n margin = generateMargin(margin);\r\n else\r\n margin = marginDefault;\r\n }\r\n else if (marginType == TYPES.o)\r\n margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]);\r\n else\r\n margin = marginDefault;\r\n\r\n //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block;\r\n settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy';\r\n settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues);\r\n settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues);\r\n settingsMargin = margin;\r\n\r\n var viewportScroll = {\r\n l: _scrollHorizontalInfo._currentScroll,\r\n t: _scrollVerticalInfo._currentScroll\r\n };\r\n // use padding element instead of viewport element because padding element has never padding, margin or position applied.\r\n var viewportOffset = _paddingElement.offset();\r\n\r\n //get coordinates\r\n var elementOffset = finalElement.offset();\r\n var doNotScroll = {\r\n x: settingsScroll.x == strNever || settingsAxis == _strY,\r\n y: settingsScroll.y == strNever || settingsAxis == _strX\r\n };\r\n elementOffset[_strTop] -= settingsMargin[0];\r\n elementOffset[_strLeft] -= settingsMargin[3];\r\n var elementScrollCoordinates = {\r\n x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l),\r\n y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t)\r\n };\r\n if (_isRTL) {\r\n if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l);\r\n if (_rtlScrollBehavior.n && normalizeRTL)\r\n elementScrollCoordinates.x *= -1;\r\n if (_rtlScrollBehavior.i && normalizeRTL)\r\n elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l));\r\n }\r\n\r\n //measuring is required\r\n if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) {\r\n var measuringElm = finalElement[0];\r\n var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : {\r\n width: measuringElm[LEXICON.oW],\r\n height: measuringElm[LEXICON.oH]\r\n };\r\n var elementSize = {\r\n w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1],\r\n h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2]\r\n };\r\n var finalizeBlock = function (isX) {\r\n var vars = getScrollbarVars(isX);\r\n var wh = vars._w_h;\r\n var lt = vars._left_top;\r\n var xy = vars._x_y;\r\n var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd);\r\n var blockIsCenter = settingsBlock[xy] == strCenter;\r\n var blockIsNearest = settingsBlock[xy] == strNearest;\r\n var scrollNever = settingsScroll[xy] == strNever;\r\n var scrollIfNeeded = settingsScroll[xy] == strIfNeeded;\r\n var vpSize = _viewportSize[wh];\r\n var vpOffset = viewportOffset[lt];\r\n var elSize = elementSize[wh];\r\n var elOffset = elementOffset[lt];\r\n var divide = blockIsCenter ? 2 : 1;\r\n var elementCenterOffset = elOffset + (elSize / 2);\r\n var viewportCenterOffset = vpOffset + (vpSize / 2);\r\n var isInView =\r\n elSize <= vpSize\r\n && elOffset >= vpOffset\r\n && elOffset + elSize <= vpOffset + vpSize;\r\n\r\n if (scrollNever)\r\n doNotScroll[xy] = true;\r\n else if (!doNotScroll[xy]) {\r\n if (blockIsNearest || scrollIfNeeded) {\r\n doNotScroll[xy] = scrollIfNeeded ? isInView : false;\r\n blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset;\r\n }\r\n elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0;\r\n }\r\n };\r\n finalizeBlock(true);\r\n finalizeBlock(false);\r\n }\r\n\r\n if (doNotScroll.y)\r\n delete elementScrollCoordinates.y;\r\n if (doNotScroll.x)\r\n delete elementScrollCoordinates.x;\r\n\r\n coordinates = elementScrollCoordinates;\r\n }\r\n }\r\n\r\n finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates));\r\n finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates));\r\n doScrollLeft = finalScroll[_strScrollLeft] !== undefined;\r\n doScrollTop = finalScroll[_strScrollTop] !== undefined;\r\n\r\n if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) {\r\n if (durationIsObject) {\r\n duration.complete = proxyCompleteCallback;\r\n _viewportElement.animate(finalScroll, duration);\r\n }\r\n else {\r\n animationOptions = {\r\n duration: duration,\r\n complete: proxyCompleteCallback\r\n };\r\n if (COMPATIBILITY.isA(easing) || FRAMEWORK.isPlainObject(easing)) {\r\n specialEasing[_strScrollLeft] = easing[0] || easing.x;\r\n specialEasing[_strScrollTop] = easing[1] || easing.y;\r\n animationOptions.specialEasing = specialEasing;\r\n }\r\n else {\r\n animationOptions.easing = easing;\r\n }\r\n _viewportElement.animate(finalScroll, animationOptions);\r\n }\r\n }\r\n else {\r\n if (doScrollLeft)\r\n _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]);\r\n if (doScrollTop)\r\n _viewportElement[_strScrollTop](finalScroll[_strScrollTop]);\r\n updateScrollbarInfos();\r\n }\r\n };\r\n\r\n /**\r\n * Stops all scroll animations.\r\n * @returns {*} The current OverlayScrollbars instance (for chaining).\r\n */\r\n _base.scrollStop = function (param1, param2, param3) {\r\n _viewportElement.stop(param1, param2, param3);\r\n return _base;\r\n };\r\n\r\n /**\r\n * Returns all relevant elements.\r\n * @param elementName The name of the element which shall be returned.\r\n * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *}\r\n */\r\n _base.getElements = function (elementName) {\r\n var obj = {\r\n target: _targetElementNative,\r\n host: _hostElementNative,\r\n padding: _paddingElementNative,\r\n viewport: _viewportElementNative,\r\n content: _contentElementNative,\r\n scrollbarHorizontal: {\r\n scrollbar: _scrollbarHorizontalElement[0],\r\n track: _scrollbarHorizontalTrackElement[0],\r\n handle: _scrollbarHorizontalHandleElement[0]\r\n },\r\n scrollbarVertical: {\r\n scrollbar: _scrollbarVerticalElement[0],\r\n track: _scrollbarVerticalTrackElement[0],\r\n handle: _scrollbarVerticalHandleElement[0]\r\n },\r\n scrollbarCorner: _scrollbarCornerElement[0]\r\n };\r\n return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj;\r\n };\r\n\r\n /**\r\n * Returns a object which describes the current state of this instance.\r\n * @param stateProperty A specific property from the state object which shall be returned.\r\n * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *}\r\n */\r\n _base.getState = function (stateProperty) {\r\n function prepare(obj) {\r\n if (!FRAMEWORK.isPlainObject(obj))\r\n return obj;\r\n var extended = extendDeep({}, obj);\r\n var changePropertyName = function (from, to) {\r\n if (extended[LEXICON.hOP](from)) {\r\n extended[to] = extended[from];\r\n delete extended[from];\r\n }\r\n };\r\n changePropertyName('w', _strWidth); //change w to width\r\n changePropertyName('h', _strHeight); //change h to height\r\n delete extended.c; //delete c (the 'changed' prop)\r\n return extended;\r\n };\r\n var obj = {\r\n destroyed: !!prepare(_destroyed),\r\n sleeping: !!prepare(_sleeping),\r\n autoUpdate: prepare(!_mutationObserversConnected),\r\n widthAuto: prepare(_widthAutoCache),\r\n heightAuto: prepare(_heightAutoCache),\r\n padding: prepare(_cssPaddingCache),\r\n overflowAmount: prepare(_overflowAmountCache),\r\n hideOverflow: prepare(_hideOverflowCache),\r\n hasOverflow: prepare(_hasOverflowCache),\r\n contentScrollSize: prepare(_contentScrollSizeCache),\r\n viewportSize: prepare(_viewportSize),\r\n hostSize: prepare(_hostSizeCache),\r\n documentMixed: prepare(_documentMixed)\r\n };\r\n return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj;\r\n };\r\n\r\n /**\r\n * Gets all or specific extension instance.\r\n * @param extName The name of the extension from which the instance shall be got.\r\n * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found.\r\n */\r\n _base.ext = function (extName) {\r\n var result;\r\n var privateMethods = _extensionsPrivateMethods.split(' ');\r\n var i = 0;\r\n if (type(extName) == TYPES.s) {\r\n if (_extensions[LEXICON.hOP](extName)) {\r\n result = extendDeep({}, _extensions[extName]);\r\n for (; i < privateMethods.length; i++)\r\n delete result[privateMethods[i]];\r\n }\r\n }\r\n else {\r\n result = {};\r\n for (i in _extensions)\r\n result[i] = extendDeep({}, _base.ext(i));\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Adds a extension to this instance.\r\n * @param extName The name of the extension which shall be added.\r\n * @param extensionOptions The extension options which shall be used.\r\n * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly.\r\n */\r\n _base.addExt = function (extName, extensionOptions) {\r\n var registeredExtensionObj = _plugin.extension(extName);\r\n var instance;\r\n var instanceAdded;\r\n var instanceContract;\r\n var contractResult;\r\n var contractFulfilled = true;\r\n if (registeredExtensionObj) {\r\n if (!_extensions[LEXICON.hOP](extName)) {\r\n instance = registeredExtensionObj.extensionFactory.call(_base,\r\n extendDeep({}, registeredExtensionObj.defaultOptions),\r\n FRAMEWORK,\r\n COMPATIBILITY);\r\n\r\n if (instance) {\r\n instanceContract = instance.contract;\r\n if (type(instanceContract) == TYPES.f) {\r\n contractResult = instanceContract(window);\r\n contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled;\r\n }\r\n if (contractFulfilled) {\r\n _extensions[extName] = instance;\r\n instanceAdded = instance.added;\r\n if (type(instanceAdded) == TYPES.f)\r\n instanceAdded(extensionOptions);\r\n\r\n return _base.ext(extName);\r\n }\r\n }\r\n }\r\n else\r\n return _base.ext(extName);\r\n }\r\n else\r\n console.warn(\"A extension with the name \\\"\" + extName + \"\\\" isn't registered.\");\r\n };\r\n\r\n /**\r\n * Removes a extension from this instance.\r\n * @param extName The name of the extension which shall be removed.\r\n * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before.\r\n */\r\n _base.removeExt = function (extName) {\r\n var instance = _extensions[extName];\r\n var instanceRemoved;\r\n if (instance) {\r\n delete _extensions[extName];\r\n\r\n instanceRemoved = instance.removed;\r\n if (type(instanceRemoved) == TYPES.f)\r\n instanceRemoved();\r\n\r\n return true;\r\n }\r\n return false;\r\n };\r\n\r\n /**\r\n * Constructs the plugin.\r\n * @param targetElement The element to which the plugin shall be applied.\r\n * @param options The initial options of the plugin.\r\n * @param extensions The extension(s) which shall be added right after the initialization.\r\n * @returns {boolean} True if the plugin was successfully initialized, false otherwise.\r\n */\r\n function construct(targetElement, options, extensions) {\r\n _defaultOptions = globals.defaultOptions;\r\n _nativeScrollbarStyling = globals.nativeScrollbarStyling;\r\n _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize);\r\n _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid);\r\n _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize);\r\n _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior);\r\n\r\n //parse & set options but don't update\r\n setOptions(extendDeep({}, _defaultOptions, options));\r\n\r\n _cssCalc = globals.cssCalc;\r\n _msieVersion = globals.msie;\r\n _autoUpdateRecommended = globals.autoUpdateRecommended;\r\n _supportTransition = globals.supportTransition;\r\n _supportTransform = globals.supportTransform;\r\n _supportPassiveEvents = globals.supportPassiveEvents;\r\n _supportResizeObserver = globals.supportResizeObserver;\r\n _supportMutationObserver = globals.supportMutationObserver;\r\n _restrictedMeasuring = globals.restrictedMeasuring;\r\n _documentElement = FRAMEWORK(targetElement.ownerDocument);\r\n _documentElementNative = _documentElement[0];\r\n _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow);\r\n _windowElementNative = _windowElement[0];\r\n _htmlElement = findFirst(_documentElement, 'html');\r\n _bodyElement = findFirst(_htmlElement, 'body');\r\n _targetElement = FRAMEWORK(targetElement);\r\n _targetElementNative = _targetElement[0];\r\n _isTextarea = _targetElement.is('textarea');\r\n _isBody = _targetElement.is('body');\r\n _documentMixed = _documentElementNative !== document;\r\n\r\n /* On a div Element The if checks only whether:\r\n * - the targetElement has the class \"os-host\"\r\n * - the targetElement has a a child with the class \"os-padding\"\r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-host\" element is the targetElement)\r\n *\r\n * <div class=\"os-host\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding\">\r\n * <div class=\"os-viewport\">\r\n * <div class=\"os-content\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n *\r\n * =====================================================================================\r\n * \r\n * On a Textarea Element The if checks only whether:\r\n * - the targetElement has the class \"os-textarea\" \r\n * - the targetElement is inside a element with the class \"os-content\" \r\n * \r\n * If that's the case, its assumed the DOM has already the following structure:\r\n * (The \".os-textarea\" (textarea) element is the targetElement)\r\n *\r\n * <div class=\"os-host-textarea\">\r\n * <div class=\"os-resize-observer-host\"></div>\r\n * <div class=\"os-padding os-text-inherit\">\r\n * <div class=\"os-viewport os-text-inherit\">\r\n * <div class=\"os-content os-text-inherit\">\r\n * <div class=\"os-textarea-cover\"></div>\r\n * <textarea class=\"os-textarea os-text-inherit\"></textarea>\r\n * </div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-horizontal \">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar os-scrollbar-vertical\">\r\n * <div class=\"os-scrollbar-track\">\r\n * <div class=\"os-scrollbar-handle\"></div>\r\n * </div>\r\n * </div>\r\n * <div class=\"os-scrollbar-corner\"></div>\r\n * </div>\r\n */\r\n _domExists = _isTextarea\r\n ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement)\r\n : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l];\r\n\r\n var initBodyScroll;\r\n var bodyMouseTouchDownListener;\r\n\r\n //check if the plugin hasn't to be initialized\r\n if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) {\r\n dispatchCallback('onInitializationWithdrawn');\r\n if (_domExists) {\r\n setupStructureDOM(true);\r\n setupScrollbarsDOM(true);\r\n setupScrollbarCornerDOM(true);\r\n }\r\n\r\n _destroyed = true;\r\n _sleeping = true;\r\n\r\n return _base;\r\n }\r\n\r\n if (_isBody) {\r\n initBodyScroll = {};\r\n initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]());\r\n initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]());\r\n\r\n bodyMouseTouchDownListener = function () {\r\n _viewportElement.removeAttr(LEXICON.ti);\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true);\r\n }\r\n }\r\n\r\n //build OverlayScrollbars DOM\r\n setupStructureDOM();\r\n setupScrollbarsDOM();\r\n setupScrollbarCornerDOM();\r\n\r\n //create OverlayScrollbars events\r\n setupStructureEvents();\r\n setupScrollbarEvents(true);\r\n setupScrollbarEvents(false);\r\n setupScrollbarCornerEvents();\r\n\r\n //create mutation observers\r\n createMutationObservers();\r\n\r\n //build resize observer for the host element\r\n setupResizeObserver(_sizeObserverElement, hostOnResized);\r\n\r\n if (_isBody) {\r\n //apply the body scroll to handle it right in the update method\r\n _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t);\r\n\r\n //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling\r\n if (document.activeElement == targetElement && _viewportElementNative.focus) {\r\n //set a tabindex to make the viewportElement focusable\r\n _viewportElement.attr(LEXICON.ti, '-1');\r\n _viewportElementNative.focus();\r\n\r\n /* the tabindex has to be removed due to;\r\n * If you set the tabindex attribute on an <div>, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too\r\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex\r\n */\r\n setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true);\r\n }\r\n }\r\n\r\n //update for the first time & initialize cache\r\n _base.update(_strAuto);\r\n\r\n //the plugin is initialized now!\r\n _initialized = true;\r\n dispatchCallback('onInitialized');\r\n\r\n //call all callbacks which would fire before the initialized was complete\r\n each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); });\r\n _callbacksInitQeueue = [];\r\n\r\n //add extensions\r\n if (type(extensions) == TYPES.s)\r\n extensions = [extensions];\r\n if (COMPATIBILITY.isA(extensions))\r\n each(extensions, function (index, value) { _base.addExt(value); });\r\n else if (FRAMEWORK.isPlainObject(extensions))\r\n each(extensions, function (key, value) { _base.addExt(key, value); });\r\n\r\n //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions)\r\n setTimeout(function () {\r\n if (_supportTransition && !_destroyed)\r\n addClass(_hostElement, _classNameHostTransition);\r\n }, 333);\r\n\r\n return _base;\r\n }\r\n\r\n if (_plugin.valid(construct(pluginTargetElement, options, extensions))) {\r\n INSTANCES(pluginTargetElement, _base);\r\n }\r\n\r\n return _base;\r\n }\r\n\r\n /**\r\n * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance.\r\n * @param pluginTargetElements The elements to which the Plugin shall be initialized.\r\n * @param options The custom options with which the plugin shall be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*}\r\n */\r\n _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) {\r\n if (arguments[LEXICON.l] === 0)\r\n return this;\r\n\r\n var arr = [];\r\n var optsIsPlainObj = FRAMEWORK.isPlainObject(options);\r\n var inst;\r\n var result;\r\n\r\n //pluginTargetElements is null or undefined\r\n if (!pluginTargetElements)\r\n return optsIsPlainObj || !options ? result : arr;\r\n\r\n /*\r\n pluginTargetElements will be converted to:\r\n 1. A jQueryElement Array\r\n 2. A HTMLElement Array\r\n 3. A Array with a single HTML Element\r\n so pluginTargetElements is always a array.\r\n */\r\n pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements];\r\n initOverlayScrollbarsStatics();\r\n\r\n if (pluginTargetElements[LEXICON.l] > 0) {\r\n if (optsIsPlainObj) {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = v;\r\n if (inst !== undefined)\r\n arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop));\r\n });\r\n }\r\n else {\r\n FRAMEWORK.each(pluginTargetElements, function (i, v) {\r\n inst = INSTANCES(v);\r\n if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst)))\r\n arr.push(inst);\r\n else if (options === undefined)\r\n arr.push(inst);\r\n });\r\n }\r\n result = arr[LEXICON.l] === 1 ? arr[0] : arr;\r\n }\r\n return result;\r\n };\r\n\r\n /**\r\n * Returns a object which contains global information about the plugin and each instance of it.\r\n * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object.\r\n */\r\n _plugin.globals = function () {\r\n initOverlayScrollbarsStatics();\r\n var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals);\r\n delete globals['msie'];\r\n return globals;\r\n };\r\n\r\n /**\r\n * Gets or Sets the default options for each new plugin initialization.\r\n * @param newDefaultOptions The object with which the default options shall be extended.\r\n */\r\n _plugin.defaultOptions = function (newDefaultOptions) {\r\n initOverlayScrollbarsStatics();\r\n var currDefaultOptions = _pluginsGlobals.defaultOptions;\r\n if (newDefaultOptions === undefined)\r\n return FRAMEWORK.extend(true, {}, currDefaultOptions);\r\n\r\n //set the new default options\r\n _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default);\r\n };\r\n\r\n /**\r\n * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance.\r\n * @param osInstance The potential OverlayScrollbars instance which shall be checked.\r\n * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise.\r\n */\r\n _plugin.valid = function (osInstance) {\r\n return osInstance instanceof _plugin && !osInstance.getState().destroyed;\r\n };\r\n\r\n /**\r\n * Registers, Unregisters or returns a extension.\r\n * Register: Pass the name and the extension. (defaultOptions is optional)\r\n * Unregister: Pass the name and anything except a function as extension parameter.\r\n * Get extension: Pass the name of the extension which shall be got.\r\n * Get all extensions: Pass no arguments.\r\n * @param extensionName The name of the extension which shall be registered, unregistered or returned.\r\n * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension.\r\n * @param defaultOptions The default options which shall be used for the registered extension.\r\n */\r\n _plugin.extension = function (extensionName, extension, defaultOptions) {\r\n var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s;\r\n var argLen = arguments[LEXICON.l];\r\n var i = 0;\r\n if (argLen < 1 || !extNameTypeString) {\r\n //return a copy of all extension objects\r\n return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions);\r\n }\r\n else if (extNameTypeString) {\r\n if (COMPATIBILITY.type(extension) == TYPES.f) {\r\n //register extension\r\n _pluginsExtensions.push({\r\n name: extensionName,\r\n extensionFactory: extension,\r\n defaultOptions: defaultOptions\r\n });\r\n }\r\n else {\r\n for (; i < _pluginsExtensions[LEXICON.l]; i++) {\r\n if (_pluginsExtensions[i].name === extensionName) {\r\n if (argLen > 1)\r\n _pluginsExtensions.splice(i, 1); //remove extension\r\n else\r\n return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n return _plugin;\r\n })();\r\n\r\n if (JQUERY && JQUERY.fn) {\r\n /**\r\n * The jQuery initialization interface.\r\n * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized.\r\n * @param extensions The extension(s) which shall be added right after initialization.\r\n * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected.\r\n */\r\n JQUERY.fn.overlayScrollbars = function (options, extensions) {\r\n var _elements = this;\r\n if (JQUERY.isPlainObject(options)) {\r\n JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); });\r\n return _elements;\r\n }\r\n else\r\n return PLUGIN(_elements, options);\r\n };\r\n }\r\n return PLUGIN;\r\n }\r\n));//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vL2hvbWUvamVua2lucy93b3Jrc3BhY2UvZGVzaWduLXN5c3RlbV9tYWluL25vZGVfbW9kdWxlcy9vdmVybGF5c2Nyb2xsYmFycy9qcy9PdmVybGF5U2Nyb2xsYmFycy5qcz83ODhiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFFBQVEsSUFBMEM7QUFDbEQsUUFBUSxtQ0FBTyxhQUFhLG9EQUFvRCxFQUFFO0FBQUEsb0dBQUM7QUFDbkYsU0FBUyxFQUcyQztBQUNwRCxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHdCQUF3QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxvQ0FBb0M7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDBCQUEwQiw4QkFBOEI7QUFDeEQsOEJBQThCLHFDQUFxQztBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QywwQ0FBMEMsNEdBQTRHOztBQUV0SjtBQUNBLDhDQUE4QztBQUM5Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixjQUFjO0FBQzNDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLDZCQUE2QjtBQUMxRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsV0FBVztBQUN4QztBQUNBLDhGQUE4RiwyQ0FBMkMsRUFBRTs7QUFFM0k7QUFDQTtBQUNBLDZCQUE2QixXQUFXO0FBQ3hDO0FBQ0EsMkZBQTJGLGdDQUFnQyxFQUFFOztBQUU3SDtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLHNCQUFzQjtBQUNwRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQSxtQ0FBbUMsb0JBQW9CO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsT0FBTztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixZQUFZOztBQUV6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7O0FBR1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1EQUFtRCxtQkFBbUI7QUFDdEU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSwyQ0FBMkMsV0FBVztBQUN0RCx5Q0FBeUMsaUNBQWlDO0FBQzFFLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLDJDQUEyQyxXQUFXO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPLFdBQVc7QUFDbEU7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsK0JBQStCO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZGQUE2RjtBQUM3RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsWUFBWTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNENBQTRDLG9CQUFvQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBLGtDQUFrQzs7QUFFbEM7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLG9CQUFvQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsc0JBQXNCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFlBQVk7QUFDN0I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxzQkFBc0IsNEJBQTRCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0EseUNBQXlDO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQSwrQ0FBK0M7O0FBRS9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiw0QkFBNEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsMEJBQTBCLHFCQUFxQjtBQUMvQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0IseUJBQXlCO0FBQ3hEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLHFCQUFxQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MscUJBQXFCO0FBQzNEO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQyxxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QixxQkFBcUI7QUFDckIsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0Esa0RBQWtELGlEQUFpRCxFQUFFO0FBQ3JHLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtREFBbUQsRUFBRTtBQUN2RyxpQkFBaUI7O0FBRWpCO0FBQ0Esa0RBQWtELGdEQUFnRCxFQUFFO0FBQ3BHLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckIsK0JBQStCLHdCQUF3QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQkFBK0Isc0JBQXNCO0FBQ3JEOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsdUNBQXVDLEVBQUU7QUFDM0YsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0Qsa0NBQWtDLEVBQUU7QUFDdEYsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCxtQ0FBbUMsRUFBRTtBQUN2RixpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQSxrREFBa0QsZ0NBQWdDLEVBQUU7QUFDcEYsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7O0FBR2pCOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyxtQkFBbUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0IscUJBQXFCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1DQUFtQyx1QkFBdUI7QUFDMUQ7QUFDQSxxQkFBcUI7O0FBRXJCO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0EsaUJBQWlCOzs7QUFHakI7O0FBRUE7QUFDQSxrREFBa0Qsa0RBQWtELEVBQUU7QUFDdEcsaUJBQWlCOztBQUVqQjtBQUNBLGtEQUFrRCwwQkFBMEIsRUFBRTtBQUM5RTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsT0FBTztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4REFBOEQ7QUFDOUQ7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0U7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxvRkFBb0Y7O0FBRXBGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0EsbURBQW1ELDhCQUE4QjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELDRDQUE0QztBQUN2RztBQUNBO0FBQ0E7QUFDQSwrREFBK0QseURBQXlEO0FBQ3hIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFOztBQUU1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvREFBb0Q7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsYUFBYTs7QUFFdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUI7QUFDckIsZ0RBQWdELGVBQWU7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0EsbURBQW1ELHVFQUF1RTtBQUMxSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCLHlCQUF5QixZQUFZO0FBQ3JDO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxpQkFBaUI7O0FBRWpCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxtQ0FBbUM7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DLGlDQUFpQztBQUNqQyw2Q0FBNkM7QUFDN0MseUNBQXlDO0FBQ3pDLG9DQUFvQztBQUNwQyxxQ0FBcUM7QUFDckMsb0NBQW9DO0FBQ3BDLDJDQUEyQztBQUMzQyx3Q0FBd0M7QUFDeEMsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjs7QUFFckI7QUFDQSw4QkFBOEIsMkJBQTJCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qix1QkFBdUI7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELHFEQUFxRDtBQUM5RztBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFQUFpRSxrRUFBa0UsZ0JBQWdCO0FBQ25KO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEY7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQzs7QUFFakM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDOztBQUVqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCOztBQUV6QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5QjtBQUM3RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQ0FBb0MsNEJBQTRCO0FBQ2hFO0FBQ0EscUJBQXFCO0FBQ3JCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsbUNBQW1DLGlCQUFpQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0EscUJBQXFCOztBQUVyQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLG9CQUFvQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUlBQW1JOztBQUVuSTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsRUFBRTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTREO0FBQzVEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsOEZBQThGOztBQUU5RjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEZBQThGO0FBQzlGOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQSw4REFBOEQ7O0FBRTlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUErQztBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RkFBNkY7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRkFBb0Y7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFLFdBQVc7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0xBQWdMO0FBQ2hMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG1EQUFtRCxnQkFBZ0I7QUFDbkU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3Qix5QkFBeUI7QUFDekI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7O0FBRUEsbURBQW1EO0FBQ25ELDJEQUEyRDs7QUFFM0Q7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qjs7QUFFN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdFQUF3RTtBQUN4RTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1IQUFtSDtBQUNuSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRIQUE0SCxpQkFBaUI7QUFDN0kseUJBQXlCOzs7QUFHekI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZIQUE2SCxpQkFBaUI7QUFDOUkseUJBQXlCOzs7QUFHekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0pBQWtKO0FBQ2xKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEVBQThFO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLHdGQUF3RjtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1IQUFtSDs7QUFFbkg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwrTkFBK047QUFDL047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwSEFBMEg7QUFDMUgsaUhBQWlIO0FBQ2pIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLCtFQUErRTtBQUM3RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0QscUNBQXFDO0FBQ3BHOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsbURBQW1ELG1CQUFtQjtBQUN0RTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixPQUFPO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBCQUEwQiwyQkFBMkI7QUFDckQ7QUFDQSxtQ0FBbUMsMkJBQTJCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwyQkFBMkIsUUFBUTtBQUNuQywyQkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdEO0FBQ0EsMERBQTBEO0FBQzFEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw4QkFBOEIsc0JBQXNCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsTUFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsZUFBZTtBQUM5QztBQUNBLCtCQUErQixlQUFlO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDhCQUE4QixtR0FBbUc7QUFDakk7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwrQkFBK0IsaUNBQWlDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLE9BQU87QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsbUJBQW1CO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGtCQUFrQjtBQUM1QyxvRkFBb0Y7QUFDcEY7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkJBQTJCLFNBQVM7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixFQUFFO0FBQy9CO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLGtCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxnQkFBZ0I7QUFDcEQ7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxtQ0FBbUMsa0NBQWtDO0FBQ3JFO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixlQUFlO0FBQ3RDLHVCQUF1QixvQkFBb0I7QUFDM0MsdUJBQXVCLGVBQWU7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHFCQUFxQjtBQUNyRCw2QkFBNkIscUJBQXFCO0FBQ2xELDJCQUEyQixxQkFBcUI7QUFDaEQsb0NBQW9DLHFCQUFxQjtBQUN6RCxvQ0FBb0MscUJBQXFCO0FBQ3pELHlDQUF5QyxxQkFBcUI7QUFDOUQsa0NBQWtDLHFCQUFxQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyw4QkFBOEI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJHO0FBQ0EsdUNBQXVDLGdDQUFnQztBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDLG9CQUFvQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDhDQUE4QztBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSw2QkFBNkIsRUFBRTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrRUFBK0Usa0NBQWtDLHNCQUFzQixrQ0FBa0MscUJBQXFCO0FBQzVOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsd0hBQXdIO0FBQ3RKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNELDREQUE0RDtBQUM1RCwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xELGtDQUFrQywyQkFBMkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDO0FBQzdDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsUUFBUTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RCw4REFBOEQ7QUFDOUQsOERBQThEO0FBQzlELHNEQUFzRDs7QUFFdEQ7QUFDQSw0Q0FBNEM7O0FBRTVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3RUFBd0Usb0NBQW9DLEVBQUU7QUFDOUc7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UscUJBQXFCLEVBQUU7QUFDekY7QUFDQSxnRUFBZ0UsMEJBQTBCLEVBQUU7O0FBRTVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCOztBQUVyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDs7QUFFcEQ7QUFDQSwwRUFBMEU7QUFDMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLFFBQVE7QUFDakM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsd0NBQXdDO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLDhCQUE4QixtQ0FBbUM7QUFDakU7QUFDQTtBQUNBLG9FQUFvRTtBQUNwRTtBQUNBLG9FQUFvRSx5QkFBeUI7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixFQUFFO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELG1DQUFtQyxFQUFFO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiIxMDkxLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohXHJcbiAqIE92ZXJsYXlTY3JvbGxiYXJzXHJcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9LaW5nU29yYS9PdmVybGF5U2Nyb2xsYmFyc1xyXG4gKlxyXG4gKiBWZXJzaW9uOiAxLjEzLjBcclxuICpcclxuICogQ29weXJpZ2h0IEtpbmdTb3JhIHwgUmVuZSBIYWFzLlxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmFcclxuICpcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxyXG4gKiBEYXRlOiAwMi4wOC4yMDIwXHJcbiAqL1xyXG5cclxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXHJcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7IH0pO1xyXG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSAnb2JqZWN0JylcclxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwuZG9jdW1lbnQsIHVuZGVmaW5lZCk7XHJcbiAgICBlbHNlXHJcbiAgICAgICAgZmFjdG9yeShnbG9iYWwsIGdsb2JhbC5kb2N1bWVudCwgdW5kZWZpbmVkKTtcclxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsXHJcbiAgICBmdW5jdGlvbiAod2luZG93LCBkb2N1bWVudCwgdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgJ3VzZSBzdHJpY3QnO1xyXG4gICAgICAgIHZhciBQTFVHSU5OQU1FID0gJ092ZXJsYXlTY3JvbGxiYXJzJztcclxuICAgICAgICB2YXIgVFlQRVMgPSB7XHJcbiAgICAgICAgICAgIG86ICdvYmplY3QnLFxyXG4gICAgICAgICAgICBmOiAnZnVuY3Rpb24nLFxyXG4gICAgICAgICAgICBhOiAnYXJyYXknLFxyXG4gICAgICAgICAgICBzOiAnc3RyaW5nJyxcclxuICAgICAgICAgICAgYjogJ2Jvb2xlYW4nLFxyXG4gICAgICAgICAgICBuOiAnbnVtYmVyJyxcclxuICAgICAgICAgICAgdTogJ3VuZGVmaW5lZCcsXHJcbiAgICAgICAgICAgIHo6ICdudWxsJ1xyXG4gICAgICAgICAgICAvL2QgOiAnZGF0ZScsXHJcbiAgICAgICAgICAgIC8vZSA6ICdlcnJvcicsXHJcbiAgICAgICAgICAgIC8vciA6ICdyZWdleHAnLFxyXG4gICAgICAgICAgICAvL3kgOiAnc3ltYm9sJ1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIExFWElDT04gPSB7XHJcbiAgICAgICAgICAgIGM6ICdjbGFzcycsXHJcbiAgICAgICAgICAgIHM6ICdzdHlsZScsXHJcbiAgICAgICAgICAgIGk6ICdpZCcsXHJcbiAgICAgICAgICAgIGw6ICdsZW5ndGgnLFxyXG4gICAgICAgICAgICBwOiAncHJvdG90eXBlJyxcclxuICAgICAgICAgICAgdGk6ICd0YWJpbmRleCcsXHJcbiAgICAgICAgICAgIG9IOiAnb2Zmc2V0SGVpZ2h0JyxcclxuICAgICAgICAgICAgY0g6ICdjbGllbnRIZWlnaHQnLFxyXG4gICAgICAgICAgICBzSDogJ3Njcm9sbEhlaWdodCcsXHJcbiAgICAgICAgICAgIG9XOiAnb2Zmc2V0V2lkdGgnLFxyXG4gICAgICAgICAgICBjVzogJ2NsaWVudFdpZHRoJyxcclxuICAgICAgICAgICAgc1c6ICdzY3JvbGxXaWR0aCcsXHJcbiAgICAgICAgICAgIGhPUDogJ2hhc093blByb3BlcnR5JyxcclxuICAgICAgICAgICAgYkNSOiAnZ2V0Qm91bmRpbmdDbGllbnRSZWN0J1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIFZFTkRPUlMgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvL2h0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvR2xvc3NhcnkvVmVuZG9yX1ByZWZpeFxyXG4gICAgICAgICAgICB2YXIganNDYWNoZSA9IHt9O1xyXG4gICAgICAgICAgICB2YXIgY3NzQ2FjaGUgPSB7fTtcclxuICAgICAgICAgICAgdmFyIGNzc1ByZWZpeGVzID0gWyctd2Via2l0LScsICctbW96LScsICctby0nLCAnLW1zLSddO1xyXG4gICAgICAgICAgICB2YXIganNQcmVmaXhlcyA9IFsnV2ViS2l0JywgJ01veicsICdPJywgJ01TJ107XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGZpcnN0TGV0dGVyVG9VcHBlcihzdHIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdHIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoMSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBfY3NzUHJlZml4ZXM6IGNzc1ByZWZpeGVzLFxyXG4gICAgICAgICAgICAgICAgX2pzUHJlZml4ZXM6IGpzUHJlZml4ZXMsXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHk6IGZ1bmN0aW9uIChuYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdXBwZXJjYXNlZE5hbWUgPSBmaXJzdExldHRlclRvVXBwZXIobmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbVN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylbTEVYSUNPTi5zXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0UG9zc2liaWxpdGllcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHY7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGNzc1ByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzID0gY3NzUHJlZml4ZXNbaV0ucmVwbGFjZSgvLS9nLCAnJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFBvc3NpYmlsaXRpZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAvL3RyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1ByZWZpeGVzW2ldICsgbmFtZSwgLy8td2Via2l0LXRyYW5zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzICsgdXBwZXJjYXNlZE5hbWUsIC8vd2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RMZXR0ZXJUb1VwcGVyKGN1cnJWZW5kb3JXaXRob3V0RGFzaGVzKSArIHVwcGVyY2FzZWROYW1lIC8vV2Via2l0VHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdWx0UG9zc2liaWxpdGllc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbG1TdHlsZVtyZXN1bHRQb3NzaWJpbGl0aWVzW3ZdXSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0UG9zc2liaWxpdGllc1t2XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2FjaGVbbmFtZV0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBfY3NzUHJvcGVydHlWYWx1ZTogZnVuY3Rpb24gKHByb3BlcnR5LCB2YWx1ZXMsIHN1ZmZpeCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYW1lID0gcHJvcGVydHkgKyAnICcgKyB2YWx1ZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGNzc0NhY2hlW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY3NzQ2FjaGVbTEVYSUNPTi5oT1BdKG5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlTdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpW0xFWElDT04uc107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NibGVWYWx1ZXMgPSB2YWx1ZXMuc3BsaXQoJyAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJlcGFyZWRTdWZmaXggPSBzdWZmaXggfHwgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3A7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcG9zc2JsZVZhbHVlc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IHYgPCBWRU5ET1JTLl9jc3NQcmVmaXhlc1tMRVhJQ09OLmxdOyB2KyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3AgPSB2IDwgMCA/IHBvc3NibGVWYWx1ZXNbaV0gOiBWRU5ET1JTLl9jc3NQcmVmaXhlc1t2XSArIHBvc3NibGVWYWx1ZXNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdW1teVN0eWxlLmNzc1RleHQgPSBwcm9wZXJ0eSArICc6JyArIHByb3AgKyBwcmVwYXJlZFN1ZmZpeDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdW1teVN0eWxlW0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwcm9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBjc3NDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIF9qc0FQSTogZnVuY3Rpb24gKG5hbWUsIGlzSW50ZXJmYWNlLCBmYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0ganNDYWNoZVtuYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFqc0NhY2hlW0xFWElDT04uaE9QXShuYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB3aW5kb3dbbmFtZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwganNQcmVmaXhlc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwgd2luZG93Wyhpc0ludGVyZmFjZSA/IGpzUHJlZml4ZXNbaV0gOiBqc1ByZWZpeGVzW2ldLnRvTG93ZXJDYXNlKCkpICsgZmlyc3RMZXR0ZXJUb1VwcGVyKG5hbWUpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAganNDYWNoZVtuYW1lXSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBmYWxsYmFjaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIENPTVBBVElCSUxJVFkgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBmdW5jdGlvbiB3aW5kb3dTaXplKHgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB4ID8gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY1ddIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jV10gOiB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W0xFWElDT04uY0hdIHx8IGRvY3VtZW50LmJvZHlbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZnVuY3Rpb24gYmluZChmdW5jLCB0aGlzT2JqKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGZ1bmMgIT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFwiQ2FuJ3QgYmluZCBmdW5jdGlvbiFcIjtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgLy90aHJvdyBuZXcgVHlwZUVycm9yKCdGdW5jdGlvbi5wcm90b3R5cGUuYmluZCAtIHdoYXQgaXMgdHJ5aW5nIHRvIGJlIGJvdW5kIGlzIG5vdCBjYWxsYWJsZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGFBcmdzID0gQXJyYXlbcHJvdG9dLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcclxuICAgICAgICAgICAgICAgIHZhciBmTk9QID0gZnVuY3Rpb24gKCkgeyB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGZCb3VuZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgPyB0aGlzIDogdGhpc09iaiwgYUFyZ3MuY29uY2F0KEFycmF5W3Byb3RvXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTsgfTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoZnVuY1twcm90b10pXHJcbiAgICAgICAgICAgICAgICAgICAgZk5PUFtwcm90b10gPSBmdW5jW3Byb3RvXTsgLy8gRnVuY3Rpb24ucHJvdG90eXBlIGRvZXNuJ3QgaGF2ZSBhIHByb3RvdHlwZSBwcm9wZXJ0eVxyXG4gICAgICAgICAgICAgICAgZkJvdW5kW3Byb3RvXSA9IG5ldyBmTk9QKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZCb3VuZDtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY3VycmVudCB3aW5kb3cgd2lkdGguXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfG51bWJlcn0gVGhlIGN1cnJlbnQgd2luZG93IHdpZHRoIGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3VzogYmluZCh3aW5kb3dTaXplLCAwLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGN1cnJlbnQgd2luZG93IGhlaWdodC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtOdW1iZXJ8bnVtYmVyfSBUaGUgY3VycmVudCB3aW5kb3cgaGVpZ2h0IGluIHBpeGVsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICB3SDogYmluZCh3aW5kb3dTaXplLCAwKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZCBpZiBub3Qgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge011dGF0aW9uT2JzZXJ2ZXJ8Knx1bmRlZmluZWR9IFRoZSBNdXRhdGlvbnNPYnNlcnZlciBPYmplY3Qgb3IgdW5kZWZpbmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtTzogYmluZChWRU5ET1JTLl9qc0FQSSwgMCwgJ011dGF0aW9uT2JzZXJ2ZXInLCB0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFJlc2l6ZU9ic2VydmVyIE9iamVjdCBvciB1bmRlZmluZWQgaWYgbm90IHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtNdXRhdGlvbk9ic2VydmVyfCp8dW5kZWZpbmVkfSBUaGUgUmVzaXplT2JzZXJ2ZXIgT2JqZWN0IG9yIHVuZGVmaW5lZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgck86IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdSZXNpemVPYnNlcnZlcicsIHRydWUpLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgUmVxdWVzdEFuaW1hdGlvbkZyYW1lIG1ldGhvZCBvciBpdCdzIGNvcnJlc3BvbmRpbmcgcG9seWZpbGwuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7KnxGdW5jdGlvbn0gVGhlIFJlcXVlc3RBbmltYXRpb25GcmFtZSBtZXRob2Qgb3IgaXQncyBjb3JyZXNwb25kaW5nIHBvbHlmaWxsLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICByQUY6IGJpbmQoVkVORE9SUy5fanNBUEksIDAsICdyZXF1ZXN0QW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGZ1bmMpIHsgcmV0dXJuIHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmMsIDEwMDAgLyA2MCk7IH0pLFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfEZ1bmN0aW9ufSBUaGUgQ2FuY2VsQW5pbWF0aW9uRnJhbWUgbWV0aG9kIG9yIGl0J3MgY29ycmVzcG9uZGluZyBwb2x5ZmlsbC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY0FGOiBiaW5kKFZFTkRPUlMuX2pzQVBJLCAwLCAnY2FuY2VsQW5pbWF0aW9uRnJhbWUnLCBmYWxzZSwgZnVuY3Rpb24gKGlkKSB7IHJldHVybiB3aW5kb3cuY2xlYXJUaW1lb3V0KGlkKTsgfSksXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSBjdXJyZW50IHRpbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgY3VycmVudCB0aW1lLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBub3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGF0ZS5ub3cgJiYgRGF0ZS5ub3coKSB8fCBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyB0aGUgcHJvcGFnYXRpb24gb2YgdGhlIGdpdmVuIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBldmVudCBvZiB3aGljaCB0aGUgcHJvcGFnYXRpb24gc2hhbGwgYmUgc3RvcGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBzdHBQOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RvcFByb3BhZ2F0aW9uKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LmNhbmNlbEJ1YmJsZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUHJldmVudHMgdGhlIGRlZmF1bHQgYWN0aW9uIG9mIHRoZSBnaXZlbiBldmVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgb2Ygd2hpY2ggdGhlIGRlZmF1bHQgYWN0aW9uIHNoYWxsIGJlIHByZXZlbnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcHJ2RDogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0ICYmIGV2ZW50LmNhbmNlbGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5yZXR1cm5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHBhZ2VYIGFuZCBwYWdlWSB2YWx1ZXMgb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgcGFnZVggYW5kIHBhZ2VYIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7eDogbnVtYmVyLCB5OiBudW1iZXJ9fSB4ID0gcGFnZVggdmFsdWUsIHkgPSBwYWdlWSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgcGFnZTogZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUGFnZSA9ICdwYWdlJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2xpZW50ID0gJ2NsaWVudCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clggPSAnWCc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clkgPSAnWSc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldCB8fCBldmVudC5zcmNFbGVtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudERvYyA9IHRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb2MgPSBldmVudERvYy5kb2N1bWVudEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHkgPSBldmVudERvYy5ib2R5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIHRvdWNoIGV2ZW50IHJldHVybiByZXR1cm4gcGFnZVgvWSBvZiBpdFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRvdWNoID0gZXZlbnQudG91Y2hlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHRvdWNoW3N0clBhZ2UgKyBzdHJYXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHRvdWNoW3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgcGFnZVgvWSBpZiBub3QgbmF0aXZlIHN1cHBvcnRlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnRbc3RyUGFnZSArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICYmIGV2ZW50W3N0ckNsaWVudCArIHN0clhdICE9IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJDbGllbnQgKyBzdHJYXSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2Muc2Nyb2xsTGVmdCB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsTGVmdCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0ckNsaWVudCArIHN0clldICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZG9jICYmIGRvYy5zY3JvbGxUb3AgfHwgYm9keSAmJiBib2R5LnNjcm9sbFRvcCB8fCAwKSAtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRvYyAmJiBkb2MuY2xpZW50VG9wIHx8IGJvZHkgJiYgYm9keS5jbGllbnRUb3AgfHwgMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBldmVudFtzdHJQYWdlICsgc3RyWF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IGV2ZW50W3N0clBhZ2UgKyBzdHJZXVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2V0cyB0aGUgY2xpY2tlZCBtb3VzZSBidXR0b24gb2YgdGhlIGdpdmVuIG1vdXNlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBtb3VzZSBldmVudCBvZiB3aGljaCB0aGUgY2xpY2tlZCBidXR0b24gc2hhbCBiZSBnb3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIHRoZSBjbGlja2VkIG1vdXNlIGJ1dHRvbi4gKDAgOiBub25lIHwgMSA6IGxlZnRCdXR0b24gfCAyIDogbWlkZGxlQnV0dG9uIHwgMyA6IHJpZ2h0QnV0dG9uKVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBtQnRuOiBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoYnV0dG9uICYgMSA/IDEgOiAoYnV0dG9uICYgMiA/IDMgOiAoYnV0dG9uICYgNCA/IDIgOiAwKSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50LndoaWNoO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIGEgaXRlbSBpcyBpbiB0aGUgZ2l2ZW4gYXJyYXkgYW5kIHJldHVybnMgaXRzIGluZGV4LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGl0ZW0gVGhlIGl0ZW0gb2Ygd2hpY2ggdGhlIHBvc2l0aW9uIGluIHRoZSBhcnJheSBzaGFsbCBiZSBkZXRlcm1pbmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgemVybyBiYXNlZCBpbmRleCBvZiB0aGUgaXRlbSBvciAtMSBpZiB0aGUgaXRlbSBpc24ndCBpbiB0aGUgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGluQTogZnVuY3Rpb24gKGl0ZW0sIGFycikge1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9Tb21ldGllbXMgaW4gSUUgYSBcIlNDUklQVDcwXCIgUGVybWlzc2lvbiBkZW5pZWQgZXJyb3Igb2NjdXJzIGlmIEhUTUwgZWxlbWVudHMgaW4gYSBpRnJhbWUgYXJlIGNvbXBhcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyciBUaGUgcG90ZW50aWFsIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGEgYXJyYXksIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgaXNBOiBmdW5jdGlvbiAoYXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRlZiA9IEFycmF5LmlzQXJyYXk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlZiA/IGRlZihhcnIpIDogdGhpcy50eXBlKGFycikgPT0gVFlQRVMuYTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBEZXRlcm1pbmUgdGhlIGludGVybmFsIEphdmFTY3JpcHQgW1tDbGFzc11dIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3Qgb2Ygd2hpY2ggdGhlIHR5cGUgc2hhbGwgYmUgZGV0ZXJtaW5lZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0eXBlIG9mIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHR5cGU6IGZ1bmN0aW9uIChvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmogKyAnJztcclxuICAgICAgICAgICAgICAgICAgICBpZiAob2JqID09PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqICsgJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE9iamVjdFtMRVhJQ09OLnBdLnRvU3RyaW5nLmNhbGwob2JqKS5yZXBsYWNlKC9eXFxbb2JqZWN0ICguKylcXF0kLywgJyQxJykudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIGJpbmQ6IGJpbmRcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgYnkgdGhlIGdpdmVuIG5hbWUuXHJcbiAgICAgICAgICAgICAgICAgKiBGb3IgZXhhbXBsZSB0aGUgZ2l2ZW4gbmFtZSBpcyBcInRyYW5zZm9ybVwiIGFuZCB5b3UncmUgdXNpbmcgYSBvbGQgRmlyZWZveCBicm93c2VyIHRoZW4gdGhlIHJldHVybmVkIHZhbHVlIHdvdWxkIGJlIFwiLW1vei10cmFuc2Zvcm1cIi5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3QgbmVlZCBhIHZlbmRvci1wcmVmaXgsIHRoZW4gdGhlIHJldHVybmVkIHN0cmluZyBpcyB0aGUgZ2l2ZW4gbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZSBhdCBhbGwgKG5vdCBldmVuIHdpdGggYSB2ZW5kb3ItcHJlZml4KSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgbnVsbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcm9wTmFtZSBUaGUgdW5wcmVmaXhlZCBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gVGhlIHZlbmRvci1wcmVmaXhlZCBDU1MgcHJvcGVydHkgb3IgbnVsbCBpZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgdGhlIGdpdmVuIENTUyBwcm9wZXJ0eS5cclxuXHJcbiAgICAgICAgICAgICAgICBjc3NQcm9wOiBmdW5jdGlvbihwcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBWRU5ET1JTLl9jc3NQcm9wZXJ0eShwcm9wTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSkoKTtcclxuXHJcblxyXG4gICAgICAgIHZhciBNQVRIID0gTWF0aDtcclxuICAgICAgICB2YXIgSlFVRVJZID0gd2luZG93LmpRdWVyeTtcclxuICAgICAgICB2YXIgRUFTSU5HID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF9lYXNpbmdzTWF0aCA9IHtcclxuICAgICAgICAgICAgICAgIHA6IE1BVEguUEksXHJcbiAgICAgICAgICAgICAgICBjOiBNQVRILmNvcyxcclxuICAgICAgICAgICAgICAgIHM6IE1BVEguc2luLFxyXG4gICAgICAgICAgICAgICAgdzogTUFUSC5wb3csXHJcbiAgICAgICAgICAgICAgICB0OiBNQVRILnNxcnQsXHJcbiAgICAgICAgICAgICAgICBuOiBNQVRILmFzaW4sXHJcbiAgICAgICAgICAgICAgICBhOiBNQVRILmFicyxcclxuICAgICAgICAgICAgICAgIG86IDEuNzAxNThcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICB4IDogY3VycmVudCBwZXJjZW50ICgwIC0gMSksXHJcbiAgICAgICAgICAgICB0IDogY3VycmVudCB0aW1lIChkdXJhdGlvbiAqIHBlcmNlbnQpLFxyXG4gICAgICAgICAgICAgYiA6IHN0YXJ0IHZhbHVlIChmcm9tKSxcclxuICAgICAgICAgICAgIGMgOiBlbmQgdmFsdWUgKHRvKSxcclxuICAgICAgICAgICAgIGQgOiBkdXJhdGlvblxyXG5cclxuICAgICAgICAgICAgIGVhc2luZ05hbWUgOiBmdW5jdGlvbih4LCB0LCBiLCBjLCBkKSB7IHJldHVybiBlYXNlZFZhbHVlOyB9XHJcbiAgICAgICAgICAgICAqL1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIHN3aW5nOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwLjUgLSBfZWFzaW5nc01hdGguYyh4ICogX2Vhc2luZ3NNYXRoLnApIC8gMjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBsaW5lYXI6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHg7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhZDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICh0IC89IGQpICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YWQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC1jICogKHQgLz0gZCkgKiAodCAtIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRRdWFkOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICsgYiA6IC1jIC8gMiAqICgoLS10KSAqICh0IC0gMikgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluQ3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAoKHQgPSB0IC8gZCAtIDEpICogdCAqIHQgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q3ViaWM6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKyAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFF1YXJ0OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgLSAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0UXVhcnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgodCAvPSBkIC8gMikgPCAxKSA/IGMgLyAyICogdCAqIHQgKiB0ICogdCArIGIgOiAtYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogdCAqIHQgLSAyKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluUXVpbnQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiAodCAvPSBkKSAqIHQgKiB0ICogdCAqIHQgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRRdWludDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqICgodCA9IHQgLyBkIC0gMSkgKiB0ICogdCAqIHQgKiB0ICsgMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbk91dFF1aW50OiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqIHQgKiB0ICogdCAqIHQgKiB0ICsgYiA6IGMgLyAyICogKCh0IC09IDIpICogdCAqIHQgKiB0ICogdCArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5TaW5lOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIF9lYXNpbmdzTWF0aC5jKHQgLyBkICogKF9lYXNpbmdzTWF0aC5wIC8gMikpICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dFNpbmU6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGMgKiBfZWFzaW5nc01hdGgucyh0IC8gZCAqIChfZWFzaW5nc01hdGgucCAvIDIpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0U2luZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gLWMgLyAyICogKF9lYXNpbmdzTWF0aC5jKF9lYXNpbmdzTWF0aC5wICogdCAvIGQpIC0gMSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IDApID8gYiA6IGMgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC8gZCAtIDEpKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZU91dEV4cG86IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh0ID09IGQpID8gYiArIGMgOiBjICogKC1fZWFzaW5nc01hdGgudygyLCAtMTAgKiB0IC8gZCkgKyAxKSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RXhwbzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSBkKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQgLyAyKSA8IDEpIHJldHVybiBjIC8gMiAqIF9lYXNpbmdzTWF0aC53KDIsIDEwICogKHQgLSAxKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjIC8gMiAqICgtX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogLS10KSArIDIpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5DaXJjOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtYyAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLz0gZCkgKiB0KSAtIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIF9lYXNpbmdzTWF0aC50KDEgLSAodCA9IHQgLyBkIC0gMSkgKiB0KSArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Q2lyYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCh0IC89IGQgLyAyKSA8IDEpID8gLWMgLyAyICogKF9lYXNpbmdzTWF0aC50KDEgLSB0ICogdCkgLSAxKSArIGIgOiBjIC8gMiAqIChfZWFzaW5nc01hdGgudCgxIC0gKHQgLT0gMikgKiB0KSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5FbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiOyBpZiAoKHQgLz0gZCkgPT0gMSkgcmV0dXJuIGIgKyBjOyBpZiAoIXApIHAgPSBkICogLjM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGEgPCBfZWFzaW5nc01hdGguYShjKSkgeyBhID0gYzsgcyA9IHAgLyA0OyB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBzID0gcCAvICgyICogX2Vhc2luZ3NNYXRoLnApICogX2Vhc2luZ3NNYXRoLm4oYyAvIGEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRFbGFzdGljOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzID0gX2Vhc2luZ3NNYXRoLm87IHZhciBwID0gMDsgdmFyIGEgPSBjO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDApIHJldHVybiBiO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodCAvPSBkKSA9PSAxKSByZXR1cm4gYiArIGM7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFwKSBwID0gZCAqIC4zO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhIDwgX2Vhc2luZ3NNYXRoLmEoYykpIHsgYSA9IGM7IHMgPSBwIC8gNDsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcyA9IHAgLyAoMiAqIF9lYXNpbmdzTWF0aC5wKSAqIF9lYXNpbmdzTWF0aC5uKGMgLyBhKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSAqIF9lYXNpbmdzTWF0aC53KDIsIC0xMCAqIHQpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICsgYyArIGI7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0RWxhc3RpYzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IF9lYXNpbmdzTWF0aC5vOyB2YXIgcCA9IDA7IHZhciBhID0gYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAwKSByZXR1cm4gYjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHQgLz0gZCAvIDIpID09IDIpIHJldHVybiBiICsgYztcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXApIHAgPSBkICogKC4zICogMS41KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYSA8IF9lYXNpbmdzTWF0aC5hKGMpKSB7IGEgPSBjOyBzID0gcCAvIDQ7IH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHMgPSBwIC8gKDIgKiBfZWFzaW5nc01hdGgucCkgKiBfZWFzaW5nc01hdGgubihjIC8gYSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgPCAxKSByZXR1cm4gLS41ICogKGEgKiBfZWFzaW5nc01hdGgudygyLCAxMCAqICh0IC09IDEpKSAqIF9lYXNpbmdzTWF0aC5zKCh0ICogZCAtIHMpICogKDIgKiBfZWFzaW5nc01hdGgucCkgLyBwKSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhICogX2Vhc2luZ3NNYXRoLncoMiwgLTEwICogKHQgLT0gMSkpICogX2Vhc2luZ3NNYXRoLnMoKHQgKiBkIC0gcykgKiAoMiAqIF9lYXNpbmdzTWF0aC5wKSAvIHApICogLjUgKyBjICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5CYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKHQgLz0gZCkgKiB0ICogKChzICsgMSkgKiB0IC0gcykgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKCh0ID0gdCAvIGQgLSAxKSAqIHQgKiAoKHMgKyAxKSAqIHQgKyBzKSArIDEpICsgYjtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBlYXNlSW5PdXRCYWNrOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCwgcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBzIHx8IF9lYXNpbmdzTWF0aC5vO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoKHQgLz0gZCAvIDIpIDwgMSkgPyBjIC8gMiAqICh0ICogdCAqICgoKHMgKj0gKDEuNTI1KSkgKyAxKSAqIHQgLSBzKSkgKyBiIDogYyAvIDIgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCArIHMpICsgMikgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VJbkJvdW5jZTogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAtIHRoaXMuZWFzZU91dEJvdW5jZSh4LCBkIC0gdCwgMCwgYywgZCkgKyBiO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGVhc2VPdXRCb3VuY2U6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG8gPSA3LjU2MjU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0IC89IGQpIDwgKDEgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogdCAqIHQpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHQgPCAoMiAvIDIuNzUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjICogKG8gKiAodCAtPSAoMS41IC8gMi43NSkpICogdCArIC43NSkgKyBiO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodCA8ICgyLjUgLyAyLjc1KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuMjUgLyAyLjc1KSkgKiB0ICsgLjkzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYyAqIChvICogKHQgLT0gKDIuNjI1IC8gMi43NSkpICogdCArIC45ODQzNzUpICsgYjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZWFzZUluT3V0Qm91bmNlOiBmdW5jdGlvbiAoeCwgdCwgYiwgYywgZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAodCA8IGQgLyAyKSA/IHRoaXMuZWFzZUluQm91bmNlKHgsIHQgKiAyLCAwLCBjLCBkKSAqIC41ICsgYiA6IHRoaXMuZWFzZU91dEJvdW5jZSh4LCB0ICogMiAtIGQsIDAsIGMsIGQpICogLjUgKyBjICogLjUgKyBiO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgKiBURVJNUyBPRiBVU0UgLSBFQVNJTkcgRVFVQVRJT05TXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgQlNEIExpY2Vuc2UuIFxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogQ29weXJpZ2h0IMOCwqkgMjAwMSBSb2JlcnQgUGVubmVyXHJcbiAgICAgICAgICAgICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBcclxuICAgICAgICAgICAgICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgXHJcbiAgICAgICAgICAgICAqIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cclxuICAgICAgICAgICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3QgXHJcbiAgICAgICAgICAgICAqIG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIFxyXG4gICAgICAgICAgICAgKiBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXHJcbiAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBhdXRob3Igbm9yIHRoZSBuYW1lcyBvZiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBcclxuICAgICAgICAgICAgICogb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20gdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi5cclxuICAgICAgICAgICAgICogXHJcbiAgICAgICAgICAgICAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiIEFORCBBTlkgXHJcbiAgICAgICAgICAgICAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRlxyXG4gICAgICAgICAgICAgKiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcclxuICAgICAgICAgICAgICogIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCxcclxuICAgICAgICAgICAgICogIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURVxyXG4gICAgICAgICAgICAgKiAgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIFxyXG4gICAgICAgICAgICAgKiBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElOR1xyXG4gICAgICAgICAgICAgKiAgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgXHJcbiAgICAgICAgICAgICAqIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4gXHJcbiAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgIH0pKCk7XHJcbiAgICAgICAgdmFyIEZSQU1FV09SSyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBfcm5vdGh0bWx3aGl0ZSA9ICgvW15cXHgyMFxcdFxcclxcblxcZl0rL2cpO1xyXG4gICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICB2YXIgX3N0ckVtcHR5ID0gJyc7XHJcbiAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsTGVmdCA9ICdzY3JvbGxMZWZ0JztcclxuICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxUb3AgPSAnc2Nyb2xsVG9wJztcclxuICAgICAgICAgICAgdmFyIF9hbmltYXRpb25zID0gW107XHJcbiAgICAgICAgICAgIHZhciBfdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgdmFyIF9jc3NOdW1iZXIgPSB7XHJcbiAgICAgICAgICAgICAgICBhbmltYXRpb25JdGVyYXRpb25Db3VudDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbHVtbkNvdW50OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmbGV4R3JvdzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGZsZXhTaHJpbms6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBvcmRlcjogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIG9ycGhhbnM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB3aWRvd3M6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB6b29tOiB0cnVlXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBleHRlbmQoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3JjLCBjb3B5SXNBcnJheSwgY29weSwgbmFtZSwgb3B0aW9ucywgY2xvbmUsIHRhcmdldCA9IGFyZ3VtZW50c1swXSB8fCB7fSxcclxuICAgICAgICAgICAgICAgICAgICBpID0gMSxcclxuICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBhcmd1bWVudHNbTEVYSUNPTi5sXSxcclxuICAgICAgICAgICAgICAgICAgICBkZWVwID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHRhcmdldCkgPT0gVFlQRVMuYikge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlZXAgPSB0YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gYXJndW1lbnRzWzFdIHx8IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcclxuICAgICAgICAgICAgICAgICAgICBpID0gMjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcclxuICAgICAgICAgICAgICAgIGlmIChfdHlwZSh0YXJnZXQpICE9IFRZUEVTLm8gJiYgIV90eXBlKHRhcmdldCkgPT0gVFlQRVMuZikge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIGV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxyXG4gICAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldCA9IEZha2VqUXVlcnk7XHJcbiAgICAgICAgICAgICAgICAgICAgLS1pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChvcHRpb25zID0gYXJndW1lbnRzW2ldKSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUgYmFzZSBvYmplY3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChuYW1lIGluIG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYyA9IHRhcmdldFtuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkgPSBvcHRpb25zW25hbWVdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IGNvcHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZWVwICYmIGNvcHkgJiYgKGlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0gQ09NUEFUSUJJTElUWS5pc0EoY29weSkpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3B5SXNBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5SXNBcnJheSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZSA9IHNyYyAmJiBDT01QQVRJQklMSVRZLmlzQShzcmMpID8gc3JjIDogW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lID0gc3JjICYmIGlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTmV2ZXIgbW92ZSBvcmlnaW5hbCBvYmplY3RzLCBjbG9uZSB0aGVtXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W25hbWVdID0gZXh0ZW5kKGRlZXAsIGNsb25lLCBjb3B5KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb3B5ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbbmFtZV0gPSBjb3B5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaW5BcnJheShpdGVtLCBhcnIsIGZyb21JbmRleCkge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IGZyb21JbmRleCB8fCAwOyBpIDwgYXJyW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcclxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gaXNGdW5jdGlvbihvYmopIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBfdHlwZShvYmopID09IFRZUEVTLmY7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc0VtcHR5T2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmopXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iaikge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFvYmogfHwgX3R5cGUob2JqKSAhPSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIga2V5O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb3RvID0gTEVYSUNPTi5wO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0W3Byb3RvXS5oYXNPd25Qcm9wZXJ0eTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNPd25Db25zdHJ1Y3RvciA9IGhhc093blByb3BlcnR5LmNhbGwob2JqLCAnY29uc3RydWN0b3InKTtcclxuICAgICAgICAgICAgICAgIHZhciBoYXNJc1Byb3RvdHlwZU9mID0gb2JqLmNvbnN0cnVjdG9yICYmIG9iai5jb25zdHJ1Y3Rvcltwcm90b10gJiYgaGFzT3duUHJvcGVydHkuY2FsbChvYmouY29uc3RydWN0b3JbcHJvdG9dLCAnaXNQcm90b3R5cGVPZicpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChvYmouY29uc3RydWN0b3IgJiYgIWhhc093bkNvbnN0cnVjdG9yICYmICFoYXNJc1Byb3RvdHlwZU9mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHsgLyoqLyB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIF90eXBlKGtleSkgPT0gVFlQRVMudSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGVhY2gob2JqLCBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5TGlrZShvYmopKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBvYmpbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjay5jYWxsKG9ialtpXSwgaSwgb2JqW2ldKSA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iajtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGlzQXJyYXlMaWtlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9ICEhb2JqICYmIFtMRVhJQ09OLmxdIGluIG9iaiAmJiBvYmpbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciB0ID0gX3R5cGUob2JqKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKHQpID8gZmFsc2UgOiAodCA9PSBUWVBFUy5hIHx8IGxlbmd0aCA9PT0gMCB8fCBfdHlwZShsZW5ndGgpID09IFRZUEVTLm4gJiYgbGVuZ3RoID4gMCAmJiAobGVuZ3RoIC0gMSkgaW4gb2JqKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0b2tlbnMuam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBtYXRjaGVzKGVsZW0sIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm9kZUxpc3QgPSAoZWxlbS5wYXJlbnROb2RlIHx8IGRvY3VtZW50KS5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSB8fCBbXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gbm9kZUxpc3RbTEVYSUNPTi5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlTGlzdFtpXSA9PSBlbGVtKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY2hpbGQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGlsZFtMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydEFkamFjZW50RWxlbWVudChlbCwgc3RyYXRlZ3ksIGNoaWxkW2ldKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKF90eXBlKGNoaWxkKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50SFRNTChzdHJhdGVneSwgY2hpbGQpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgIGVsLmluc2VydEFkamFjZW50RWxlbWVudChzdHJhdGVneSwgY2hpbGQubm9kZVR5cGUgPyBjaGlsZCA6IGNoaWxkWzBdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsW0xFWElDT04uc11bcHJvcF0gIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbTEVYSUNPTi5zXVtwcm9wXSA9IHBhcnNlQ1NTVmFsKHByb3AsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VDU1NWYWwocHJvcCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9jc3NOdW1iZXJbcHJvcC50b0xvd2VyQ2FzZSgpXSAmJiBfdHlwZSh2YWwpID09IFRZUEVTLm4pXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsICs9ICdweCc7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaiwgcmVtb3ZlRnJvbVEpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpbmRleDtcclxuICAgICAgICAgICAgICAgIHZhciBuZXh0QW5pbTtcclxuICAgICAgICAgICAgICAgIGlmIChyZW1vdmVGcm9tUSAhPT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iai5xLnNwbGljZSgwLCAxKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLnFbTEVYSUNPTi5sXSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0QW5pbSA9IGFuaW1PYmoucVswXTtcclxuICAgICAgICAgICAgICAgICAgICBhbmltYXRlKGFuaW1PYmouZWwsIG5leHRBbmltLnByb3BzLCBuZXh0QW5pbS5kdXJhdGlvbiwgbmV4dEFuaW0uZWFzaW5nLCBuZXh0QW5pbS5jb21wbGV0ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGluQXJyYXkoYW5pbU9iaiwgX2FuaW1hdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzZXRBbmltYXRpb25WYWx1ZShlbCwgcHJvcCwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwcm9wID09PSBfc3RyU2Nyb2xsTGVmdCB8fCBwcm9wID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgIGVsW3Byb3BdID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKGVsLCBwcm9wLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGFuaW1hdGUoZWwsIHByb3BzLCBvcHRpb25zLCBlYXNpbmcsIGNvbXBsZXRlLCBndWFyYW50ZWVkTmV4dCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc09wdGlvbnMgPSBpc1BsYWluT2JqZWN0KG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZyb20gPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciB0byA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBhbmltT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgdmFyIHByb2dyZXNzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ZXA7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGlmIChoYXNPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWFzaW5nID0gb3B0aW9ucy5lYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSBvcHRpb25zLnN0YXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgIHByb2dyZXNzID0gb3B0aW9ucy5wcm9ncmVzcztcclxuICAgICAgICAgICAgICAgICAgICBzdGVwID0gb3B0aW9ucy5zdGVwO1xyXG4gICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmcgPSBvcHRpb25zLnNwZWNpYWxFYXNpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUgPSBvcHRpb25zLmNvbXBsZXRlO1xyXG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gb3B0aW9ucy5kdXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBzcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZyB8fCB7fTtcclxuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gZHVyYXRpb24gfHwgNDAwO1xyXG4gICAgICAgICAgICAgICAgZWFzaW5nID0gZWFzaW5nIHx8ICdzd2luZyc7XHJcbiAgICAgICAgICAgICAgICBndWFyYW50ZWVkTmV4dCA9IGd1YXJhbnRlZWROZXh0IHx8IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9hbmltYXRpb25zW2ldLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0gX2FuaW1hdGlvbnNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFuaW1PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbDogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHE6IFtdXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBfYW5pbWF0aW9ucy5wdXNoKGFuaW1PYmopO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoa2V5IGluIHByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gX3N0clNjcm9sbExlZnQgfHwga2V5ID09PSBfc3RyU2Nyb2xsVG9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tW2tleV0gPSBlbFtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbVtrZXldID0gRmFrZWpRdWVyeShlbCkuY3NzKGtleSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gZnJvbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmcm9tW2tleV0gIT09IHByb3BzW2tleV0gJiYgcHJvcHNba2V5XSAhPT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0b1trZXldID0gcHJvcHNba2V5XTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmplY3QodG8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVOb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGVyY2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZnJvbVZhbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdG9WYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVhc2VkVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0aW1lU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZyYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGFwc2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxUG9zID0gZ3VhcmFudGVlZE5leHQgPyAwIDogaW5BcnJheShxT2JqLCBhbmltT2JqLnEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBxT2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wczogdG8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBoYXNPcHRpb25zID8gb3B0aW9ucyA6IGR1cmF0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocVBvcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcVBvcyA9IGFuaW1PYmoucVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEucHVzaChxT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChxUG9zID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVTdGFydCA9IENPTVBBVElCSUxJVFkubm93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lTm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGFwc2VkID0gKHRpbWVOb3cgLSB0aW1lU3RhcnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCA9IHFPYmouc3RvcCB8fCBlbGFwc2VkID49IGR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlcmNlbnQgPSAxIC0gKChNQVRILm1heCgwLCB0aW1lU3RhcnQgKyBkdXJhdGlvbiAtIHRpbWVOb3cpIC8gZHVyYXRpb24pIHx8IDApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiB0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tVmFsID0gcGFyc2VGbG9hdChmcm9tW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b1ZhbCA9IHBhcnNlRmxvYXQodG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2VkVmFsID0gKHRvVmFsIC0gZnJvbVZhbCkgKiBFQVNJTkdbc3BlY2lhbEVhc2luZ1trZXldIHx8IGVhc2luZ10ocGVyY2VudCwgcGVyY2VudCAqIGR1cmF0aW9uLCAwLCAxLCBkdXJhdGlvbikgKyBmcm9tVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRBbmltYXRpb25WYWx1ZShlbCwga2V5LCBlYXNlZFZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHN0ZXApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwKGVhc2VkVmFsLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbTogZWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcDoga2V5LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBmcm9tVmFsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdzogZWFzZWRWYWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kOiB0b1ZhbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3M6IHBlcmNlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXNpbmc6IGVhc2luZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlYWNpYWxFYXNpbmc6IHNwZWNpYWxFYXNpbmcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGU6IGNvbXBsZXRlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwOiBzdGVwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFRpbWU6IHRpbWVTdGFydFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKHByb2dyZXNzKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ3Jlc3Moe30sIHBlcmNlbnQsIE1BVEgubWF4KDAsIGR1cmF0aW9uIC0gZWxhcHNlZCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oY29tcGxldGUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqLmZyYW1lID0gQ09NUEFUSUJJTElUWS5yQUYoKShmcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5mcmFtZSA9IENPTVBBVElCSUxJVFkuckFGKCkoZnJhbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gdG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgdG9ba2V5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChndWFyYW50ZWVkTmV4dClcclxuICAgICAgICAgICAgICAgICAgICBzdGFydE5leHRBbmltYXRpb25JblEoYW5pbU9iaik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIHN0b3AoZWwsIGNsZWFyUSwganVtcFRvRW5kKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYW5pbU9iajtcclxuICAgICAgICAgICAgICAgIHZhciBxT2JqO1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX2FuaW1hdGlvbnNbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5pbU9iaiA9IF9hbmltYXRpb25zW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhbmltT2JqLmVsID09PSBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5pbU9iai5xW0xFWElDT04ubF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxT2JqID0gYW5pbU9iai5xWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcU9iai5zdG9wID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkocU9iai5mcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltT2JqLnEuc3BsaWNlKDAsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqdW1wVG9FbmQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gcU9iai5wcm9wcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0QW5pbWF0aW9uVmFsdWUoZWwsIGtleSwgcU9iai5wcm9wc1trZXldKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xlYXJRKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1PYmoucSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0TmV4dEFuaW1hdGlvbkluUShhbmltT2JqLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBlbGVtZW50SXNWaXNpYmxlKGVsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gISEoZWxbTEVYSUNPTi5vV10gfHwgZWxbTEVYSUNPTi5vSF0gfHwgZWwuZ2V0Q2xpZW50UmVjdHMoKVtMRVhJQ09OLmxdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gRmFrZWpRdWVyeShzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tMRVhJQ09OLmxdID09PSAwKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgICAgICAgICAgICAgIHZhciBiYXNlID0gbmV3IEZha2VqUXVlcnkoKTtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IHNlbGVjdG9yO1xyXG4gICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgdmFyIGVsbXM7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWw7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKF90eXBlKHNlbGVjdG9yKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudHMgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IuY2hhckF0KDApID09PSAnPCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuaW5uZXJIVE1MID0gc2VsZWN0b3I7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBlbC5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsbXMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goZWxtc1tpXSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKGVsZW1lbnRzKSAhPSBUWVBFUy5zICYmICghaXNBcnJheUxpa2UoZWxlbWVudHMpIHx8IGVsZW1lbnRzID09PSB3aW5kb3cgfHwgZWxlbWVudHMgPT09IGVsZW1lbnRzLnNlbGYpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlbGVtZW50c1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2VbaV0gPSBlbGVtZW50c1tpXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYmFzZVtMRVhJQ09OLmxdID0gZWxlbWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIEZha2VqUXVlcnlbTEVYSUNPTi5wXSA9IHtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0VWRU5UUzpcclxuXHJcbiAgICAgICAgICAgICAgICBvbjogZnVuY3Rpb24gKGV2ZW50TmFtZSwgaGFuZGxlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TmFtZSA9IChldmVudE5hbWUgfHwgX3N0ckVtcHR5KS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW19zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudE5hbWVMZW5ndGggPSBldmVudE5hbWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWwuYWRkRXZlbnRMaXN0ZW5lcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lW2ldLCBoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsLmRldGFjaEV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVMZW5ndGg7IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwuYXR0YWNoRXZlbnQoJ29uJyArIGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBvZmY6IGZ1bmN0aW9uIChldmVudE5hbWUsIGhhbmRsZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBldmVudE5hbWUgPSAoZXZlbnROYW1lIHx8IF9zdHJFbXB0eSkubWF0Y2goX3Jub3RodG1sd2hpdGUpIHx8IFtfc3RyRW1wdHldO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnROYW1lTGVuZ3RoID0gZXZlbnROYW1lW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50TmFtZUxlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZVtpXSwgaGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlbC5kZXRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgZXZlbnROYW1lTGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmRldGFjaEV2ZW50KCdvbicgKyBldmVudE5hbWVbaV0sIGhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgb25lOiBmdW5jdGlvbiAoZXZlbnROYW1lLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXZlbnROYW1lID0gKGV2ZW50TmFtZSB8fCBfc3RyRW1wdHkpLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbX3N0ckVtcHR5XTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgRmFrZWpRdWVyeS5lYWNoKGV2ZW50TmFtZSwgZnVuY3Rpb24gKGksIG9uZUV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uZUhhbmRsZXIgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vZmYob25lRXZlbnROYW1lLCBvbmVIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5vbihvbmVFdmVudE5hbWUsIG9uZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5pbml0RXZlbnQoZXZlbnROYW1lLCB0cnVlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmZpcmVFdmVudCgnb24nICsgZXZlbnROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICAvL0RPTSBOT0RFIElOU0VSVElORyAvIFJFTU9WSU5HOlxyXG5cclxuICAgICAgICAgICAgICAgIGFwcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlZW5kJywgY2hpbGQpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcHJlcGVuZDogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJiZWdpbicsIGNoaWxkKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGJlZm9yZTogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYmVmb3JlYmVnaW4nLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBhZnRlcjogZnVuY3Rpb24gKGNoaWxkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IGluc2VydEFkamFjZW50RWxlbWVudCh0aGlzLCAnYWZ0ZXJlbmQnLCBjaGlsZCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmU6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudE5vZGUgPSBlbC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZSAhPSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHVud3JhcDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnRzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IHRoaXMucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkocGFyZW50LCBwYXJlbnRzKSA9PT0gLSAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKHBhcmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwYXJlbnRzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbCA9IHBhcmVudHNbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGVsLnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbC5maXJzdENoaWxkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShlbC5maXJzdENoaWxkLCBlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcEFsbDogZnVuY3Rpb24gKHdyYXBwZXJIVE1MKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd3JhcHBlciA9IEZha2VqUXVlcnkod3JhcHBlckhUTUwpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkZWVwZXN0ID0gd3JhcHBlcjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gbm9kZXNbMF0ucGFyZW50Tm9kZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcHJldmlvdXNTaWJsaW5nID0gbm9kZXNbMF0ucHJldmlvdXNTaWJsaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChkZWVwZXN0LmNoaWxkTm9kZXNbTEVYSUNPTi5sXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZXBlc3QgPSBkZWVwZXN0LmNoaWxkTm9kZXNbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IG5vZGVzW0xFWElDT04ubF0gLSBpOyBkZWVwZXN0LmZpcnN0Q2hpbGQgPT09IG5vZGVzWzBdICYmIGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVlcGVzdC5hcHBlbmRDaGlsZChub2Rlc1tpXSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXh0U2libGluZyA9IHByZXZpb3VzU2libGluZyA/IHByZXZpb3VzU2libGluZy5uZXh0U2libGluZyA6IHBhcmVudC5maXJzdENoaWxkO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUod3JhcHBlciwgbmV4dFNpYmxpbmcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgd3JhcElubmVyOiBmdW5jdGlvbiAod3JhcHBlckhUTUwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gRmFrZWpRdWVyeSh0aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRzID0gZWwuY29udGVudHMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb250ZW50c1tMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudHMud3JhcEFsbCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsLmFwcGVuZCh3cmFwcGVySFRNTCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHdyYXA6IGZ1bmN0aW9uICh3cmFwcGVySFRNTCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBGYWtlalF1ZXJ5KHRoaXMpLndyYXBBbGwod3JhcHBlckhUTUwpOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIE5PREUgTUFOSVBVTEFUSU9OIC8gSU5GT1JNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgY3NzOiBmdW5jdGlvbiAoc3R5bGVzLCB2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGtleTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3B0U3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldENwdFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90eXBlKHN0eWxlcykgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwdFN0eWxlID0gZ2V0Q3B0U3R5bGUgPyBnZXRDcHRTdHlsZShlbCwgbnVsbCkgOiBlbC5jdXJyZW50U3R5bGVbc3R5bGVzXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2h0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTU0ODM5NyBjYW4gYmUgbnVsbCBzb21ldGltZXMgaWYgaWZyYW1lIHdpdGggZGlzcGxheTogbm9uZSAoZmlyZWZveCBvbmx5ISlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRDcHRTdHlsZSA/IGNwdFN0eWxlICE9IG51bGwgPyBjcHRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlcykgOiBlbFtMRVhJQ09OLnNdW3N0eWxlc10gOiBjcHRTdHlsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENTU1ZhbCh0aGlzLCBzdHlsZXMsIHZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBzdHlsZXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Q1NTVmFsKHRoaXMsIGtleSwgc3R5bGVzW2tleV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGhhc0NsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW0sIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVQcmVwYXJlZCA9IF9zdHJTcGFjZSArIGNsYXNzTmFtZSArIF9zdHJTcGFjZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NMaXN0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NMaXN0ICYmIGNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoZWxlbS5jbGFzc05hbWUgKyBfc3RyRW1wdHkpICsgX3N0clNwYWNlKS5pbmRleE9mKGNsYXNzTmFtZVByZXBhcmVkKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIGFkZENsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzZXM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1cjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXp6O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdXBwb3J0Q2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbG1DbGFzc0xpc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLm1hdGNoKF9ybm90aHRtbHdoaXRlKSB8fCBbXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgoZWxlbSA9IHRoaXNbaSsrXSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdCA9IGVsZW0uY2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0Q2xhc3NMaXN0ID0gZWxtQ2xhc3NMaXN0ICE9PSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN1cHBvcnRDbGFzc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxtQ2xhc3NMaXN0LmFkZChjbGF6eik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJWYWx1ZSA9IGVsZW0uY2xhc3NOYW1lICsgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKF9zdHJTcGFjZSArIHN0cmlwQW5kQ29sbGFwc2UoY3VyVmFsdWUpICsgX3N0clNwYWNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGNsYXp6ID0gY2xhc3Nlc1t2KytdKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIuaW5kZXhPZihfc3RyU3BhY2UgKyBjbGF6eiArIF9zdHJTcGFjZSkgPCAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ciArPSBjbGF6eiArIF9zdHJTcGFjZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKGN1cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0uY2xhc3NOYW1lID0gZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICByZW1vdmVDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc2VzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1clZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGF6ejtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3VwcG9ydENsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxtQ2xhc3NMaXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NlcyA9IGNsYXNzTmFtZS5tYXRjaChfcm5vdGh0bWx3aGl0ZSkgfHwgW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKGVsZW0gPSB0aGlzW2krK10pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbG1DbGFzc0xpc3QgPSBlbGVtLmNsYXNzTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0ID09PSB1bmRlZmluZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VwcG9ydENsYXNzTGlzdCA9IGVsbUNsYXNzTGlzdCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdXBwb3J0Q2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsbUNsYXNzTGlzdC5yZW1vdmUoY2xhenopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyVmFsdWUgPSBlbGVtLmNsYXNzTmFtZSArIF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmIChfc3RyU3BhY2UgKyBzdHJpcEFuZENvbGxhcHNlKGN1clZhbHVlKSArIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKChjbGF6eiA9IGNsYXNzZXNbdisrXSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY3VyLmluZGV4T2YoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UpID4gLTEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyID0gY3VyLnJlcGxhY2UoX3N0clNwYWNlICsgY2xhenogKyBfc3RyU3BhY2UsIF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gc3RyaXBBbmRDb2xsYXBzZShjdXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgaGlkZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyB0aGlzW0xFWElDT04uc10uZGlzcGxheSA9ICdub25lJzsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHNob3c6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHsgdGhpc1tMRVhJQ09OLnNdLmRpc3BsYXkgPSAnYmxvY2snOyB9KTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgYXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWw7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGVsID0gdGhpc1tpKytdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsLmdldEF0dHJpYnV0ZShhdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcmVtb3ZlQXR0cjogZnVuY3Rpb24gKGF0dHJOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHRoaXMucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIG9mZnNldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBlbFtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsTGVmdCA9IHdpbmRvdy5wYWdlWE9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbX3N0clNjcm9sbExlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxUb3AgPSB3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50W19zdHJTY3JvbGxUb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKyBzY3JvbGxUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3QubGVmdCArIHNjcm9sbExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbCA9IHRoaXNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBlbC5vZmZzZXRUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IGVsLm9mZnNldExlZnRcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzY3JvbGxMZWZ0OiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsTGVmdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsW19zdHJTY3JvbGxMZWZ0XSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChlbCA9IHRoaXNbaSsrXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbFtfc3RyU2Nyb2xsVG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxbX3N0clNjcm9sbFRvcF0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgICAgIHZhbDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsID0gdGhpc1swXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWwudmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZWwudmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vRE9NIFRSQVZFUlNBTCAvIEZJTFRFUklORzpcclxuXHJcbiAgICAgICAgICAgICAgICBmaXJzdDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVxKDApO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBsYXN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXEoLTEpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBlcTogZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnkodGhpc1tpbmRleCA+PSAwID8gaW5kZXggOiB0aGlzW0xFWElDT04ubF0gKyBpbmRleF0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBmaW5kOiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWwgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2ggPSBlbC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY2hbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgY2hpbGRyZW46IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gdGhpcy5jaGlsZHJlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSBjaFtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoZWwubWF0Y2hlcyAmJiBlbC5tYXRjaGVzKHNlbGVjdG9yKSkgfHwgbWF0Y2hlcyhlbCwgc2VsZWN0b3IpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNoaWxkcmVuKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgcGFyZW50OiBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXJlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPyBGYWtlalF1ZXJ5KHBhcmVudCkuaXMoc2VsZWN0b3IpIDogdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHMucHVzaChwYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KHBhcmVudHMpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBpczogZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWwgPSB0aGlzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IgPT09ICc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudElzVmlzaWJsZShlbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RvciA9PT0gJzpoaWRkZW4nKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFlbGVtZW50SXNWaXNpYmxlKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChlbC5tYXRjaGVzICYmIGVsLm1hdGNoZXMoc2VsZWN0b3IpKSB8fCBtYXRjaGVzKGVsLCBzZWxlY3RvcikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBjb250ZW50czogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50cyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZHM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcyA9IHRoaXMuY2hpbGROb2RlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoaWxkc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cy5wdXNoKGNoaWxkc1tpXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWtlalF1ZXJ5KGNvbnRlbnRzKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcblxyXG4gICAgICAgICAgICAgICAgZWFjaDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVhY2godGhpcywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy9BTklNQVRJT046XHJcblxyXG4gICAgICAgICAgICAgICAgYW5pbWF0ZTogZnVuY3Rpb24gKHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkgeyBhbmltYXRlKHRoaXMsIHByb3BzLCBkdXJhdGlvbiwgZWFzaW5nLCBjb21wbGV0ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuXHJcbiAgICAgICAgICAgICAgICBzdG9wOiBmdW5jdGlvbiAoY2xlYXJRLCBqdW1wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7IHN0b3AodGhpcywgY2xlYXJRLCBqdW1wKTsgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBleHRlbmQoRmFrZWpRdWVyeSwge1xyXG4gICAgICAgICAgICAgICAgZXh0ZW5kOiBleHRlbmQsXHJcbiAgICAgICAgICAgICAgICBpbkFycmF5OiBpbkFycmF5LFxyXG4gICAgICAgICAgICAgICAgaXNFbXB0eU9iamVjdDogaXNFbXB0eU9iamVjdCxcclxuICAgICAgICAgICAgICAgIGlzUGxhaW5PYmplY3Q6IGlzUGxhaW5PYmplY3QsXHJcbiAgICAgICAgICAgICAgICBlYWNoOiBlYWNoXHJcbiAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIEZha2VqUXVlcnk7XHJcbiAgICAgICAgfSkoKTtcclxuICAgICAgICB2YXIgSU5TVEFOQ0VTID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIF90YXJnZXRzID0gW107XHJcbiAgICAgICAgICAgIHZhciBfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZyA9ICdfX292ZXJsYXlTY3JvbGxiYXJzX18nO1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFJlZ2lzdGVyLCB1bnJlZ2lzdGVyIG9yIGdldCBhIGNlcnRhaW4gKG9yIGFsbCkgaW5zdGFuY2VzLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgdGFyZ2V0IGFuZCB0aGUgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIFVucmVnaXN0ZXI6IFBhc3MgdGhlIHRhcmdldCBhbmQgbnVsbC5cclxuICAgICAgICAgICAgICogR2V0IEluc3RhbmNlOiBQYXNzIHRoZSB0YXJnZXQgZnJvbSB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgVGFyZ2V0czogUGFzcyBubyBhcmd1bWVudHMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXQgVGhlIHRhcmdldCB0byB3aGljaCB0aGUgaW5zdGFuY2Ugc2hhbGwgYmUgcmVnaXN0ZXJlZCAvIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIHVucmVnaXN0ZXJlZCAvIHRoZSBpbnN0YW5jZSBzaGFsbCBiZSBnb3RcclxuICAgICAgICAgICAgICogQHBhcmFtIGluc3RhbmNlIFRoZSBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp8dm9pZH0gUmV0dXJucyB0aGUgaW5zdGFuY2UgZnJvbSB0aGUgZ2l2ZW4gdGFyZ2V0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXJnTGVuID0gYXJndW1lbnRzW0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJnTGVuIDwgMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGFsbCB0YXJnZXRzXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVnaXN0ZXIgaW5zdGFuY2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W19pbnN0YW5jZVByb3BlcnR5U3RyaW5nXSA9IGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0cy5wdXNoKHRhcmdldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5kZXggPSBDT01QQVRJQklMSVRZLmluQSh0YXJnZXQsIF90YXJnZXRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPiAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy91bnJlZ2lzdGVyIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRhcmdldFtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldHMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IGluc3RhbmNlIGZyb20gdGFyZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90YXJnZXRzW2luZGV4XVtfaW5zdGFuY2VQcm9wZXJ0eVN0cmluZ107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSgpO1xyXG4gICAgICAgIHZhciBQTFVHSU4gPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgX3BsdWdpbjtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zR2xvYmFscztcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3A7XHJcbiAgICAgICAgICAgIHZhciBfcGx1Z2luc0V4dGVuc2lvbnMgPSBbXTtcclxuICAgICAgICAgICAgdmFyIF9wbHVnaW5zT3B0aW9ucyA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZVRlbXBsYXRlVHlwZXMgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMuYiwgLy9ib29sZWFuXHJcbiAgICAgICAgICAgICAgICAgICAgVFlQRVMubiwgLy9udW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5zLCAvL3N0cmluZ1xyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmEsIC8vYXJyYXlcclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy5vLCAvL29iamVjdFxyXG4gICAgICAgICAgICAgICAgICAgIFRZUEVTLmYsIC8vZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICBUWVBFUy56ICAvL251bGxcclxuICAgICAgICAgICAgICAgIF07XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ3NTcGxpdCA9ICcgJztcclxuICAgICAgICAgICAgICAgIHZhciByZXN0cmljdGVkU3RyaW5nc1Bvc3NpYmlsaXRpZXNTcGxpdCA9ICc6JztcclxuICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWVBbGxvd2VkVmFsdWVzID0gW1RZUEVTLnosIFRZUEVTLnNdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG51bWJlckFsbG93ZWRWYWx1ZXMgPSBUWVBFUy5uO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlcyA9IFtUWVBFUy56LCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBib29sZWFuVHJ1ZVRlbXBsYXRlID0gW3RydWUsIFRZUEVTLmJdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGJvb2xlYW5GYWxzZVRlbXBsYXRlID0gW2ZhbHNlLCBUWVBFUy5iXTtcclxuICAgICAgICAgICAgICAgIHZhciBjYWxsYmFja1RlbXBsYXRlID0gW251bGwsIFtUWVBFUy56LCBUWVBFUy5mXV07XHJcbiAgICAgICAgICAgICAgICB2YXIgdXBkYXRlT25Mb2FkVGVtcGxhdGUgPSBbWydpbWcnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciBpbmhlcml0ZWRBdHRyc1RlbXBsYXRlID0gW1snc3R5bGUnLCAnY2xhc3MnXSwgW1RZUEVTLnMsIFRZUEVTLmEsIFRZUEVTLnpdXTtcclxuICAgICAgICAgICAgICAgIHZhciByZXNpemVBbGxvd2VkVmFsdWVzID0gJ246bm9uZSBiOmJvdGggaDpob3Jpem9udGFsIHY6dmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JBbGxvd2VkVmFsdWVzID0gJ3YtaDp2aXNpYmxlLWhpZGRlbiB2LXM6dmlzaWJsZS1zY3JvbGwgczpzY3JvbGwgaDpoaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5QWxsb3dlZFZhbHVlcyA9ICd2OnZpc2libGUgaDpoaWRkZW4gYTphdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVBbGxvd2VkVmFsdWVzID0gJ246bmV2ZXIgczpzY3JvbGwgbDpsZWF2ZSBtOm1vdmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlID0ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogWydvcy10aGVtZS1kYXJrJywgY2xhc3NOYW1lQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBzdHJpbmdcclxuICAgICAgICAgICAgICAgICAgICByZXNpemU6IFsnbm9uZScsIHJlc2l6ZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vbmUgfHwgYm90aCAgfHwgaG9yaXpvbnRhbCB8fCB2ZXJ0aWNhbCB8fCBuIHx8IGIgfHwgaCB8fCB2XHJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZUF1dG9DYXBhYmxlOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgY2xpcEFsd2F5czogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplUlRMOiBib29sZWFuVHJ1ZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0Fic29sdXRlOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZTogW251bGwsIGJvb2xlYW5OdWxsQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlIHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlSW50ZXJ2YWw6IFszMywgbnVtYmVyQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAgICAvL251bWJlclxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZU9uTG9hZDogdXBkYXRlT25Mb2FkVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2hvd05hdGl2ZVNjcm9sbGJhcnM6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbGl6ZTogYm9vbGVhblRydWVUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3RydWUgfHwgZmFsc2VcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QmVoYXZpb3I6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogWydzY3JvbGwnLCBvdmVyZmxvd0JlaGF2aW9yQWxsb3dlZFZhbHVlc10sICAgICAgICAgICAgICAgICAgICAvL3Zpc2libGUtaGlkZGVuICB8fCB2aXNpYmxlLXNjcm9sbCB8fCBoaWRkZW4gfHwgc2Nyb2xsIHx8IHYtaCB8fCB2LXMgfHwgaCB8fCBzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IFsnc2Nyb2xsJywgb3ZlcmZsb3dCZWhhdmlvckFsbG93ZWRWYWx1ZXNdICAgICAgICAgICAgICAgICAgICAgLy92aXNpYmxlLWhpZGRlbiAgfHwgdmlzaWJsZS1zY3JvbGwgfHwgaGlkZGVuIHx8IHNjcm9sbCB8fCB2LWggfHwgdi1zIHx8IGggfHwgc1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBbJ2F1dG8nLCBzY3JvbGxiYXJzVmlzaWJpbGl0eUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgIC8vdmlzaWJsZSB8fCBoaWRkZW4gfHwgYXV0byB8fCB2IHx8IGggfHwgYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZTogWyduZXZlcicsIHNjcm9sbGJhcnNBdXRvSGlkZUFsbG93ZWRWYWx1ZXNdLCAgICAgICAgICAgIC8vbmV2ZXIgfHwgc2Nyb2xsIHx8IGxlYXZlIHx8IG1vdmUgfHwgbiB8fCBzIHx8IGwgfHwgbVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvSGlkZURlbGF5OiBbODAwLCBudW1iZXJBbGxvd2VkVmFsdWVzXSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVtYmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRyYWdTY3JvbGxpbmc6IGJvb2xlYW5UcnVlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWNrU2Nyb2xsaW5nOiBib29sZWFuRmFsc2VUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdWNoU3VwcG9ydDogYm9vbGVhblRydWVUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBIYW5kbGU6IGJvb2xlYW5GYWxzZVRlbXBsYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlIHx8IGZhbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5XaWR0aDogYm9vbGVhbkZhbHNlVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkeW5IZWlnaHQ6IGJvb2xlYW5GYWxzZVRlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSB8fCBmYWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWRBdHRyczogaW5oZXJpdGVkQXR0cnNUZW1wbGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3RyaW5nIHx8IGFycmF5IHx8IG51bGxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrczoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemVkOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkluaXRpYWxpemF0aW9uV2l0aGRyYXduOiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRlc3Ryb3llZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0YXJ0OiBjYWxsYmFja1RlbXBsYXRlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFN0b3A6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbk92ZXJmbG93QW1vdW50Q2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkRpcmVjdGlvbkNoYW5nZWQ6IGNhbGxiYWNrVGVtcGxhdGUsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNvbnRlbnRTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkhvc3RTaXplQ2hhbmdlZDogY2FsbGJhY2tUZW1wbGF0ZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblVwZGF0ZWQ6IGNhbGxiYWNrVGVtcGxhdGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbnVsbCB8fCBmdW5jdGlvblxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB2YXIgY29udmVydCA9IGZ1bmN0aW9uICh0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWN1cnNpdmUgPSBmdW5jdGlvbiAob2JqKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWxUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGtleSBpbiBvYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghb2JqW0xFWElDT04uaE9QXShrZXkpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW2tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxUeXBlID0gdHlwZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbFR5cGUgPT0gVFlQRVMuYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHZhbFt0ZW1wbGF0ZSA/IDEgOiAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZhbFR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IHJlY3Vyc2l2ZSh2YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVjdXJzaXZlKEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIG9wdGlvbnNEZWZhdWx0c0FuZFRlbXBsYXRlKSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RlZmF1bHRzOiBjb252ZXJ0KCksXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF90ZW1wbGF0ZTogY29udmVydCh0cnVlKSxcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogVmFsaWRhdGVzIHRoZSBwYXNzZWQgb2JqZWN0IGJ5IHRoZSBwYXNzZWQgdGVtcGxhdGUuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IHdoaWNoIHNoYWxsIGJlIHZhbGlkYXRlZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGVtcGxhdGUgVGhlIHRlbXBsYXRlIHdoaWNoIGRlZmluZXMgdGhlIGFsbG93ZWQgdmFsdWVzIGFuZCB0eXBlcy5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcGFyYW0gd3JpdGVFcnJvcnMgVHJ1ZSBpZiBlcnJvcnMgc2hhbGwgYmUgbG9nZ2VkIHRvIHRoZSBjb25zb2xlLlxyXG4gICAgICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkaWZmT2JqIElmIGEgb2JqZWN0IGlzIHBhc3NlZCB0aGVuIG9ubHkgdmFsaWQgZGlmZmVyZW5jZXMgdG8gdGhpcyBvYmplY3Qgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e319IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHR3byBvYmplY3RzIGNhbGxlZCBcImRlZmF1bHRcIiBhbmQgXCJwcmVwYXJlZFwiIHdoaWNoIGNvbnRhaW5zIG9ubHkgdGhlIHZhbGlkIHByb3BlcnRpZXMgb2YgdGhlIHBhc3NlZCBvcmlnaW5hbCBvYmplY3QgYW5kIGRpc2NhcmRzIG5vdCBkaWZmZXJlbnQgdmFsdWVzIGNvbXBhcmVkIHRvIHRoZSBwYXNzZWQgZGlmZk9iai5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfdmFsaWRhdGU6IGZ1bmN0aW9uIChvYmosIHRlbXBsYXRlLCB3cml0ZUVycm9ycywgZGlmZk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9ucyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYmplY3RDb3B5ID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgb2JqKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluQXJyYXkgPSBGUkFNRVdPUksuaW5BcnJheTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRW1wdHlPYmogPSBGUkFNRVdPUksuaXNFbXB0eU9iamVjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrT2JqZWN0UHJvcHMgPSBmdW5jdGlvbiAoZGF0YSwgdGVtcGxhdGUsIGRpZmZEYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIHByZXZQcm9wTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiB0ZW1wbGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ZW1wbGF0ZVtMRVhJQ09OLmhPUF0ocHJvcCkgJiYgZGF0YVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVmFsaWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRGlmZiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZSA9IHRlbXBsYXRlW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVWYWx1ZVR5cGUgPSB0eXBlKHRlbXBsYXRlVmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVJc0NvbXBsZXggPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5vO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGVtcGxhdGVUeXBlcyA9ICFDT01QQVRJQklMSVRZLmlzQSh0ZW1wbGF0ZVZhbHVlKSA/IFt0ZW1wbGF0ZVZhbHVlXSA6IHRlbXBsYXRlVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhRGlmZlZhbHVlID0gZGlmZkRhdGFbcHJvcF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkYXRhVmFsdWUgPSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YVZhbHVlVHlwZSA9IHR5cGUoZGF0YVZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BQcmVmaXggPSBwcmV2UHJvcE5hbWUgPyBwcmV2UHJvcE5hbWUgKyAnLicgOiAnJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gXCJUaGUgb3B0aW9uIFxcXCJcIiArIHByb3BQcmVmaXggKyBwcm9wICsgXCJcXFwiIHdhc24ndCBzZXQsIGJlY2F1c2VcIjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yUG9zc2libGVUeXBlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3JSZXN0cmljdGVkU3RyaW5ncyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzUmVzdHJpY3RlZFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFpblBvc3NpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclR5cGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGo7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhRGlmZlZhbHVlID0gZGF0YURpZmZWYWx1ZSA9PT0gdW5kZWZpbmVkID8ge30gOiBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgdGVtcGxhdGUgaGFzIGEgb2JqZWN0IGFzIHZhbHVlLCBpdCBtZWFucyB0aGF0IHRoZSBvcHRpb25zIGFyZSBjb21wbGV4ICh2ZXJzY2hhY2h0ZWx0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGVtcGxhdGVJc0NvbXBsZXggJiYgZGF0YVZhbHVlVHlwZSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0gPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrT2JqZWN0UHJvcHMoZGF0YVZhbHVlLCB0ZW1wbGF0ZVZhbHVlLCBkYXRhRGlmZlZhbHVlLCB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRbcHJvcF0sIHByb3BQcmVmaXggKyBwcm9wKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKFtkYXRhLCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRdLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRW1wdHlPYmoodmFsdWVbcHJvcF0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtwcm9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICghdGVtcGxhdGVJc0NvbXBsZXgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZW1wbGF0ZVR5cGVzW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJUeXBlID0gdGVtcGxhdGVUeXBlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhbHVlVHlwZSA9IHR5cGUoY3VyclR5cGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgY3VycnR5cGUgaXMgc3RyaW5nIGFuZCBzdGFydHMgd2l0aCByZXN0cmljdGVkU3RyaW5nUHJlZml4IGFuZCBlbmQgd2l0aCByZXN0cmljdGVkU3RyaW5nU3VmZml4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNSZXN0cmljdGVkVmFsdWUgPSB0ZW1wbGF0ZVZhbHVlVHlwZSA9PSBUWVBFUy5zICYmIGluQXJyYXkoY3VyclR5cGUsIHBvc3NpYmxlVGVtcGxhdGVUeXBlcykgPT09IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1Jlc3RyaWN0ZWRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclBvc3NpYmxlVHlwZXMucHVzaChUWVBFUy5zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc3BsaXQgaXQgaW50byBhIGFycmF5IHdoaWNoIGNvbnRhaW5zIGFsbCBwb3NzaWJsZSB2YWx1ZXMgZm9yIGV4YW1wbGU6IFtcInk6eWVzXCIsIFwibjpub1wiLCBcIm06bWF5YmVcIl1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0ID0gY3VyclR5cGUuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NTcGxpdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yUmVzdHJpY3RlZFN0cmluZ3MgPSBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmNvbmNhdChyZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHYgPSAwOyB2IDwgcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1NwbGl0W0xFWElDT04ubF07IHYrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zcGxpdCB0aGUgcG9zc2libGUgdmFsdWVzIGludG8gdGhlaXIgcG9zc2liaWxpdGVpcyBmb3IgZXhhbXBsZTogW1wieVwiLCBcInllc1wiXSAtPiB0aGUgZmlyc3QgaXMgYWx3YXlzIHRoZSBtYWluUG9zc2liaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQgPSByZXN0cmljdGVkU3RyaW5nVmFsdWVzU3BsaXRbdl0uc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpblBvc3NpYmlsaXR5ID0gcmVzdHJpY3RlZFN0cmluZ1ZhbHVlc1Bvc3NpYmlsaXRpZXNTcGxpdFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W0xFWElDT04ubF07IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgYW55IHBvc3NpYmlsaXR5IG1hdGNoZXMgd2l0aCB0aGUgZGF0YVZhbHVlLCBpdHMgdmFsaWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YVZhbHVlID09PSByZXN0cmljdGVkU3RyaW5nVmFsdWVzUG9zc2liaWxpdGllc1NwbGl0W2pdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNWYWxpZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JQb3NzaWJsZVR5cGVzLnB1c2goY3VyclR5cGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGFWYWx1ZVR5cGUgPT09IGN1cnJUeXBlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNEaWZmID0gZGF0YVZhbHVlICE9PSBkYXRhRGlmZlZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNEaWZmKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRPcHRpb25zW3Byb3BdID0gZGF0YVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNSZXN0cmljdGVkVmFsdWUgPyBpbkFycmF5KGRhdGFEaWZmVmFsdWUsIHJlc3RyaWN0ZWRTdHJpbmdWYWx1ZXNQb3NzaWJpbGl0aWVzU3BsaXQpIDwgMCA6IGlzRGlmZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkT3B0aW9uc1ByZXBhcmVkW3Byb3BdID0gaXNSZXN0cmljdGVkVmFsdWUgPyBtYWluUG9zc2liaWxpdHkgOiBkYXRhVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh3cml0ZUVycm9ycykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvciArIFwiIGl0IGRvZXNuJ3QgYWNjZXB0IHRoZSB0eXBlIFsgXCIgKyBkYXRhVmFsdWVUeXBlLnRvVXBwZXJDYXNlKCkgKyBcIiBdIHdpdGggdGhlIHZhbHVlIG9mIFxcXCJcIiArIGRhdGFWYWx1ZSArIFwiXFxcIi5cXHJcXG5cIiArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQWNjZXB0ZWQgdHlwZXMgYXJlOiBbIFwiICsgZXJyb3JQb3NzaWJsZVR5cGVzLmpvaW4oJywgJykudG9VcHBlckNhc2UoKSArIFwiIF0uXCIgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3JSZXN0cmljdGVkU3RyaW5nc1tsZW5ndGhdID4gMCA/IFwiXFxyXFxuVmFsaWQgc3RyaW5ncyBhcmU6IFsgXCIgKyBlcnJvclJlc3RyaWN0ZWRTdHJpbmdzLmpvaW4oJywgJykuc3BsaXQocmVzdHJpY3RlZFN0cmluZ3NQb3NzaWJpbGl0aWVzU3BsaXQpLmpvaW4oJywgJykgKyBcIiBdLlwiIDogJycpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkYXRhW3Byb3BdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja09iamVjdFByb3BzKG9iamVjdENvcHksIHRlbXBsYXRlLCBkaWZmT2JqIHx8IHt9LCB2YWxpZGF0ZWRPcHRpb25zLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdmFsdWVzIHdoaWNoIGFyZW4ndCBzcGVjaWZpZWQgaW4gdGhlIHRlbXBsYXRlIHRvIHRoZSBmaW5pc2hlZCB2YWxpZGF0ZWQgb2JqZWN0IHRvIHByZXZlbnQgdGhlbSBmcm9tIGJlaW5nIGRpc2NhcmRlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihrZWVwRm9yZWlnblByb3BzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHZhbGlkYXRlZE9wdGlvbnMsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWQsIG9iamVjdENvcHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICovXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRW1wdHlPYmoob2JqZWN0Q29weSkgJiYgd3JpdGVFcnJvcnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSBmb2xsb3dpbmcgb3B0aW9ucyBhcmUgZGlzY2FyZGVkIGR1ZSB0byBpbnZhbGlkaXR5OlxcclxcbicgKyB3aW5kb3cuSlNPTi5zdHJpbmdpZnkob2JqZWN0Q29weSwgbnVsbCwgMikpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0OiB2YWxpZGF0ZWRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ByZXBhcmVkOiB2YWxpZGF0ZWRPcHRpb25zUHJlcGFyZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0oKSk7XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgdGhlIG9iamVjdCB3aGljaCBjb250YWlucyBnbG9iYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBsdWdpbiBhbmQgZWFjaCBpbnN0YW5jZSBvZiBpdC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV9wbHVnaW5zR2xvYmFscylcclxuICAgICAgICAgICAgICAgICAgICBfcGx1Z2luc0dsb2JhbHMgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKF9wbHVnaW5zT3B0aW9ucy5fZGVmYXVsdHMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfcGx1Z2luc0F1dG9VcGRhdGVMb29wKVxyXG4gICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zQXV0b1VwZGF0ZUxvb3AgPSBuZXcgT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGdsb2JhbCBvYmplY3QgZm9yIHRoZSBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RzLiBJdCBjb250YWlucyByZXNvdXJjZXMgd2hpY2ggZXZlcnkgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IG5lZWRzLiBUaGlzIG9iamVjdCBpcyBpbml0aWFsaXplZCBvbmx5IG9uY2U6IGlmIHRoZSBmaXJzdCBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3QgZ2V0cyBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGRlZmF1bHRPcHRpb25zXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNHbG9iYWxzKGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIHN0ck92ZXJmbG93ID0gJ292ZXJmbG93JztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJIaWRkZW4gPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgICAgIHZhciBzdHJTY3JvbGwgPSAnc2Nyb2xsJztcclxuICAgICAgICAgICAgICAgIHZhciBib2R5RWxlbWVudCA9IEZSQU1FV09SSygnYm9keScpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckR1bW15RWxlbWVudCA9IEZSQU1FV09SSygnPGRpdiBpZD1cIm9zLWR1bW15LXNjcm9sbGJhci1zaXplXCI+PGRpdj48L2Rpdj48L2Rpdj4nKTtcclxuICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJEdW1teUVsZW1lbnQwID0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGQgPSBGUkFNRVdPUksoc2Nyb2xsYmFyRHVtbXlFbGVtZW50LmNoaWxkcmVuKCdkaXYnKS5lcSgwKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuaGlkZSgpLnNob3coKTsgLy9maXggSUU4IGJ1ZyAoaW5jb3JyZWN0IG1lYXN1cmluZylcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgbmF0aXZlU2Nyb2xsYmFyU2l6ZSA9IGNhbGNOYXRpdmVTY3JvbGxiYXJTaXplKHNjcm9sbGJhckR1bW15RWxlbWVudDApO1xyXG4gICAgICAgICAgICAgICAgdmFyIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgeDogbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ID09PSAwLFxyXG4gICAgICAgICAgICAgICAgICAgIHk6IG5hdGl2ZVNjcm9sbGJhclNpemUueSA9PT0gMFxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHZhciBtc2llID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdWEgPSB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySW5kZXhPZiA9ICdpbmRleE9mJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyU3ViU3RyaW5nID0gJ3N1YnN0cmluZyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1zaWUgPSB1YVtzdHJJbmRleE9mXSgnTVNJRSAnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJpZGVudCA9IHVhW3N0ckluZGV4T2ZdKCdUcmlkZW50LycpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlZGdlID0gdWFbc3RySW5kZXhPZl0oJ0VkZ2UvJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJ2ID0gdWFbc3RySW5kZXhPZl0oJ3J2OicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlSW50RnVuYyA9IHBhcnNlSW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMCBvciBvbGRlciA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBpZiAobXNpZSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHBhcnNlSW50RnVuYyh1YVtzdHJTdWJTdHJpbmddKG1zaWUgKyA1LCB1YVtzdHJJbmRleE9mXSgnLicsIG1zaWUpKSwgMTApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBJRSAxMSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0cmlkZW50ID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10ocnYgKyAzLCB1YVtzdHJJbmRleE9mXSgnLicsIHJ2KSksIDEwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRWRnZSAoSUUgMTIrKSA9PiByZXR1cm4gdmVyc2lvbiBudW1iZXJcclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChlZGdlID4gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcGFyc2VJbnRGdW5jKHVhW3N0clN1YlN0cmluZ10oZWRnZSArIDUsIHVhW3N0ckluZGV4T2ZdKCcuJywgZWRnZSkpLCAxMCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyIGJyb3dzZXJcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBGUkFNRVdPUksuZXh0ZW5kKF9iYXNlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdE9wdGlvbnM6IGRlZmF1bHRPcHRpb25zLFxyXG4gICAgICAgICAgICAgICAgICAgIG1zaWU6IG1zaWUsXHJcbiAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3A6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGF1dG9VcGRhdGVSZWNvbW1lbmRlZDogIUNPTVBBVElCSUxJVFkubU8oKSxcclxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplOiBuYXRpdmVTY3JvbGxiYXJTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQ6IG5hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlU2Nyb2xsYmFyU3R5bGluZzogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuYWRkQ2xhc3MoJ29zLXZpZXdwb3J0LW5hdGl2ZS1zY3JvbGxiYXJzLWludmlzaWJsZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gKHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoJ3Njcm9sbGJhci13aWR0aCcpID09PSAnbm9uZScgJiYgKG1zaWUgPiA5IHx8ICFtc2llKSkgfHwgd2luZG93LmdldENvbXB1dGVkU3R5bGUoc2Nyb2xsYmFyRHVtbXlFbGVtZW50MCwgJzo6LXdlYmtpdC1zY3JvbGxiYXInKS5nZXRQcm9wZXJ0eVZhbHVlKCdkaXNwbGF5JykgPT09ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggb3BlcmEgYnVnOiBzY3JvbGxiYXIgc3R5bGVzIHdpbGwgb25seSBhcHBlYXIgaWYgb3ZlcmZsb3cgdmFsdWUgaXMgc2Nyb2xsIG9yIGF1dG8gZHVyaW5nIHRoZSBhY3RpdmF0aW9uIG9mIHRoZSBzdHlsZS5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hbmQgc2V0IG92ZXJmbG93IHRvIHNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csIHN0ckhpZGRlbikuaGlkZSgpLmNzcyhzdHJPdmVyZmxvdywgc3RyU2Nyb2xsKS5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIChzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04ub0hdIC0gc2Nyb2xsYmFyRHVtbXlFbGVtZW50MFtMRVhJQ09OLmNIXSkgPT09IDAgJiYgKHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5vV10gLSBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uY1ddKSA9PT0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplOiB7IHg6IDMwLCB5OiAzMCB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNzc0NhbGM6IFZFTkRPUlMuX2Nzc1Byb3BlcnR5VmFsdWUoJ3dpZHRoJywgJ2NhbGMnLCAnKDFweCknKSB8fCBudWxsLFxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3RyaWN0ZWRNZWFzdXJpbmc6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTQzOTMwNVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NpbmNlIDEuMTEuMCBhbHdheXMgZmFsc2UgLT4gZml4ZWQgdmlhIENTUyAoaG9wZWZ1bGx5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuY3NzKHN0ck92ZXJmbG93LCBzdHJIaWRkZW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3Moc3RyT3ZlcmZsb3csICd2aXNpYmxlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxTaXplMiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IHNjcm9sbGJhckR1bW15RWxlbWVudDBbTEVYSUNPTi5zV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBzY3JvbGxiYXJEdW1teUVsZW1lbnQwW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoc2Nyb2xsU2l6ZS53IC0gc2Nyb2xsU2l6ZTIudykgIT09IDAgfHwgKHNjcm9sbFNpemUuaCAtIHNjcm9sbFNpemUyLmgpICE9PSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgcnRsU2Nyb2xsQmVoYXZpb3I6IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5jc3MoeyAnb3ZlcmZsb3cteSc6IHN0ckhpZGRlbiwgJ292ZXJmbG93LXgnOiBzdHJTY3JvbGwsICdkaXJlY3Rpb24nOiAncnRsJyB9KS5zY3JvbGxMZWZ0KDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHVtbXlDb250YWluZXJPZmZzZXQgPSBzY3JvbGxiYXJEdW1teUVsZW1lbnQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0ID0gZHVtbXlDb250YWluZXJDaGlsZC5vZmZzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9odHRwczovL2dpdGh1Yi5jb20vS2luZ1NvcmEvT3ZlcmxheVNjcm9sbGJhcnMvaXNzdWVzLzE4N1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJEdW1teUVsZW1lbnQuc2Nyb2xsTGVmdCgtOTk5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGR1bW15Q29udGFpbmVyQ2hpbGRPZmZzZXRBZnRlclNjcm9sbCA9IGR1bW15Q29udGFpbmVyQ2hpbGQub2Zmc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29yaWdpbiBkaXJlY3Rpb24gPSBkZXRlcm1pbmVzIGlmIHRoZSB6ZXJvIHNjcm9sbCBwb3NpdGlvbiBpcyBvbiB0aGUgbGVmdCBvciByaWdodCBzaWRlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLydpJyBtZWFucyAnaW52ZXJ0JyAoaSA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgaW52ZXJ0ZWQgdG8gYmUgY29ycmVjdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJ1ZSA9IG9uIHRoZSBsZWZ0IHNpZGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBvbiB0aGUgcmlnaHQgc2lkZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaTogZHVtbXlDb250YWluZXJPZmZzZXQubGVmdCA9PT0gZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9uZWdhdGl2ZSA9IGRldGVybWluZXMgaWYgdGhlIG1heGltdW0gc2Nyb2xsIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyduJyBtZWFucyAnbmVnYXRlJyAobiA9PT0gdHJ1ZSBtZWFucyB0aGF0IHRoZSBheGlzIG11c3QgYmUgbmVnYXRlZCB0byBiZSBjb3JyZWN0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90cnVlID0gbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmFsc2UgPSBwb3NpdGl2ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbjogZHVtbXlDb250YWluZXJDaGlsZE9mZnNldC5sZWZ0ICE9PSBkdW1teUNvbnRhaW5lckNoaWxkT2Zmc2V0QWZ0ZXJTY3JvbGwubGVmdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKCksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zZm9ybTogISFWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyksXHJcbiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydFRyYW5zaXRpb246ICEhVkVORE9SUy5fY3NzUHJvcGVydHkoJ3RyYW5zaXRpb24nKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UGFzc2l2ZUV2ZW50czogKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN1cHBvcnRzUGFzc2l2ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Rlc3QnLCBudWxsLCBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0c1Bhc3NpdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdXBwb3J0c1Bhc3NpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSkoKSxcclxuICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UmVzaXplT2JzZXJ2ZXI6ICEhQ09NUEFUSUJJTElUWS5yTygpLFxyXG4gICAgICAgICAgICAgICAgICAgIHN1cHBvcnRNdXRhdGlvbk9ic2VydmVyOiAhIUNPTVBBVElCSUxJVFkubU8oKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgc2Nyb2xsYmFyRHVtbXlFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi5zKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL0NhdGNoIHpvb20gZXZlbnQ6XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhYnMgPSBNQVRILmFicztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93V2lkdGggPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpbmRvd0hlaWdodCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2luZG93RHByID0gZ2V0V2luZG93RFBSKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1cgPSBDT01QQVRJQklMSVRZLndXKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3SCA9IENPTVBBVElCSUxJVFkud0goKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YVcgPSBuZXdXIC0gd2luZG93V2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVsdGFIID0gbmV3SCAtIHdpbmRvd0hlaWdodDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVsdGFXID09PSAwICYmIGRlbHRhSCA9PT0gMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhV1JhdGlvID0gTUFUSC5yb3VuZChuZXdXIC8gKHdpbmRvd1dpZHRoIC8gMTAwLjApKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZWx0YUhSYXRpbyA9IE1BVEgucm91bmQobmV3SCAvICh3aW5kb3dIZWlnaHQgLyAxMDAuMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhVyA9IGFicyhkZWx0YVcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhSCA9IGFicyhkZWx0YUgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic0RlbHRhV1JhdGlvID0gYWJzKGRlbHRhV1JhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhYnNEZWx0YUhSYXRpbyA9IGFicyhkZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3RFBSID0gZ2V0V2luZG93RFBSKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRlbHRhSXNCaWdnZXIgPSBhYnNEZWx0YVcgPiAyICYmIGFic0RlbHRhSCA+IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZmVyZW5jZSA9ICFkaWZmZXJlbmNlSXNCaWdnZXJUaGFuT25lKGFic0RlbHRhV1JhdGlvLCBhYnNEZWx0YUhSYXRpbyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZHByQ2hhbmdlZCA9IG5ld0RQUiAhPT0gd2luZG93RHByICYmIHdpbmRvd0RwciA+IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNab29tID0gZGVsdGFJc0JpZ2dlciAmJiBkaWZmZXJlbmNlICYmIGRwckNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2xkU2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3U2Nyb2xsYmFyU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNab29tKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9keUVsZW1lbnQuYXBwZW5kKHNjcm9sbGJhckR1bW15RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3U2Nyb2xsYmFyU2l6ZSA9IF9iYXNlLm5hdGl2ZVNjcm9sbGJhclNpemUgPSBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShzY3JvbGxiYXJEdW1teUVsZW1lbnRbMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckR1bW15RWxlbWVudC5yZW1vdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkU2Nyb2xsYmFyU2l6ZS54ICE9PSBuZXdTY3JvbGxiYXJTaXplLnggfHwgb2xkU2Nyb2xsYmFyU2l6ZS55ICE9PSBuZXdTY3JvbGxiYXJTaXplLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmVhY2goSU5TVEFOQ0VTKCksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChJTlNUQU5DRVModGhpcykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5TVEFOQ0VTKHRoaXMpLnVwZGF0ZSgnem9vbScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93V2lkdGggPSBuZXdXO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93SGVpZ2h0ID0gbmV3SDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvd0RwciA9IG5ld0RQUjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpZmZlcmVuY2VJc0JpZ2dlclRoYW5PbmUodmFsT25lLCB2YWxUd28pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFic1ZhbE9uZSA9IGFicyh2YWxPbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWJzVmFsVHdvID0gYWJzKHZhbFR3byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhKGFic1ZhbE9uZSA9PT0gYWJzVmFsVHdvIHx8IGFic1ZhbE9uZSArIDEgPT09IGFic1ZhbFR3byB8fCBhYnNWYWxPbmUgLSAxID09PSBhYnNWYWxUd28pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0V2luZG93RFBSKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZERQSSA9IHdpbmRvdy5zY3JlZW4uZGV2aWNlWERQSSB8fCAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc0RQSSA9IHdpbmRvdy5zY3JlZW4ubG9naWNhbFhEUEkgfHwgMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvIHx8IChkRFBJIC8gc0RQSSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksod2luZG93KS5vbigncmVzaXplJywgb25SZXNpemUpO1xyXG4gICAgICAgICAgICAgICAgfSkoKTtcclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjYWxjTmF0aXZlU2Nyb2xsYmFyU2l6ZShtZWFzdXJlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub0hdIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IG1lYXN1cmVFbGVtZW50W0xFWElDT04ub1ddIC0gbWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV11cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIG9iamVjdCB3aGljaCBtYW5hZ2VzIHRoZSBhdXRvIHVwZGF0ZSBsb29wIGZvciBhbGwgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0cy4gVGhpcyBvYmplY3QgaXMgaW5pdGlhbGl6ZWQgb25seSBvbmNlOiBpZiB0aGUgZmlyc3QgT3ZlcmxheVNjcm9sbGJhcnMgb2JqZWN0IGdldHMgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgZnVuY3Rpb24gT3ZlcmxheVNjcm9sbGJhcnNBdXRvVXBkYXRlTG9vcChnbG9iYWxzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Jhc2UgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2dldE5vdyA9IENPTVBBVElCSUxJVFkubm93O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlID0gJ2F1dG9VcGRhdGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJBdXRvVXBkYXRlSW50ZXJ2YWwgPSBfc3RyQXV0b1VwZGF0ZSArICdJbnRlcnZhbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckxlbmd0aCA9IExFWElDT04ubDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcGluZ0luc3RhbmNlcyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcEludGVydmFsRGVmYXVsdCA9IDMzO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9sb29wSW50ZXJ2YWwgPSBfbG9vcEludGVydmFsRGVmYXVsdDtcclxuICAgICAgICAgICAgICAgIHZhciBfbG9vcFRpbWVPbGQgPSBfZ2V0Tm93KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2xvb3BJRDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgYXV0byB1cGRhdGUgbG9vcCB3aGljaCB3aWxsIHJ1biBldmVyeSA1MCBtaWxsaXNlY29uZHMgb3IgbGVzcyBpZiB0aGUgdXBkYXRlIGludGVydmFsIG9mIGEgaW5zdGFuY2UgaXMgbG93ZXIgdGhhbiA1MCBtaWxsaXNlY29uZHMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIHZhciBsb29wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXSA+IDAgJiYgX2xvb3BJc0FjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElEID0gQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZU5ldyA9IF9nZXROb3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRpbWVEZWx0YSA9IHRpbWVOZXcgLSBfbG9vcFRpbWVPbGQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsb3dlc3RJbnRlcnZhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVEZWx0YSA+IF9sb29wSW50ZXJ2YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wVGltZU9sZCA9IHRpbWVOZXcgLSAodGltZURlbHRhICUgX2xvb3BJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlc3RJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfbG9vcGluZ0luc3RhbmNlc1tfc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2UgPSBfbG9vcGluZ0luc3RhbmNlc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2UgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZU9wdGlvbnMgPSBpbnN0YW5jZS5vcHRpb25zKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQXV0b1VwZGF0ZUFsbG93ZWQgPSBpbnN0YW5jZU9wdGlvbnNbX3N0ckF1dG9VcGRhdGVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCA9IE1BVEgubWF4KDEsIGluc3RhbmNlT3B0aW9uc1tfc3RyQXV0b1VwZGF0ZUludGVydmFsXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdyA9IF9nZXROb3coKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaW5zdGFuY2VBdXRvVXBkYXRlQWxsb3dlZCA9PT0gdHJ1ZSB8fCBpbnN0YW5jZUF1dG9VcGRhdGVBbGxvd2VkID09PSBudWxsKSAmJiAobm93IC0gX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlW2ldKSA+IGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS51cGRhdGUoJ2F1dG8nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzSW50ZXJ2YWxDYWNoZVtpXSA9IG5ldyBEYXRlKG5vdyArPSBpbnN0YW5jZUF1dG9VcGRhdGVJbnRlcnZhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VzdEludGVydmFsID0gTUFUSC5tYXgoMSwgTUFUSC5taW4obG93ZXN0SW50ZXJ2YWwsIGluc3RhbmNlQXV0b1VwZGF0ZUludGVydmFsKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IGxvd2VzdEludGVydmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJbnRlcnZhbCA9IF9sb29wSW50ZXJ2YWxEZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgdG8gdGhlIGF1dG8gdXBkYXRlIGxvb3AuIE9ubHkgc3VjY2Vzc2Z1bCBpZiB0aGUgaW5zdGFuY2UgaXNuJ3QgYWxyZWFkeSBhZGRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpbnN0YW5jZSBUaGUgaW5zdGFuY2Ugd2hpY2ggc2hhbGwgYmUgdXBkYXRlZCBpbiBhIGxvb3AgYXV0b21hdGljYWxseS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2UuYWRkID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcykgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnB1c2goaW5zdGFuY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbG9vcGluZ0luc3RhbmNlc0ludGVydmFsQ2FjaGUucHVzaChfZ2V0Tm93KCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2xvb3BpbmdJbnN0YW5jZXNbX3N0ckxlbmd0aF0gPiAwICYmICFfbG9vcElzQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbG9vcElzQWN0aXZlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9vcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZSBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSBmcm9tIHRoZSBhdXRvIHVwZGF0ZSBsb29wLiBPbmx5IHN1Y2Nlc3NmdWwgaWYgdGhlIGluc3RhbmNlIHdhcyBhZGRlZCBiZWZvcmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaW5zdGFuY2UgVGhlIGluc3RhbmNlIHdoaWNoIHNoYWxsIGJlIHVwZGF0ZWQgaW4gYSBsb29wIGF1dG9tYXRpY2FsbHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnJlbW92ZSA9IGZ1bmN0aW9uIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IF9pbkFycmF5KGluc3RhbmNlLCBfbG9vcGluZ0luc3RhbmNlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgZnJvbSBsb29waW5nSW5zdGFuY2VzIGxpc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BpbmdJbnN0YW5jZXNJbnRlcnZhbENhY2hlLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sb29waW5nSW5zdGFuY2VzLnNwbGljZShpbmRleCwgMSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3QgdXBkYXRlIGxvb3AgYmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29waW5nSW5zdGFuY2VzW19zdHJMZW5ndGhdID09PSAwICYmIF9sb29wSXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9sb29wSXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbHMuYXV0b1VwZGF0ZUxvb3AgPSBfbG9vcElzQWN0aXZlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9sb29wSUQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkoX2xvb3BJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2xvb3BJRCA9IC0xO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEEgb2JqZWN0IHdoaWNoIG1hbmFnZXMgdGhlIHNjcm9sbGJhcnMgdmlzaWJpbGl0eSBvZiB0aGUgdGFyZ2V0IGVsZW1lbnQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgaGlkZGVuLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgY3VzdG9tIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBjdXN0b20gZXh0ZW5zaW9ucy5cclxuICAgICAgICAgICAgICogQHBhcmFtIGdsb2JhbHNcclxuICAgICAgICAgICAgICogQHBhcmFtIGF1dG9VcGRhdGVMb29wXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2UocGx1Z2luVGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucywgZ2xvYmFscywgYXV0b1VwZGF0ZUxvb3ApIHtcclxuICAgICAgICAgICAgICAgIC8vc2hvcnRjdXRzXHJcbiAgICAgICAgICAgICAgICB2YXIgdHlwZSA9IENPTVBBVElCSUxJVFkudHlwZTtcclxuICAgICAgICAgICAgICAgIHZhciBpbkFycmF5ID0gRlJBTUVXT1JLLmluQXJyYXk7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWFjaCA9IEZSQU1FV09SSy5lYWNoO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbWFrZSBjb3JyZWN0IGluc3RhbmNlb2ZcclxuICAgICAgICAgICAgICAgIHZhciBfYmFzZSA9IG5ldyBfcGx1Z2luKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2ZyYW1ld29ya1Byb3RvID0gRlJBTUVXT1JLW0xFWElDT04ucF07XHJcblxyXG4gICAgICAgICAgICAgICAgLy9pZiBwYXNzZWQgZWxlbWVudCBpcyBubyBIVE1MIGVsZW1lbnQ6IHNraXAgYW5kIHJldHVyblxyXG4gICAgICAgICAgICAgICAgaWYgKCFpc0hUTUxFbGVtZW50KHBsdWdpblRhcmdldEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2lmIHBhc3NlZCBlbGVtZW50IGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQ6IHNldCBwYXNzZWQgb3B0aW9ucyBpZiB0aGVyZSBhcmUgYW55IGFuZCByZXR1cm4gaXRzIGluc3RhbmNlXHJcbiAgICAgICAgICAgICAgICBpZiAoSU5TVEFOQ0VTKHBsdWdpblRhcmdldEVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3QgPSBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaW5zdC5vcHRpb25zKG9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnN0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2xvYmFsczpcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZDtcclxuICAgICAgICAgICAgICAgIHZhciBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcnRsU2Nyb2xsQmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2F1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXNpZVZlcnNpb247XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX25hdGl2ZVNjcm9sbGJhclNpemU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cztcclxuICAgICAgICAgICAgICAgIHZhciBfc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzdHJpY3RlZE1lYXN1cmluZztcclxuXHJcbiAgICAgICAgICAgICAgICAvL2dlbmVyYWwgcmVhZG9ubHk6XHJcbiAgICAgICAgICAgICAgICB2YXIgX2luaXRpYWxpemVkO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzVGV4dGFyZWE7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lzQm9keTtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRNaXhlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9tRXhpc3RzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vZ2VuZXJhbDpcclxuICAgICAgICAgICAgICAgIHZhciBfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ1g7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJYO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5YO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tYXJnaW5ZO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9pc1JUTDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2xlZXBpbmc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRCb3JkZXJTaXplID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbEhvcml6b250YWxJbmZvID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbFZlcnRpY2FsSW5mbyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgdmFyIF92aWV3cG9ydFNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfbmF0aXZlU2Nyb2xsYmFyTWluU2l6ZSA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8vbmFtaW5nOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1pbnVzSGlkZGVuID0gJy1oaWRkZW4nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNYXJnaW5NaW51cyA9ICdtYXJnaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUGFkZGluZ01pbnVzID0gJ3BhZGRpbmctJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQm9yZGVyTWludXMgPSAnYm9yZGVyLSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clRvcCA9ICd0b3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJSaWdodCA9ICdyaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckJvdHRvbSA9ICdib3R0b20nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJMZWZ0ID0gJ2xlZnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNaW5NaW51cyA9ICdtaW4tJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWF4TWludXMgPSAnbWF4LSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cldpZHRoID0gJ3dpZHRoJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RySGVpZ2h0ID0gJ2hlaWdodCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckZsb2F0ID0gJ2Zsb2F0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyRW1wdHkgPSAnJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyQXV0byA9ICdhdXRvJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU3luYyA9ICdzeW5jJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsID0gJ3Njcm9sbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ckh1bmRyZWRQZXJjZW50ID0gJzEwMCUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJYID0gJ3gnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJZID0gJ3knO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJEb3QgPSAnLic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNwYWNlID0gJyAnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxiYXIgPSAnc2Nyb2xsYmFyJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNIb3Jpem9udGFsID0gJy1ob3Jpem9udGFsJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTWludXNWZXJ0aWNhbCA9ICctdmVydGljYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJTY3JvbGxMZWZ0ID0gX3N0clNjcm9sbCArICdMZWZ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyU2Nyb2xsVG9wID0gX3N0clNjcm9sbCArICdUb3AnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50ID0gJ21vdXNlZG93biB0b3VjaHN0YXJ0JztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyTW91c2VUb3VjaFVwRXZlbnQgPSAnbW91c2V1cCB0b3VjaGVuZCB0b3VjaGNhbmNlbCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQgPSAnbW91c2Vtb3ZlIHRvdWNobW92ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlRW50ZXIgPSAnbW91c2VlbnRlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0ck1vdXNlTGVhdmUgPSAnbW91c2VsZWF2ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0cktleURvd25FdmVudCA9ICdrZXlkb3duJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyS2V5VXBFdmVudCA9ICdrZXl1cCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N0clNlbGVjdFN0YXJ0RXZlbnQgPSAnc2VsZWN0c3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQgPSAndHJhbnNpdGlvbmVuZCB3ZWJraXRUcmFuc2l0aW9uRW5kIG9UcmFuc2l0aW9uRW5kJztcclxuICAgICAgICAgICAgICAgIHZhciBfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eSA9ICdfX292ZXJsYXlTY3JvbGxiYXJzUk9fXyc7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jbGFzcyBuYW1lczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9jYXNzTmFtZXNQcmVmaXggPSAnb3MtJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSFRNTEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnaG9zdCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctZm9yZWlnbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXRleHRhcmVhJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhckhvcml6b250YWxIaWRkZW4gPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLScgKyBfc3RyU2Nyb2xsYmFyICsgX3N0ck1pbnVzSG9yaXpvbnRhbCArIF9zdHJNaW51c0hpZGRlbjtcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGJhclZlcnRpY2FsSGlkZGVuID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy0nICsgX3N0clNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsICsgX3N0ck1pbnVzSGlkZGVuO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbiA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctdHJhbnNpdGlvbic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSVEwgPSBfY2xhc3NOYW1lSG9zdEVsZW1lbnQgKyAnLXJ0bCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctcmVzaXplLWRpc2FibGVkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctc2Nyb2xsaW5nJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ID0gX2NsYXNzTmFtZUhvc3RFbGVtZW50ICsgJy1vdmVyZmxvdyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyA9IF9jbGFzc05hbWVIb3N0RWxlbWVudCArICctb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dYID0gX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyArICcteCc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1kgPSBfY2xhc3NOYW1lSG9zdE92ZXJmbG93ICsgJy15JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50ID0gX2Nhc3NOYW1lc1ByZWZpeCArICd0ZXh0YXJlYSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVRleHRhcmVhQ292ZXJFbGVtZW50ID0gX2NsYXNzTmFtZVRleHRhcmVhRWxlbWVudCArICctY292ZXInO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncGFkZGluZyc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndmlld3BvcnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNJbnZpc2libGUgPSBfY2xhc3NOYW1lVmlld3BvcnRFbGVtZW50ICsgJy1uYXRpdmUtc2Nyb2xsYmFycy1pbnZpc2libGUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCA9IF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQgKyAnLW5hdGl2ZS1zY3JvbGxiYXJzLW92ZXJsYWlkJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVDb250ZW50QXJyYW5nZUVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ2NvbnRlbnQtYXJyYW5nZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNvbnRlbnRHbHVlRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAnY29udGVudC1nbHVlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3NpemUtYXV0by1vYnNlcnZlcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCA9IF9jYXNzTmFtZXNQcmVmaXggKyAncmVzaXplLW9ic2VydmVyLWl0ZW0nO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQgPSBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRWxlbWVudCArICctZmluYWwnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA9IF9jYXNzTmFtZXNQcmVmaXggKyAndGV4dC1pbmhlcml0JztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyID0gX2Nhc3NOYW1lc1ByZWZpeCArIF9zdHJTY3JvbGxiYXI7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctdHJhY2snO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA9IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFjayArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlID0gX2NsYXNzTmFtZVNjcm9sbGJhciArICctaGFuZGxlJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlT2ZmID0gX2NsYXNzTmFtZVNjcm9sbGJhckhhbmRsZSArICctb2ZmJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy11bnVzYWJsZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckF1dG9IaWRkZW4gPSBfY2xhc3NOYW1lU2Nyb2xsYmFyICsgJy0nICsgX3N0ckF1dG8gKyBfc3RyTWludXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lciA9IF9jbGFzc05hbWVTY3JvbGxiYXIgKyAnLWNvcm5lcic7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXIgKyAnLXJlc2l6ZSc7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIgPSBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplICsgJy1ib3RoJztcclxuICAgICAgICAgICAgICAgIHZhciBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplSCA9IF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUgKyBfc3RyTWludXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVWID0gX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZSArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVTY3JvbGxiYXJIb3Jpem9udGFsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c0hvcml6b250YWw7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZVNjcm9sbGJhclZlcnRpY2FsID0gX2NsYXNzTmFtZVNjcm9sbGJhciArIF9zdHJNaW51c1ZlcnRpY2FsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVEcmFnZ2luZyA9IF9jYXNzTmFtZXNQcmVmaXggKyAnZHJhZ2dpbmcnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVUaGVtZU5vbmUgPSBfY2Fzc05hbWVzUHJlZml4ICsgJ3RoZW1lLW5vbmUnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kgPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVZpZXdwb3J0TmF0aXZlU2Nyb2xsYmFyc0ludmlzaWJsZSxcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzT3ZlcmxhaWQsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclRyYWNrT2ZmLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhclVudXNhYmxlLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuLFxyXG4gICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemUsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUIsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZVYsXHJcbiAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZURyYWdnaW5nXS5qb2luKF9zdHJTcGFjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9jYWxsYmFja3M6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfY2FsbGJhY2tzSW5pdFFldWV1ZSA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vYXR0cnMgdmlld3BvcnQgc2hhbGwgaW5oZXJpdCBmcm9tIHRhcmdldFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0ID0gW0xFWElDT04udGldO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vb3B0aW9uczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZWZhdWx0T3B0aW9ucztcclxuICAgICAgICAgICAgICAgIHZhciBfY3VycmVudE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnM7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9leHRlbnNpb25zOlx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2V4dGVuc2lvbnMgPSB7fTtcclxuICAgICAgICAgICAgICAgIHZhciBfZXh0ZW5zaW9uc1ByaXZhdGVNZXRob2RzID0gJ2FkZGVkIHJlbW92ZWQgb24gY29udHJhY3QnO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vdXBkYXRlXHRcclxuICAgICAgICAgICAgICAgIHZhciBfbGFzdFVwZGF0ZVRpbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3N3YWxsb3dVcGRhdGVMYWcgPSA0MjtcclxuICAgICAgICAgICAgICAgIHZhciBfdXBkYXRlT25Mb2FkRXZlbnROYW1lID0gJ2xvYWQnO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVPbkxvYWRFbG1zID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy9ET00gZWxlbWVudHM6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfd2luZG93RWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfZG9jdW1lbnRFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9odG1sRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfYm9keUVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnQ7ICAgICAgICAgICAgICAgICAgICAgLy90aGUgdGFyZ2V0IGVsZW1lbnQgb2YgdGhpcyBPdmVybGF5U2Nyb2xsYmFycyBvYmplY3RcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgICAgIC8vdGhlIGhvc3QgZWxlbWVudCBvZiB0aGlzIE92ZXJsYXlTY3JvbGxiYXJzIG9iamVjdCAtPiBtYXkgYmUgdGhlIHNhbWUgYXMgdGFyZ2V0RWxlbWVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50OyAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGF1dG8gY2hhbmdlc1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3NpemVPYnNlcnZlckVsZW1lbnQ7ICAgICAgICAgICAgICAgLy9vYnNlcnZlcyBzaXplIGFuZCBwYWRkaW5nIGNoYW5nZXNcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9wYWRkaW5nRWxlbWVudDsgICAgICAgICAgICAgICAgICAgIC8vbWFuYWdlcyB0aGUgcGFkZGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudDsgICAgICAgICAgICAgICAgICAgLy9pcyB0aGUgdmlld3BvcnQgb2Ygb3VyIHNjcm9sbGJhciBtb2RlbFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRFbGVtZW50OyAgICAgICAgICAgICAgICAgICAgLy90aGUgZWxlbWVudCB3aGljaCBob2xkcyB0aGUgY29udGVudFx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRBcnJhbmdlRWxlbWVudDsgICAgICAgICAgICAgLy9pcyBuZWVkZWQgZm9yIGNvcnJlY3Qgc2l6aW5nIG9mIHRoZSBjb250ZW50IGVsZW1lbnQgKG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhcnMgYXJlIG92ZXJsYXlzKVx0XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlRWxlbWVudDsgICAgICAgICAgICAgICAgLy9oYXMgYWx3YXlzIHRoZSBzaXplIG9mIHRoZSBjb250ZW50IGVsZW1lbnRcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUNvdmVyRWxlbWVudDsgICAgICAgICAgICAgIC8vb25seSBhcHBsaWVkIGlmIHRhcmdldCBpcyBhIHRleHRhcmVhIGVsZW1lbnQuIFVzZWQgZm9yIGNvcnJlY3Qgc2l6ZSBjYWxjdWxhdGlvbiBhbmQgZm9yIHByZXZlbnRpb24gb2YgdW5jb250cm9sbGVkIHNjcm9sbGluZ1x0XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsVHJhY2tFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF93aW5kb3dFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9kb2N1bWVudEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RhcmdldEVsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2hvc3RFbGVtZW50TmF0aXZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b09ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcGFkZGluZ0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnROYXRpdmU7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9DYWNoZTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9ob3N0U2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGFzT3ZlcmZsb3dDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaGlkZU92ZXJmbG93Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3dpZHRoQXV0b0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9oZWlnaHRBdXRvQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JveFNpemluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NQYWRkaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0JvcmRlckNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jc3NNYXJnaW5DYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY3NzRGlyZWN0aW9uQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9jbGlwQWx3YXlzQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NvbnRlbnRHbHVlU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfYXV0b1VwZGF0ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zaXplQXV0b0NhcGFibGVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzRHJhZ1Njcm9sbGluZ0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9yZXNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfbm9ybWFsaXplUlRMQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX2NsYXNzTmFtZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9vbGRDbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGU7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3RleHRhcmVhSW5mb0NhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYVNpemVDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZTtcclxuICAgICAgICAgICAgICAgIHZhciBfdGV4dGFyZWFEeW5XaWR0aENhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9ib2R5TWluU2l6ZUNhY2hlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF91cGRhdGVBdXRvQ2FjaGUgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL011dGF0aW9uT2JzZXJ2ZXI6XHRcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckhvc3Q7XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVySG9zdENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudENhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZDtcclxuICAgICAgICAgICAgICAgIHZhciBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgPSBbJ3dyYXAnLCAnY29scycsICdyb3dzJ107XHJcbiAgICAgICAgICAgICAgICB2YXIgX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QgPSBbTEVYSUNPTi5pLCBMRVhJQ09OLmMsIExFWElDT04ucywgJ29wZW4nXS5jb25jYXQoX3ZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL2V2ZW50czpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9kZXN0cm95RXZlbnRzID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgLy90ZXh0YXJlYTpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF90ZXh0YXJlYUhhc0ZvY3VzO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFyczpcdFxyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNBdXRvSGlkZURlbGF5O1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlcjtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlO1xyXG4gICAgICAgICAgICAgICAgdmFyIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZTtcclxuICAgICAgICAgICAgICAgIHZhciBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQ7XHJcbiAgICAgICAgICAgICAgICB2YXIgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zO1xyXG5cclxuICAgICAgICAgICAgICAgIC8vcmVzaXplXHRcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplTm9uZTtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplQm90aDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplSG9yaXpvbnRhbDtcclxuICAgICAgICAgICAgICAgIHZhciBfcmVzaXplVmVydGljYWw7XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudCBMaXN0ZW5lciA9PT09Ly9cdFxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSBldmVudCBsaXN0ZW5lciBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LiBcdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdG8gd2hpY2ggdGhlIGV2ZW50IGxpc3RlbmVyIHNoYWxsIGJlIGFwcGxpZWQgb3IgcmVtb3ZlZC5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50TmFtZXMgVGhlIG5hbWUocykgb2YgdGhlIGV2ZW50cy5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGxpc3RlbmVyIFRoZSBtZXRob2Qgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcmVtb3ZlIFRydWUgaWYgdGhlIGhhbmRsZXIgc2hhbGwgYmUgcmVtb3ZlZCwgZmFsc2Ugb3IgdW5kZWZpbmVkIGlmIHRoZSBoYW5kbGVyIHNoYWxsIGJlIGFkZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcGFzc2l2ZU9yT3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGV2ZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZXMsIGxpc3RlbmVyLCByZW1vdmUsIHBhc3NpdmVPck9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29sbGVjdGVkID0gQ09NUEFUSUJJTElUWS5pc0EoZXZlbnROYW1lcykgJiYgQ09NUEFUSUJJTElUWS5pc0EobGlzdGVuZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2QgPSByZW1vdmUgPyAncmVtb3ZlRXZlbnRMaXN0ZW5lcicgOiAnYWRkRXZlbnRMaXN0ZW5lcic7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9uT2ZmID0gcmVtb3ZlID8gJ29mZicgOiAnb24nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBldmVudHMgPSBjb2xsZWN0ZWQgPyBmYWxzZSA6IGV2ZW50TmFtZXMuc3BsaXQoX3N0clNwYWNlKVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhc3NpdmVPck9wdGlvbnNJc09iaiA9IEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KHBhc3NpdmVPck9wdGlvbnMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYXNzaXZlID0gKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyAmJiAocGFzc2l2ZU9yT3B0aW9uc0lzT2JqID8gKHBhc3NpdmVPck9wdGlvbnMuX3Bhc3NpdmUpIDogcGFzc2l2ZU9yT3B0aW9ucykpIHx8IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYXB0dXJlID0gcGFzc2l2ZU9yT3B0aW9uc0lzT2JqICYmIChwYXNzaXZlT3JPcHRpb25zLl9jYXB0dXJlIHx8IGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmF0aXZlUGFyYW0gPSBfc3VwcG9ydFBhc3NpdmVFdmVudHMgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhc3NpdmU6IHBhc3NpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmU6IGNhcHR1cmUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IGNhcHR1cmU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb2xsZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7IGkgPCBldmVudE5hbWVzW0xFWElDT04ubF07IGkrKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lc1tpXSwgbGlzdGVuZXJbaV0sIHJlbW92ZSwgcGFzc2l2ZU9yT3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IGV2ZW50c1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKF9zdXBwb3J0UGFzc2l2ZUV2ZW50cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbMF1bbWV0aG9kXShldmVudHNbaV0sIGxpc3RlbmVyLCBuYXRpdmVQYXJhbSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50W29uT2ZmXShldmVudHNbaV0sIGxpc3RlbmVyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgcGFzc2l2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lcywgbGlzdGVuZXIsIGZhbHNlLCBwYXNzaXZlKTtcclxuICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wdXNoKENPTVBBVElCSUxJVFkuYmluZChzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyLCAwLCBlbGVtZW50LCBldmVudE5hbWVzLCBsaXN0ZW5lciwgdHJ1ZSwgcGFzc2l2ZSkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBSZXNpemUgT2JzZXJ2ZXIgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgYSByZXNpemUgb2JzZXJ2ZXIgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSByZXNpemUgb2JzZXJ2ZXIgc2hhbGwgYmUgYWRkZWQgb3IgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2sgVGhlIGNhbGxiYWNrIHdoaWNoIGlzIGZpcmVkIGV2ZXJ5IHRpbWUgdGhlIHJlc2l6ZSBvYnNlcnZlciByZWdpc3RlcnMgYSBzaXplIGNoYW5nZSBvciBmYWxzZSAvIHVuZGVmaW5lZCBpZiB0aGUgcmVzaXplT2JzZXJ2ZXIgc2hhbGwgYmUgcmVtb3ZlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBSZXNpemVPYnNlcnZlcih0YXJnZXRFbGVtZW50LCBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplT2JzZXJ2ZXIgPSBDT01QQVRJQklMSVRZLnJPKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBbmltYXRpb25TdGFydEV2ZW50ID0gJ2FuaW1hdGlvbnN0YXJ0IG1vekFuaW1hdGlvblN0YXJ0IHdlYmtpdEFuaW1hdGlvblN0YXJ0IE1TQW5pbWF0aW9uU3RhcnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQ2hpbGROb2RlcyA9ICdjaGlsZE5vZGVzJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnN0U2Nyb2xsID0gMzMzMzMzMztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXShjb25zdFNjcm9sbClbX3N0clNjcm9sbExlZnRdKF9pc1JUTCA/IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGwgOiBjb25zdFNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkVsZW1lbnRSZXNpemVkQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgcmVzaXplIG9ic2VydmVyOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25FbGVtZW50UmVzaXplZENhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5hZGRDbGFzcygnb2JzZXJ2ZWQnKS5hcHBlbmQoZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkpLmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyID0gZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0gPSBuZXcgcmVzaXplT2JzZXJ2ZXIoY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9ic2VydmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX21zaWVWZXJzaW9uID4gOSB8fCAhX2F1dG9VcGRhdGVSZWNvbW1lbmRlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50LnByZXBlbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlRGl2KHsgYzogX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsIGRpcjogJ2x0cicgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdihfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJJdGVtRmluYWxFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVEaXYoX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVySXRlbUVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZURpdih7IGM6IF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckl0ZW1GaW5hbEVsZW1lbnQsIHN0eWxlOiAnd2lkdGg6IDIwMCU7IGhlaWdodDogMjAwJScgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYnNlcnZlckVsZW1lbnQgPSB0YXJnZXRFbGVtZW50WzBdW3N0ckNoaWxkTm9kZXNdWzBdW3N0ckNoaWxkTm9kZXNdWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2hyaW5rRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudCA9IEZSQU1FV09SSyhvYnNlcnZlckVsZW1lbnRbc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXhwYW5kRWxlbWVudENoaWxkID0gRlJBTUVXT1JLKGV4cGFuZEVsZW1lbnRbMF1bc3RyQ2hpbGROb2Rlc11bMF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhDYWNoZSA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodENhY2hlID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNEaXJ0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJBRklkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VycldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZhY3RvciA9IDI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGxiYXJTaXplID0gZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJTaXplOyAvL2NhcmUgZG9uJ3QgbWFrZSBjaGFuZ2VzIHRvIHRoaXMgb2JqZWN0ISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldFdpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICogZmFjdG9yICsgbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICogZmFjdG9yICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVSZXNldEhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXSArIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIGZhY3RvciArIG5hdGl2ZVNjcm9sbGJhclNpemUueSAqIGZhY3RvciArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLnggKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJXaWR0aF0gPSBzaXplUmVzZXRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RySGVpZ2h0XSA9IHNpemVSZXNldEhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50Q2hpbGQuY3NzKGV4cGFuZENoaWxkQ1NTKTtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNocmlua0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNpemVSZXNldFdpZHRoKVtfc3RyU2Nyb2xsVG9wXShzaXplUmVzZXRIZWlnaHQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XShjb25zdFNjcm9sbClbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hyaW5rRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY29uc3RTY3JvbGwpW19zdHJTY3JvbGxUb3BdKGNvbnN0U2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9uUmVzaXplZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNEaXJ0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhDYWNoZSA9IGN1cnJXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodENhY2hlID0gY3VyckhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvblNjcm9sbCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycldpZHRoID0gb2JzZXJ2ZXJFbGVtZW50W0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyckhlaWdodCA9IG9ic2VydmVyRWxlbWVudFtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRGlydHkgPSBjdXJyV2lkdGggIT0gd2lkdGhDYWNoZSB8fCBjdXJySGVpZ2h0ICE9IGhlaWdodENhY2hlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudCAmJiBpc0RpcnR5ICYmICFyQUZJZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuY0FGKCkockFGSWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJBRklkID0gQ09NUEFUSUJJTElUWS5yQUYoKShvblJlc2l6ZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWV2ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uUmVzaXplZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnBydkQoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHBhbmRDaGlsZENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXJFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQob2JzZXJ2ZXJFbGVtZW50Q1NTLCBfc3RyRW1wdHksIFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0oKG5hdGl2ZVNjcm9sbGJhclNpemUueSArIDEpICogZmFjdG9yKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNjcm9sbGJhclNpemUueCAqIC1mYWN0b3IsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTY3JvbGxiYXJTaXplLnkgKiAtZmFjdG9yLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSgobmF0aXZlU2Nyb2xsYmFyU2l6ZS54ICsgMSkgKiBmYWN0b3IpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKG9ic2VydmVyRWxlbWVudCkuY3NzKG9ic2VydmVyRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnQub24oX3N0clNjcm9sbCwgb25TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaHJpbmtFbGVtZW50Lm9uKF9zdHJTY3JvbGwsIG9uU2Nyb2xsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5vbihzdHJBbmltYXRpb25TdGFydEV2ZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xldHMgYXNzdW1lIHRoYXQgdGhlIGRpdnMgd2lsbCBuZXZlciBiZSB0aGF0IGxhcmdlIGFuZCBhIGNvbnN0YW50IHZhbHVlIGlzIGVub3VnaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBhbmRDaGlsZENTU1tfc3RyV2lkdGhdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZENoaWxkQ1NTW19zdHJIZWlnaHRdID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZEVsZW1lbnRDaGlsZC5jc3MoZXhwYW5kQ2hpbGRDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRhY2hFdmVudCA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuYXR0YWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpc0lFID0gX21zaWVWZXJzaW9uICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRhY2hFdmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKGdlbmVyYXRlRGl2KF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmRGaXJzdCh0YXJnZXRFbGVtZW50LCBfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudClbMF0uYXR0YWNoRXZlbnQoJ29ucmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9iaiA9IF9kb2N1bWVudEVsZW1lbnROYXRpdmUuY3JlYXRlRWxlbWVudChUWVBFUy5vKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zZXRBdHRyaWJ1dGUoTEVYSUNPTi50aSwgJy0xJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc2V0QXR0cmlidXRlKExFWElDT04uYywgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoub25sb2FkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSB0aGlzLmNvbnRlbnREb2N1bWVudC5kZWZhdWx0VmlldztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3bmQuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHduZC5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmoudHlwZSA9ICd0ZXh0L2h0bWwnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGF0YSA9ICdhYm91dDpibGFuayc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzSUUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5wcmVwZW5kKG9iaik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50Lm9uKHN0ckFuaW1hdGlvblN0YXJ0RXZlbnQsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFyZ2V0RWxlbWVudFswXSA9PT0gX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRpciA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxMZWZ0VmFsdWUgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXIgIT09IF9jc3NEaXJlY3Rpb25EZXRlY3RlZENhY2hlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyID09PSAnbHRyJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTGVmdF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyUmlnaHRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsTGVmdFZhbHVlID0gY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckxlZnRdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJSaWdodF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbExlZnRWYWx1ZSA9IF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLWNvbnN0U2Nyb2xsIDogX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAwIDogY29uc3RTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2V4ZWN1dGlvbiBvcmRlciBpcyBpbXBvcnRhbnQgZm9yIElFISEhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudC5jaGlsZHJlbigpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnRbX3N0clNjcm9sbExlZnRdKHNjcm9sbExlZnRWYWx1ZSlbX3N0clNjcm9sbFRvcF0oY29uc3RTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkRldGVjdGVkQ2FjaGUgPSBkaXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb25DaGFuZ2VkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIodGFyZ2V0RWxlbWVudCwgX3N0clNjcm9sbCwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb25DaGFuZ2VkKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHJlc2l6ZSBvYnNlcnZlcjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVPYnNlcnZlck9iaiA9IGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVPYnNlcnZlck9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNpemVPYnNlcnZlck9iai5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50W19zdHJSZXNpemVPYnNlcnZlclByb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUodGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVJlc2l6ZU9ic2VydmVyRWxlbWVudCkuZXEoMCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRnJlZXplcyBvciB1bmZyZWV6ZXMgdGhlIGdpdmVuIHJlc2l6ZSBvYnNlcnZlci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB0YXJnZXRFbGVtZW50IFRoZSBlbGVtZW50IHRvIHdoaWNoIHRoZSB0YXJnZXQgcmVzaXplIG9ic2VydmVyIGlzIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZnJlZXplIFRydWUgaWYgdGhlIHJlc2l6ZSBvYnNlcnZlciBzaGFsbCBiZSBmcm96ZW4sIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGZyZWV6ZVJlc2l6ZU9ic2VydmVyKHRhcmdldEVsZW1lbnQsIGZyZWV6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXRFbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYoZnJlZXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRSZXNpemVPYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gdGFyZ2V0RWxlbWVudC5jb250ZW50cygpWzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRbX3N0clJlc2l6ZU9ic2VydmVyUHJvcGVydHldLnVub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNoaWxkcmVuKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KS5lcSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdyA9IHRhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGggPSB0YXJnZXRFbGVtZW50LmNzcyhfc3RySGVpZ2h0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSB3O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFJlc2l6ZU9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB0YXJnZXRFbGVtZW50LmNvbnRlbnRzKClbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFtfc3RyUmVzaXplT2JzZXJ2ZXJQcm9wZXJ0eV0ub2JzZXJ2ZShlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjc3MgPSB7IH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJIZWlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQuY2hpbGRyZW4oX3N0ckRvdCArIF9jbGFzc05hbWVSZXNpemVPYnNlcnZlckVsZW1lbnQpLmVxKDApLmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgKi9cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IE11dGF0aW9uIE9ic2VydmVycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENyZWF0ZXMgTXV0YXRpb25PYnNlcnZlcnMgZm9yIHRoZSBob3N0IGFuZCBjb250ZW50IEVsZW1lbnQgaWYgdGhleSBhcmUgc3VwcG9ydGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRNdXRhdGlvbk9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyA9IDExO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25PYnNlcnZlciA9IENPTVBBVElCSUxJVFkubU8oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRMYXN0VXBkYXRlID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXV0YXRpb25BdHRyTmFtZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uSXNDbGFzcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZE11dGF0aW9uVmFsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Q2xhc3NWYWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0Q2xhc3NOYW1lUmVnZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50VGltZW91dDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2sgPSBmdW5jdGlvbiAobXV0YXRpb25zKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvVXBkYXRlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVGb3JjZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0ZWRBdHRycyA9IFtdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXQgPSBtdXRhdGlvbi50YXJnZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uQXR0ck5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbklzQ2xhc3MgPSBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLmM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZE11dGF0aW9uVmFsID0gbXV0YXRpb24ub2xkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0NsYXNzVmFsID0gbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgbXV0YXRpb25Jc0NsYXNzICYmICFkb1VwZGF0ZUZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBvbGQgY2xhc3MgdmFsdWUgY29udGFpbnMgX2NsYXNzTmFtZUhvc3RFbGVtZW50Rm9yZWlnbiBhbmQgbmV3IGNsYXNzIHZhbHVlIGRvZXNuJ3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbGRNdXRhdGlvblZhbC5pbmRleE9mKF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pID4gLTEgJiYgbmV3Q2xhc3NWYWwuaW5kZXhPZihfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0Q2xhc3NOYW1lUmVnZXggPSBjcmVhdGVIb3N0Q2xhc3NOYW1lUmVnRXhwKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudE5hdGl2ZS5jbGFzc05hbWUgPSBuZXdDbGFzc1ZhbC5zcGxpdChfc3RyU3BhY2UpLmNvbmNhdChvbGRNdXRhdGlvblZhbC5zcGxpdChfc3RyU3BhY2UpLmZpbHRlcihmdW5jdGlvbiAobmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmFtZS5tYXRjaChob3N0Q2xhc3NOYW1lUmVnZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKS5qb2luKF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBkb1VwZGF0ZUZvcmNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBtdXRhdGlvbklzQ2xhc3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGhvc3RDbGFzc05hbWVzQ2hhbmdlZChvbGRNdXRhdGlvblZhbCwgbmV3Q2xhc3NWYWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBtdXRhdGlvbkF0dHJOYW1lID09PSBMRVhJQ09OLnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBvbGRNdXRhdGlvblZhbCAhPT0gbXV0YXRpb25UYXJnZXRbTEVYSUNPTi5zXS5jc3NUZXh0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlZEF0dHJzLnB1c2gobXV0YXRpb25BdHRyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KG11dGF0ZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKGRvVXBkYXRlRm9yY2UgfHwgX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvVXBkYXRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayA9IGZ1bmN0aW9uIChtdXRhdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb1VwZGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaW5pdGlhbGl6ZWQgJiYgIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2gobXV0YXRpb25zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGUgPSBpc1Vua25vd25NdXRhdGlvbihtdXRhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhZG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBDT01QQVRJQklMSVRZLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0byA9IChfaGVpZ2h0QXV0b0NhY2hlIHx8IF93aWR0aEF1dG9DYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRMYXN0VXBkYXRlID0gbm93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGNvbHMsIHJvd3Mgb3Igd3JhcCBhdHRyIHdhcyBjaGFuZ2VkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNvbnRlbnRUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uT2JzZXJ2ZXJDb250ZW50TGFnIDw9IDAgfHwgbm93IC0gY29udGVudExhc3RVcGRhdGUgPiBtdXRhdGlvbk9ic2VydmVyQ29udGVudExhZyB8fCAhc2l6ZUF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFRpbWVvdXQgPSBzZXRUaW1lb3V0KGFjdGlvbiwgbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX211dGF0aW9uT2JzZXJ2ZXJIb3N0ID0gbmV3IG11dGF0aW9uT2JzZXJ2ZXIoX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQgPSBuZXcgbXV0YXRpb25PYnNlcnZlcihfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgIV9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckhvc3Qub2JzZXJ2ZShfaG9zdEVsZW1lbnROYXRpdmUsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVPbGRWYWx1ZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQub2JzZXJ2ZShfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50TmF0aXZlIDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlT2xkVmFsdWU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0cmVlOiAhX2lzVGV4dGFyZWEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZExpc3Q6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGE6ICFfaXNUZXh0YXJlYSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcjogX2lzVGV4dGFyZWEgPyBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWEgOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzSG9zdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyc0Nvbm5lY3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogRGlzY29ubmVjdHMgdGhlIE11dGF0aW9uT2JzZXJ2ZXJzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXIgJiYgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVySG9zdC5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9tdXRhdGlvbk9ic2VydmVyQ29udGVudC5kaXNjb25uZWN0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBFdmVudHMgb2YgZWxlbWVudHMgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGlzIG1ldGhvZCBnZXRzIGNhbGxlZCBldmVyeSB0aW1lIHRoZSBob3N0IGVsZW1lbnQgZ2V0cyByZXNpemVkLiBJTVBPUlRBTlQ6IFBhZGRpbmcgY2hhbmdlcyBhcmUgZGV0ZWN0ZWQgdG9vISFcclxuICAgICAgICAgICAgICAgICAqIEl0IHJlZnJlc2hlcyB0aGUgaG9zdFJlc2l6ZWRFdmVudEFyZ3MgYW5kIHRoZSBob3N0U2l6ZVJlc2l6ZUNhY2hlLlxyXG4gICAgICAgICAgICAgICAgICogSWYgdGhlcmUgYXJlIGFueSBzaXplIGNoYW5nZXMsIHRoZSB1cGRhdGUgbWV0aG9kIGdldHMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25SZXNpemVkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfc2l6ZU9ic2VydmVyRWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IF9zaXplT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VkID0gY2hlY2tDYWNoZShob3N0U2l6ZSwgX2hvc3RFbGVtZW50U2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGhvc3RTaXplO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIGVudGVyIGV2ZW50IG9mIHRoZSBob3N0IGVsZW1lbnQuIFRoaXMgZXZlbnQgaXMgb25seSBuZWVkZWQgZm9yIHRoZSBhdXRvSGlkZSBmZWF0dXJlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0T25Nb3VzZUVudGVyKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgbW91c2UgbGVhdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTGVhdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX2JvZHlFbGVtZW50Lmhhc0NsYXNzKF9jbGFzc05hbWVEcmFnZ2luZykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIG1vdXNlIG1vdmUgZXZlbnQgb2YgdGhlIGhvc3QgZWxlbWVudC4gVGhpcyBldmVudCBpcyBvbmx5IG5lZWRlZCBmb3IgdGhlIGF1dG9IaWRlIFwibW92ZVwiIGZlYXR1cmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhvc3RPbk1vdXNlTW92ZSgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSAmJiAhX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQcmV2ZW50cyB0ZXh0IGZyb20gZGVzZWxlY3Rpb24gaWYgYXR0YWNoZWQgdG8gdGhlIGRvY3VtZW50IGVsZW1lbnQgb24gdGhlIG1vdXNlZG93biBldmVudCBvZiBhIERPTSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV2ZW50IFRoZSBzZWxlY3Qgc3RhcnQgZXZlbnQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRvY3VtZW50T25TZWxlY3RTdGFydChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBBIGNhbGxiYWNrIHdoaWNoIHdpbGwgYmUgY2FsbGVkIGFmdGVyIGEgZWxlbWVudCBoYXMgbG9hZGVkLlx0XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZU9uTG9hZENhbGxiYWNrKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsbSA9IEZSQU1FV09SSyhldmVudC50YXJnZXQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBlYWNoVXBkYXRlT25Mb2FkKGZ1bmN0aW9uIChpLCB1cGRhdGVPbkxvYWRTZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxtLmlzKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgbW91c2UgJiB0b3VjaCBldmVudHMgb2YgdGhlIGhvc3QgZWxlbWVudC4gKGZvciBoYW5kbGluZyBhdXRvLWhpZGluZyBvZiB0aGUgc2Nyb2xsYmFycylcclxuICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIGV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoTW92ZUV2ZW50LnNwbGl0KF9zdHJTcGFjZSlbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTW92ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKCFfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBkZXN0cm95KSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfaG9zdEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyTW91c2VFbnRlciwgX3N0ck1vdXNlTGVhdmVdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbaG9zdE9uTW91c2VFbnRlciwgaG9zdE9uTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICghX3Njcm9sbGJhcnNBdXRvSGlkZUxlYXZlIHx8IGRlc3Ryb3kpLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGUgcGx1Z2luIGlzIGluaXRpYWxpemVkIGFuZCB0aGUgbW91c2UgaXMgb3ZlciB0aGUgaG9zdCBlbGVtZW50LCBtYWtlIHRoZSBzY3JvbGxiYXJzIHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV9pbml0aWFsaXplZCAmJiAhZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50Lm9uZSgnbW91c2VvdmVyJywgaG9zdE9uTW91c2VFbnRlcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBVcGRhdGUgRGV0ZWN0aW9uID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogTWVhc3VyZXMgdGhlIG1pbiB3aWR0aCBhbmQgbWluIGhlaWdodCBvZiB0aGUgYm9keSBlbGVtZW50IGFuZCByZWZyZXNoZXMgdGhlIHJlbGF0ZWQgY2FjaGUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgbWluIHdpZHRoIG9yIG1pbiBoZWlnaHQgaGFzIGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gYm9keU1pblNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5ICYmIF9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUudyA9IHBhcnNlVG9aZXJvT3JOdW1iZXIoX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplLmggPSBwYXJzZVRvWmVyb09yTnVtYmVyKF9jb250ZW50QXJyYW5nZUVsZW1lbnQuY3NzKF9zdHJNaW5NaW51cyArIF9zdHJIZWlnaHQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuYyA9IGNoZWNrQ2FjaGUoYm9keU1pblNpemUsIF9ib2R5TWluU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1pblNpemUuZiA9IHRydWU7IC8vZmxhZyBmb3IgXCJtZWFzdXJlZCBhdCBsZWFzdCBvbmNlXCJcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlNaW5TaXplQ2FjaGUgPSBib2R5TWluU2l6ZTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gISFib2R5TWluU2l6ZS5jO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjbGFzcyBuYW1lcyByZWFsbHkgY2hhbmdlZCAobmV3IGNsYXNzIHdpdGhvdXQgcGx1Z2luIGhvc3QgcHJlZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9sZENsYXNzTmFtZXMgVGhlIG9sZCBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG5ld0NsYXNzTmFtZXMgVGhlIG5ldyBDbGFzc05hbWUgc3RyaW5nIG9yIGFycmF5LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNsYXNzIG5hbWVzIGhhcyByZWFsbHkgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBob3N0Q2xhc3NOYW1lc0NoYW5nZWQob2xkQ2xhc3NOYW1lcywgbmV3Q2xhc3NOYW1lcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyQ2xhc3NlcyA9IHR5cGVvZiBuZXdDbGFzc05hbWVzID09IFRZUEVTLnMgPyBuZXdDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2xkQ2xhc3NlcyA9IHR5cGVvZiBvbGRDbGFzc05hbWVzID09IFRZUEVTLnMgPyBvbGRDbGFzc05hbWVzLnNwbGl0KF9zdHJTcGFjZSkgOiBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZGlmZiA9IGdldEFycmF5RGlmZmVyZW5jZXMob2xkQ2xhc3NlcywgY3VyckNsYXNzZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgbm9uZSB0aGVtZSBmcm9tIGRpZmYgbGlzdCB0byBwcmV2ZW50IHVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBpbkFycmF5KF9jbGFzc05hbWVUaGVtZU5vbmUsIGRpZmYpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWdleDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnNwbGljZShpZHgsIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGlmZltMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWdleCA9IGNyZWF0ZUhvc3RDbGFzc05hbWVSZWdFeHAodHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRpZmZbaV0ubWF0Y2gocmVnZXgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtdXRhdGlvbiBpcyBub3QgZnJvbSBhIGZyb20gdGhlIHBsdWdpbiBnZW5lcmF0ZWQgZWxlbWVudC4gSWYgdGhlIHRhcmdldCBlbGVtZW50IGlzIGEgdGV4dGFyZWEgdGhlIG11dGF0aW9uIGlzIGFsd2F5cyB1bmtub3duLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG11dGF0aW9uIFRoZSBtdXRhdGlvbiB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG11dGF0aW9uIGlzIGZyb20gYSB1bmtub3duIGVsZW1lbnQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNVbmtub3duTXV0YXRpb24obXV0YXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlTmFtZSA9IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG11dGF0aW9uVGFyZ2V0ID0gbXV0YXRpb24udGFyZ2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRhdGlvblR5cGUgPSBtdXRhdGlvbi50eXBlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbG9zZXN0ID0gJ2Nsb3Nlc3QnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAobXV0YXRpb25UYXJnZXQgPT09IF9jb250ZW50RWxlbWVudE5hdGl2ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZU5hbWUgPT09IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVHlwZSA9PT0gJ2F0dHJpYnV0ZXMnICYmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgfHwgYXR0cmlidXRlTmFtZSA9PT0gTEVYSUNPTi5zKSAmJiAhX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZ25vcmUgY2xhc3NOYW1lIGNoYW5nZXMgYnkgdGhlIHBsdWdpblx0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVOYW1lID09PSBMRVhJQ09OLmMgJiYgRlJBTUVXT1JLKG11dGF0aW9uVGFyZ2V0KS5oYXNDbGFzcyhfY2xhc3NOYW1lSG9zdEVsZW1lbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhvc3RDbGFzc05hbWVzQ2hhbmdlZChtdXRhdGlvbi5vbGRWYWx1ZSwgbXV0YXRpb25UYXJnZXQuY2xhc3NOYW1lKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSBkbyBpdCBvZiBicm93c2VyIHN1cHBvcnQgaXQgbmF0aXZlbHlcdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdICE9IFRZUEVTLmYpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG11dGF0aW9uVGFyZ2V0W3N0ckNsb3Nlc3RdKF9zdHJEb3QgKyBfY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJFbGVtZW50KSAhPT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb25UYXJnZXRbc3RyQ2xvc2VzdF0oX3N0ckRvdCArIF9jbGFzc05hbWVTY3JvbGxiYXIpICE9PSBudWxsIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGlvblRhcmdldFtzdHJDbG9zZXN0XShfc3RyRG90ICsgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lcikgIT09IG51bGwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBjb250ZW50IHNpemUgd2FzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGlzIG1ldGhvZCB3YXMgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNvbnRlbnQgc2l6ZSB3YXMgY2hhbmdlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGVBdXRvQ29udGVudFNpemVDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRNZWFzdXJlRWxlbWVudCA9IGdldENvbnRlbnRNZWFzdXJlRWxlbWVudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVZhbHVlTGVuZ3RoID0gX2lzVGV4dGFyZWEgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZSA/IF90YXJnZXRFbGVtZW50LnZhbCgpLmxlbmd0aCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldENTUyA9ICFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQgJiYgX3dpZHRoQXV0b0NhY2hlICYmICFfaXNUZXh0YXJlYTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBib2R5TWluU2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldENTUykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCA9IF9jb250ZW50RWxlbWVudC5jc3MoX3N0ckZsb2F0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudFNjcm9sbFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSArIHRleHRhcmVhVmFsdWVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSArIHRleHRhcmVhVmFsdWVMZW5ndGhcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXRDU1MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJGbG9hdF0gPSBmbG9hdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY3NzKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQyA9IGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWQgPSBjaGVja0NhY2hlKGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZSwgX2NvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZUNoYW5nZURldGVjdGVkQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnRTY3JvbGxTaXplQ2hhbmdlRGV0ZWN0ZWRDYWNoZSA9IGNvbnRlbnRFbGVtZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5nZWQgfHwgYm9keU1pblNpemVDO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyB0cnVlIHdoZW4gYSBhdHRyaWJ1dGUgd2hpY2ggdGhlIE11dGF0aW9uT2JzZXJ2ZXIgd291bGQgb2JzZXJ2ZSBoYXMgY2hhbmdlZC4gIFxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgb25lIG9mIHRoZSBhdHRyaWJ1dGVzIHdoaWNoIGEgTXV0YXRpb25PYnNlcnZlciB3b3VsZCBvYnNlcnZlIGhhcyBjaGFuZ2VkLCBmYWxzZSBvciB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBtZWFuaW5nZnVsQXR0cnNDaGFuZ2VkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc2xlZXBpbmcgfHwgX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlZEF0dHJzID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoZWNrcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2VsZW06IF9ob3N0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9hdHRyczogX211dGF0aW9uT2JzZXJ2ZXJBdHRyc0hvc3QuY29uY2F0KCc6dmlzaWJsZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9lbGVtOiBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50IDogdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2F0dHJzOiBfbXV0YXRpb25PYnNlcnZlckF0dHJzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2tzLCBmdW5jdGlvbiAoaW5kZXgsIGNoZWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0gPSBjaGVjay5fZWxlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goY2hlY2suX2F0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyID0gYXR0ci5jaGFyQXQoMCkgPT09ICc6JyA/IGVsZW0uaXMoYXR0cikgOiBlbGVtLmF0dHIoYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tDYWNoZShjdXJyLCBjYWNoZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZEF0dHJzLnB1c2goYXR0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlQXV0b0NhY2hlW2F0dHJdID0gY3VycjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVZpZXdwb3J0QXR0cnNGcm9tVGFyZ2V0KGNoYW5nZWRBdHRycyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjaGFuZ2VkQXR0cnNbTEVYSUNPTi5sXSA+IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDaGVja3MgaXMgYSBDU1MgUHJvcGVydHkgb2YgYSBjaGlsZCBlbGVtZW50IGlzIGFmZmVjdGluZyB0aGUgc2Nyb2xsIHNpemUgb2YgdGhlIGNvbnRlbnQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gcHJvcGVydHlOYW1lIFRoZSBDU1MgcHJvcGVydHkgbmFtZS5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwcm9wZXJ0eSBpcyBhZmZlY3RpbmcgdGhlIGNvbnRlbnQgc2Nyb2xsIHNpemUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gaXNTaXplQWZmZWN0aW5nQ1NTUHJvcGVydHkocHJvcGVydHlOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfaW5pdGlhbGl6ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4R3JvdyA9ICdmbGV4LWdyb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmbGV4U2hyaW5rID0gJ2ZsZXgtc2hyaW5rJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmxleEJhc2lzID0gJ2ZsZXgtYmFzaXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZmZlY3RpbmdQcm9wc1ggPSBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RyV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNYXJnaW5NaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUmlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdmb250LXdlaWdodCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICd3b3JkLXNwYWNpbmcnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNYQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJMZWZ0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyUGFkZGluZ01pbnVzICsgX3N0clJpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyTGVmdCArIF9zdHJXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ckJvcmRlck1pbnVzICsgX3N0clJpZ2h0ICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWluTWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWF4TWludXMgKyBfc3RySGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyTWFyZ2luTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyVG9wLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnbGluZS1oZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmbGV4R3JvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleFNocmluayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmxleEJhc2lzXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWZmZWN0aW5nUHJvcHNZQ29udGVudEJveCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3AsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJQYWRkaW5nTWludXMgKyBfc3RyQm90dG9tLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyVG9wICsgX3N0cldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyQm9yZGVyTWludXMgKyBfc3RyQm90dG9tICsgX3N0cldpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgX3N0clMgPSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIF9zdHJWUyA9ICd2LXMnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1ggPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnggPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueCA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1kgPSBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLnkgPT09IF9zdHJTIHx8IF9vdmVyZmxvd0JlaGF2aW9yQ2FjaGUueSA9PT0gX3N0clZTO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzaXplSXNBZmZlY3RlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGVja1Byb3BlcnR5TmFtZSA9IGZ1bmN0aW9uIChhcnIsIG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnJbTEVYSUNPTi5sXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hlY2tZKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNZLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWUNvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGVja1ggJiYgIXNpemVJc0FmZmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVJc0FmZmVjdGVkID0gY2hlY2tQcm9wZXJ0eU5hbWUoYWZmZWN0aW5nUHJvcHNYLCBwcm9wZXJ0eU5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNpemVJc0FmZmVjdGVkICYmICFfaXNCb3JkZXJCb3gpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplSXNBZmZlY3RlZCA9IGNoZWNrUHJvcGVydHlOYW1lKGFmZmVjdGluZ1Byb3BzWENvbnRlbnRCb3gsIHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzaXplSXNBZmZlY3RlZDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFVwZGF0ZSA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIGF0dHJpYnV0ZSB2YWx1ZXMgb2YgdGhlIHZpZXdwb3J0IGVsZW1lbnQgdG8gdGhlIHZhbHVlcyBmcm9tIHRoZSB0YXJnZXQgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIFRoZSB2YWx1ZSBvZiBhIGF0dHJpYnV0ZSBpcyBvbmx5IHNldCBpZiB0aGUgYXR0cmlidXRlIGlzIHdoaXRlbGlzdGVkLlxyXG4gICAgICAgICAgICAgICAgICogQGF0dHJzIGF0dHJzIFRoZSBhcnJheSBvZiBhdHRyaWJ1dGVzIHdoaWNoIHNoYWxsIGJlIHNldCBvciB1bmRlZmluZWQgaWYgYWxsIHdoaXRlbGlzdGVkIHNoYWxsIGJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gdXBkYXRlVmlld3BvcnRBdHRyc0Zyb21UYXJnZXQoYXR0cnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBhdHRycyA9IGF0dHJzIHx8IF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldDtcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKGF0dHJzLCBmdW5jdGlvbiAoaW5kZXgsIGF0dHIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaW5BKGF0dHIsIF92aWV3cG9ydEF0dHJzRnJvbVRhcmdldCkgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRhcmdldEF0dHIgPSBfdGFyZ2V0RWxlbWVudC5hdHRyKGF0dHIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUodGFyZ2V0QXR0cikgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihhdHRyLCB0YXJnZXRBdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucmVtb3ZlQXR0cihhdHRyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVXBkYXRlcyB0aGUgdmFyaWFibGVzIGFuZCBzaXplIG9mIHRoZSB0ZXh0YXJlYSBlbGVtZW50LCBhbmQgbWFuYWdlcyB0aGUgc2Nyb2xsIG9uIG5ldyBsaW5lIG9yIG5ldyBjaGFyYWN0ZXIuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhVXBkYXRlKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX3NsZWVwaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3cmFwQXR0ck9mZiA9ICFfdGV4dGFyZWFBdXRvV3JhcHBpbmdDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1pbldpZHRoID0gX3ZpZXdwb3J0U2l6ZS53O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWluSGVpZ2h0ID0gX3ZpZXdwb3J0U2l6ZS5oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3NzID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkb01lYXN1cmUgPSBfd2lkdGhBdXRvQ2FjaGUgfHwgd3JhcEF0dHJPZmY7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc2V0IG1pbiBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyTWluTWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB3aWR0aCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3N0ckF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdXaWR0aCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IGRvTWVhc3VyZSA/IE1BVEgubWF4KG9yaWdXaWR0aCwgX3RhcmdldEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10gLSAxKSA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8qd2lkdGggKz0gKF93aWR0aEF1dG9DYWNoZSA/IF9tYXJnaW5YICsgKCFfaXNCb3JkZXJCb3ggPyB3cmFwQXR0ck9mZiA/IDAgOiBfcGFkZGluZ1ggKyBfYm9yZGVyWCA6IDApIDogMCk7Ki9cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IG1lYXN1cmVkIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RyV2lkdGhdID0gX3dpZHRoQXV0b0NhY2hlID8gX3N0ckF1dG8gLyp3aWR0aCovIDogX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vc2V0IGhlaWdodCBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNzc1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ0hlaWdodCA9IF90YXJnZXRFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQgPSBNQVRILm1heChvcmlnSGVpZ2h0LCBfdGFyZ2V0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNIXSAtIDEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBlbmQgY29ycmVjdCBzaXplIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0cldpZHRoXSA9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ckhlaWdodF0gPSBoZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUNvdmVyRWxlbWVudC5jc3MoY3NzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgbWluIHdpZHRoIC8gbWluIGhlaWdodCB0byBwcmV2ZW50IHRleHRhcmVhIGNvbGxhcHNpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgY3NzW19zdHJNaW5NaW51cyArIF9zdHJXaWR0aF0gPSBtaW5XaWR0aCAvKisgKCFfaXNCb3JkZXJCb3ggJiYgX3dpZHRoQXV0b0NhY2hlID8gX3BhZGRpbmdYICsgX2JvcmRlclggOiAwKSovO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NbX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodF0gPSBtaW5IZWlnaHQgLyorICghX2lzQm9yZGVyQm94ICYmIF9oZWlnaHRBdXRvQ2FjaGUgPyBfcGFkZGluZ1kgKyBfYm9yZGVyWSA6IDApKi87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyhjc3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9vcmlnaW5hbFdpZHRoOiBvcmlnV2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfb3JpZ2luYWxIZWlnaHQ6IG9yaWdIZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZHluYW1pY1dpZHRoOiB3aWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9keW5hbWljSGVpZ2h0OiBoZWlnaHRcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdXBkYXRlSGludHMgQSBvYmplY3RzIHdoaWNoIGNvbnRhaW5zIGhpbnRzIGZvciB0aGlzIHVwZGF0ZTpcclxuICAgICAgICAgICAgICAgICAqIHtcclxuICAgICAgICAgICAgICAgICAqICAgX2hvc3RTaXplQ2hhbmdlZCA6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIF9jb250ZW50U2l6ZUNoYW5nZWQgOiBib29sZWFuLFxyXG4gICAgICAgICAgICAgICAgICogICBfZm9yY2UgOiBib29sZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT0gcHJldmVudFN3YWxsb3dpbmdcclxuICAgICAgICAgICAgICAgICAqICAgX2NoYW5nZWRPcHRpb25zIDogeyB9LCAgICAgICAgICAgICAgICAgICAgICAgID09IHByZXZlbnRTd2FsbG93aW5nICYmIHByZXZlbnRTbGVlcFxyXG4gICAgICAgICAgICAgICAgKiAgfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiB1cGRhdGUodXBkYXRlSGludHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3N3YWxsb3dlZFVwZGF0ZVRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUhpbnRzID0gdXBkYXRlSGludHMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzLl9ob3N0U2l6ZUNoYW5nZWQgfD0gdXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZCB8PSB1cGRhdGVIaW50cy5fY29udGVudFNpemVDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2UgfD0gdXBkYXRlSGludHMuX2ZvcmNlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgbm93ID0gQ09NUEFUSUJJTElUWS5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2hvc3RTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemVDaGFuZ2VkID0gISFfc3dhbGxvd2VkVXBkYXRlSGludHMuX2NvbnRlbnRTaXplQ2hhbmdlZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZm9yY2UgPSAhIV9zd2FsbG93ZWRVcGRhdGVIaW50cy5fZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNoYW5nZWRPcHRpb25zID0gdXBkYXRlSGludHMuX2NoYW5nZWRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzd2FsbG93ID0gX3N3YWxsb3dVcGRhdGVMYWcgPiAwICYmIF9pbml0aWFsaXplZCAmJiAhX2Rlc3Ryb3llZCAmJiAhZm9yY2UgJiYgIWNoYW5nZWRPcHRpb25zICYmIChub3cgLSBfbGFzdFVwZGF0ZVRpbWUpIDwgX3N3YWxsb3dVcGRhdGVMYWcgJiYgKCFfaGVpZ2h0QXV0b0NhY2hlICYmICFfd2lkdGhBdXRvQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkaXNwbGF5SXNIaWRkZW47XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzd2FsbG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3dhbGxvd2VkVXBkYXRlVGltZW91dCA9IHNldFRpbWVvdXQodXBkYXRlLCBfc3dhbGxvd1VwZGF0ZUxhZyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWJvcnQgdXBkYXRlIGR1ZSB0bzpcclxuICAgICAgICAgICAgICAgICAgICAvL2Rlc3Ryb3llZFxyXG4gICAgICAgICAgICAgICAgICAgIC8vc3dhbGxvd2luZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vc2xlZXBpbmdcclxuICAgICAgICAgICAgICAgICAgICAvL2hvc3QgaXMgaGlkZGVuIG9yIGhhcyBmYWxzZSBkaXNwbGF5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQgfHwgc3dhbGxvdyB8fCAoX3NsZWVwaW5nICYmICFjaGFuZ2VkT3B0aW9ucykgfHwgKF9pbml0aWFsaXplZCAmJiAhZm9yY2UgJiYgKGRpc3BsYXlJc0hpZGRlbiA9IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpKSkgfHwgX2hvc3RFbGVtZW50LmNzcygnZGlzcGxheScpID09PSAnaW5saW5lJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfbGFzdFVwZGF0ZVRpbWUgPSBub3c7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N3YWxsb3dlZFVwZGF0ZUhpbnRzID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vaWYgc2Nyb2xsYmFyIHN0eWxpbmcgaXMgcG9zc2libGUgYW5kIG5hdGl2ZSBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZCB0aGUgc2Nyb2xsYmFyIHN0eWxpbmcgd2lsbCBiZSBhcHBsaWVkIHdoaWNoIGhpZGVzIHRoZSBuYXRpdmUgc2Nyb2xsYmFycyBjb21wbGV0ZWx5LlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZyAmJiAhKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9uYXRpdmUgc2Nyb2xsYmFycyBhcmUgaGlkZGVuLCBzbyBjaGFuZ2UgdGhlIHZhbHVlcyB0byB6ZXJvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJTaXplLnggPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBuYXRpdmUgc2Nyb2xsYmFyIHNpemUgKGluIGNhc2Ugb2Ygem9vbSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2Nyb2xsYmFyIHBhZGRpbmcgaXMgbmVlZGVkIGZvciBmaXJlZm94LCBiZWNhdXNlIGZpcmVmb3ggaGlkZXMgc2Nyb2xsYmFyIGF1dG9tYXRpY2FsbHkgaWYgdGhlIHNpemUgb2YgdGhlIGRpdiBpcyB0b28gc21hbGwuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhbGN1bGF0aW9uOiBbc2Nyb2xsYmFyIHNpemUgKzMgKjNdXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCszIGJlY2F1c2Ugb2YgcG9zc2libGUgZGVjb3JhdGlvbiBlLmcuIGJvcmRlcnMsIG1hcmdpbnMgZXRjLiwgYnV0IG9ubHkgaWYgbmF0aXZlIHNjcm9sbGJhciBpcyBOT1QgYSBvdmVybGFpZCBzY3JvbGxiYXIpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKCozIGJlY2F1c2UgKDEpaW5jcmVhc2UgLyAoMilkZWNyZWFzZSAtYnV0dG9uIGFuZCAoMylyZXNpemUgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiAoX25hdGl2ZVNjcm9sbGJhclNpemUueCArIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ID8gMCA6IDMpKSAqIDMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHk6IChfbmF0aXZlU2Nyb2xsYmFyU2l6ZS55ICsgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyAwIDogMykpICogM1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHRpb25zID0gY2hhbmdlZE9wdGlvbnMgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tDYWNoZUF1dG9Gb3JjZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoZWNrQ2FjaGUuYXBwbHkodGhpcywgW10uc2xpY2UuY2FsbChhcmd1bWVudHMpLmNvbmNhdChbZm9yY2VdKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zYXZlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB4OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxUb3BdKClcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy50ZXh0YXJlYTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIHZpc2liaWxpdHk6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNWaXNpYmlsaXR5ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMudmlzaWJpbGl0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzVmlzaWJpbGl0eSwgX3Njcm9sbGJhcnNWaXNpYmlsaXR5Q2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGU6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNBdXRvSGlkZSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzQXV0b0hpZGVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzQXV0b0hpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2Nyb2xsYmFycyBjbGljayBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuY2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZywgX3Njcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIGRyYWcgc2Nyb2xsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1Njcm9sbGJhcnMuZHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZywgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGFzc05hbWUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsYXNzTmFtZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGNsYXNzTmFtZSwgX2NsYXNzTmFtZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZXNpemVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzaXplID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMucmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShyZXNpemUsIF9yZXNpemVDYWNoZSkgJiYgIV9pc0JvZHk7IC8vYm9keSBjYW4ndCBiZSByZXNpemVkIHNpbmNlIHRoZSB3aW5kb3cgaXRzZWxmIGFjdHMgYXMgcmVzaXplIHBvc3NpYmlsaXR5LlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3BhZGRpbmdBYnNvbHV0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nQWJzb2x1dGUgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5wYWRkaW5nQWJzb2x1dGU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHBhZGRpbmdBYnNvbHV0ZSwgX3BhZGRpbmdBYnNvbHV0ZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9jbGlwQWx3YXlzXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsaXBBbHdheXMgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy5jbGlwQWx3YXlzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjbGlwQWx3YXlzQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY2xpcEFsd2F5cywgX2NsaXBBbHdheXNDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2l6ZUF1dG9DYXBhYmxlXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZSA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnNpemVBdXRvQ2FwYWJsZSAmJiAhX2lzQm9keTsgLy9ib2R5IGNhbiBuZXZlciBiZSBzaXplIGF1dG8sIGJlY2F1c2UgaXQgc2hhbGwgYmUgYWx3YXlzIGFzIGJpZyBhcyB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvQ2FwYWJsZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHNpemVBdXRvQ2FwYWJsZSwgX3NpemVBdXRvQ2FwYWJsZUNhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zaG93TmF0aXZlU2Nyb2xsYmFyc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLnNob3dOYXRpdmVTY3JvbGxiYXJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZywgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYXV0b1VwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhdXRvVXBkYXRlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuYXV0b1VwZGF0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1VwZGF0ZUNoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGF1dG9VcGRhdGUsIF9hdXRvVXBkYXRlQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL292ZXJmbG93QmVoYXZpb3JcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvciA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLm92ZXJmbG93QmVoYXZpb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShvdmVyZmxvd0JlaGF2aW9yLCBfb3ZlcmZsb3dCZWhhdmlvckNhY2hlLCBmb3JjZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZHluV2lkdGg6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGggPSBjdXJyZW50UHJlcGFyZWRPcHRpb25zVGV4dGFyZWEuZHluV2lkdGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluV2lkdGhDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5XaWR0aENhY2hlLCB0ZXh0YXJlYUR5bldpZHRoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9keW5IZWlnaHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluSGVpZ2h0ID0gY3VycmVudFByZXBhcmVkT3B0aW9uc1RleHRhcmVhLmR5bkhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShfdGV4dGFyZWFEeW5IZWlnaHRDYWNoZSwgdGV4dGFyZWFEeW5IZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgdmlzaWJpbGl0eVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVOZXZlciA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ24nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVTY3JvbGwgPSBzY3JvbGxiYXJzQXV0b0hpZGUgPT09ICdzJztcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ20nO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSA9IHNjcm9sbGJhcnNBdXRvSGlkZSA9PT0gJ2wnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3Njcm9sbGJhcnMgYXV0b0hpZGVEZWxheVxyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSA9IGN1cnJlbnRQcmVwYXJlZE9wdGlvbnNTY3JvbGxiYXJzLmF1dG9IaWRlRGVsYXk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb2xkIGNsYXNzTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgIF9vbGRDbGFzc05hbWUgPSBfY2xhc3NOYW1lQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZU5vbmUgPSByZXNpemUgPT09ICduJztcclxuICAgICAgICAgICAgICAgICAgICBfcmVzaXplQm90aCA9IHJlc2l6ZSA9PT0gJ2InO1xyXG4gICAgICAgICAgICAgICAgICAgIF9yZXNpemVIb3Jpem9udGFsID0gcmVzaXplID09PSAnaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZVZlcnRpY2FsID0gcmVzaXplID09PSAndic7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vbm9ybWFsaXplUlRMXHJcbiAgICAgICAgICAgICAgICAgICAgX25vcm1hbGl6ZVJUTENhY2hlID0gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubm9ybWFsaXplUlRMO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lnbm9yZSBvdmVybGF5IHNjcm9sbGJhciBoaWRpbmdcclxuICAgICAgICAgICAgICAgICAgICBpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID0gaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyAmJiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueCAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZWZyZXNoIG9wdGlvbnMgY2FjaGVcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc1Zpc2liaWxpdHlDYWNoZSA9IHNjcm9sbGJhcnNWaXNpYmlsaXR5O1xyXG4gICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVDYWNoZSA9IHNjcm9sbGJhcnNBdXRvSGlkZTtcclxuICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzQ2xpY2tTY3JvbGxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgPSBzY3JvbGxiYXJzRHJhZ1Njcm9sbGluZztcclxuICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lQ2FjaGUgPSBjbGFzc05hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc2l6ZUNhY2hlID0gcmVzaXplO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nQWJzb2x1dGVDYWNoZSA9IHBhZGRpbmdBYnNvbHV0ZTtcclxuICAgICAgICAgICAgICAgICAgICBfY2xpcEFsd2F5c0NhY2hlID0gY2xpcEFsd2F5cztcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9DYXBhYmxlQ2FjaGUgPSBzaXplQXV0b0NhcGFibGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDYWNoZSA9IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2F1dG9VcGRhdGVDYWNoZSA9IGF1dG9VcGRhdGU7XHJcbiAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QmVoYXZpb3JDYWNoZSA9IGV4dGVuZERlZXAoe30sIG92ZXJmbG93QmVoYXZpb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bldpZHRoQ2FjaGUgPSB0ZXh0YXJlYUR5bldpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUR5bkhlaWdodENhY2hlID0gdGV4dGFyZWFEeW5IZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBfaGFzT3ZlcmZsb3dDYWNoZSB8fCB7IHg6IGZhbHNlLCB5OiBmYWxzZSB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBjb3JyZWN0IGNsYXNzIG5hbWUgdG8gdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGFzc05hbWVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX29sZENsYXNzTmFtZSArIF9zdHJTcGFjZSArIF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIGNsYXNzTmFtZSAhPT0gdW5kZWZpbmVkICYmIGNsYXNzTmFtZSAhPT0gbnVsbCAmJiBjbGFzc05hbWUubGVuZ3RoID4gMCA/IGNsYXNzTmFtZSA6IF9jbGFzc05hbWVUaGVtZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgY29ycmVjdCBhdXRvIFVwZGF0ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChhdXRvVXBkYXRlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXV0b1VwZGF0ZSA9PT0gdHJ1ZSB8fCAoYXV0b1VwZGF0ZSA9PT0gbnVsbCAmJiBfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5hZGQoX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b1VwZGF0ZUxvb3AucmVtb3ZlKF9iYXNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FjdGl2YXRlIG9yIGRlYWN0aXZhdGUgc2l6ZSBhdXRvIGNhcGFiaWxpdHlcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbnRlbnRHbHVlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEdsdWVFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmJlZm9yZShfY29udGVudEdsdWVFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LnNob3coKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lU2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuYmVmb3JlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9sZFNpemUgPSB7IHc6IC0xLCBoOiAtMSB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdTaXplID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGVja0NhY2hlKG5ld1NpemUsIG9sZFNpemUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIChfaGVpZ2h0QXV0b0NhY2hlICYmIG5ld1NpemUuaCA+IDApIHx8IChfd2lkdGhBdXRvQ2FjaGUgJiYgbmV3U2l6ZS53ID4gMCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9pbml0aWFsaXplZCAmJiAoIV9oZWlnaHRBdXRvQ2FjaGUgJiYgbmV3U2l6ZS5oID09PSAwKSB8fCAoIV93aWR0aEF1dG9DYWNoZSAmJiBuZXdTaXplLncgPT09IDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkU2l6ZSA9IG5ld1NpemU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0QXV0byBkZXRlY3RvciBidWcgaWYgaGVpZ2h0IGlzIGZpeGVkIGJ1dCBjb250ZW50SGVpZ2h0IGlzIDAuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGUgcHJvYmFiaWxpdHkgdGhpcyBidWcgd2lsbCBldmVyIGhhcHBlbiBpcyB2ZXJ5IHZlcnkgbG93LCB0aGF0cyB3aHkgaXRzIG9rIGlmIHdlIHVzZSBjYWxjIHdoaWNoIGlzbid0IHN1cHBvcnRlZCBpbiBJRTguXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9jc3NDYWxjICE9PSBudWxsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnQuY3NzKF9zdHJIZWlnaHQsIF9jc3NDYWxjICsgJygxMDAlICsgMXB4KScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIGZvcmNlLCB1cGRhdGUgYWxsIHJlc2l6ZU9ic2VydmVycyB0b29cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnQuZmluZCgnKicpLnRyaWdnZXIoX3N0clNjcm9sbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2l6ZUF1dG9PYnNlcnZlckFkZGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LmZpbmQoJyonKS50cmlnZ2VyKF9zdHJTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kaXNwbGF5IGhpZGRlbjpcclxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5SXNIaWRkZW4gPSBkaXNwbGF5SXNIaWRkZW4gPT09IHVuZGVmaW5lZCA/IF9ob3N0RWxlbWVudC5pcygnOmhpZGRlbicpIDogZGlzcGxheUlzSGlkZGVuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhIEF1dG9XcmFwcGluZzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmcgPSBfaXNUZXh0YXJlYSA/IF90YXJnZXRFbGVtZW50LmF0dHIoJ3dyYXAnKSAhPT0gJ29mZicgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFBdXRvV3JhcHBpbmdDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYUF1dG9XcmFwcGluZywgX3RleHRhcmVhQXV0b1dyYXBwaW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBkaXJlY3Rpb246XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNzc0RpcmVjdGlvbiA9IF9ob3N0RWxlbWVudC5jc3MoJ2RpcmVjdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjc3NEaXJlY3Rpb25DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjc3NEaXJlY3Rpb24sIF9jc3NEaXJlY3Rpb25DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJveC1zaXppbmc6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJveFNpemluZyA9IF9ob3N0RWxlbWVudC5jc3MoJ2JveC1zaXppbmcnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYm94U2l6aW5nQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm94U2l6aW5nLCBfY3NzQm94U2l6aW5nQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2RldGVjdCBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nID0gZ2V0VG9wUmlnaHRCb3R0b21MZWZ0SG9zdChfc3RyUGFkZGluZ01pbnVzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy93aWR0aCArIGhlaWdodCBhdXRvIGRldGVjdGluZyB2YXI6XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZXhjZXB0aW9uIG9jY3VycyBpbiBJRTggc29tZXRpbWVzICh1bmtub3duIGV4Y2VwdGlvbilcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzaXplQXV0b09ic2VydmVyRWxlbWVudEJDUmVjdCA9IF9zaXplQXV0b09ic2VydmVyQWRkZWQgPyBfc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCkgOiBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9pc1JUTCA9IGNzc0RpcmVjdGlvbiA9PT0gJ3J0bCc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9yZGVyQm94ID0gKGJveFNpemluZyA9PT0gJ2JvcmRlci1ib3gnKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExMZWZ0ID0gX2lzUlRMID8gX3N0ckxlZnQgOiBfc3RyUmlnaHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzUlRMUmlnaHQgPSBfaXNSVEwgPyBfc3RyUmlnaHQgOiBfc3RyTGVmdDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3Qgd2lkdGggYXV0bzpcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uID0gKF9zaXplQXV0b09ic2VydmVyQWRkZWQgJiYgKF9ob3N0RWxlbWVudC5jc3MoX3N0ckZsb2F0KSAhPT0gJ25vbmUnIC8qfHwgX2lzVGV4dGFyZWEgKi8pKSA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnJpZ2h0IC0gc2l6ZUF1dG9PYnNlcnZlckVsZW1lbnRCQ1JlY3QubGVmdCkgPT09IDApICYmICghcGFkZGluZ0Fic29sdXRlID8gKF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmNXXSAtIF9wYWRkaW5nWCkgPiAwIDogdHJ1ZSkgOiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZUF1dG9DYXBhYmxlICYmICF3aWR0aEF1dG9PYnNlcnZlckRldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wQ3Vyckhvc3RXaWR0aCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9XXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoID0gX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCBfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdG1wTmV3SG9zdFdpZHRoID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGhBdXRvUmVzaXplRGV0ZWN0aW9uID0gdG1wQ3Vyckhvc3RXaWR0aCAhPT0gdG1wTmV3SG9zdFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRHbHVlRWxlbWVudC5jc3MoX3N0cldpZHRoLCB0bXBDdXJySG9zdFdpZHRoICsgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBOZXdIb3N0V2lkdGggPSBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5vV107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEdsdWVFbGVtZW50LmNzcyhfc3RyV2lkdGgsIHRtcEN1cnJDb250ZW50R2x1ZVdpZHRoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbiA9IHRtcEN1cnJIb3N0V2lkdGggIT09IHRtcE5ld0hvc3RXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2lkdGhBdXRvID0gKHdpZHRoQXV0b09ic2VydmVyRGV0ZWN0aW9uIHx8IHdpZHRoQXV0b1Jlc2l6ZURldGVjdGlvbikgJiYgc2l6ZUF1dG9DYXBhYmxlICYmICFkaXNwbGF5SXNIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdpZHRoQXV0b0NoYW5nZWQgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKHdpZHRoQXV0bywgX3dpZHRoQXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzV2lkdGhBdXRvID0gIXdpZHRoQXV0byAmJiBfd2lkdGhBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGhlaWdodCBhdXRvOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWlnaHRBdXRvID0gX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZCAmJiBzaXplQXV0b0NhcGFibGUgJiYgIWRpc3BsYXlJc0hpZGRlbiA/IChNQVRILnJvdW5kKHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LmJvdHRvbSAtIHNpemVBdXRvT2JzZXJ2ZXJFbGVtZW50QkNSZWN0LnRvcCkgPT09IDApIC8qICYmICghcGFkZGluZ0Fic29sdXRlICYmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfbXNpZVZlcnNpb24pID8gdHJ1ZSA6IHRydWUpICovIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlaWdodEF1dG9DaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShoZWlnaHRBdXRvLCBfaGVpZ2h0QXV0b0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgd2FzSGVpZ2h0QXV0byA9ICFoZWlnaHRBdXRvICYmIF9oZWlnaHRBdXRvQ2FjaGU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZGV0ZWN0IGJvcmRlcjpcclxuICAgICAgICAgICAgICAgICAgICAvL3dlIG5lZWQgdGhlIGJvcmRlciBvbmx5IGlmIGJvcmRlciBib3ggYW5kIGF1dG8gc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVCb3JkZXJYID0gKHdpZHRoQXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVwZGF0ZUJvcmRlclkgPSAoaGVpZ2h0QXV0byAmJiBfaXNCb3JkZXJCb3gpIHx8ICFfaXNCb3JkZXJCb3g7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvcmRlciA9IGdldFRvcFJpZ2h0Qm90dG9tTGVmdEhvc3QoX3N0ckJvcmRlck1pbnVzLCAnLScgKyBfc3RyV2lkdGgsICF1cGRhdGVCb3JkZXJYLCAhdXBkYXRlQm9yZGVyWSlcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9kZXRlY3QgbWFyZ2luOlxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW4gPSBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KF9zdHJNYXJnaW5NaW51cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdmFycyB0byBhcHBseSBjb3JyZWN0IGNzc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZUVsZW1lbnRDU1MgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mdW5jc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRIb3N0U2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9oYXMgdG8gYmUgY2xpZW50U2l6ZSBiZWNhdXNlIG9mZnNldFNpemUgcmVzcGVjdCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBfaG9zdEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBnZXRWaWV3cG9ydFNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmlld3BvcnQgc2l6ZSBpcyBwYWRkaW5nIGNvbnRhaW5lciBiZWNhdXNlIGl0IG5ldmVyIGhhcyBwYWRkaW5nLCBtYXJnaW4gYW5kIGEgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vZGV0ZXJtaW5lIHpvb20gcm91bmRpbmcgZXJyb3IgLT4gc29tZXRpbWVzIHNjcm9sbFdpZHRoL0hlaWdodCBpcyBzbWFsbGVyIHRoYW4gY2xpZW50V2lkdGgvSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgdGhpcyBoYXBwZW5zIGFkZCB0aGUgZGlmZmVyZW5jZSB0byB0aGUgdmlld3BvcnRTaXplIHRvIGNvbXBlbnNhdGUgdGhlIHJvdW5kaW5nIGVycm9yXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10gKyBNQVRILm1heCgwLCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jV10gLSBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5zV10pLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogX3BhZGRpbmdFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdICsgTUFUSC5tYXgoMCwgX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uY0hdIC0gX2NvbnRlbnRFbGVtZW50TmF0aXZlW0xFWElDT04uc0hdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vc2V0IGluZm8gZm9yIHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWCA9IF9wYWRkaW5nWCA9IHBhZGRpbmcubCArIHBhZGRpbmcucjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0Fic29sdXRlWSA9IF9wYWRkaW5nWSA9IHBhZGRpbmcudCArIHBhZGRpbmcuYjtcclxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nQWJzb2x1dGVYICo9IHBhZGRpbmdBYnNvbHV0ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdBYnNvbHV0ZVkgKj0gcGFkZGluZ0Fic29sdXRlID8gMSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZy5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShwYWRkaW5nLCBfY3NzUGFkZGluZ0NhY2hlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9zZXQgaW5mbyBmb3IgYm9yZGVyXHJcbiAgICAgICAgICAgICAgICAgICAgX2JvcmRlclggPSBib3JkZXIubCArIGJvcmRlci5yO1xyXG4gICAgICAgICAgICAgICAgICAgIF9ib3JkZXJZID0gYm9yZGVyLnQgKyBib3JkZXIuYjtcclxuICAgICAgICAgICAgICAgICAgICBib3JkZXIuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYm9yZGVyLCBfY3NzQm9yZGVyQ2FjaGUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3NldCBpbmZvIGZvciBtYXJnaW5cclxuICAgICAgICAgICAgICAgICAgICBfbWFyZ2luWCA9IG1hcmdpbi5sICsgbWFyZ2luLnI7XHJcbiAgICAgICAgICAgICAgICAgICAgX21hcmdpblkgPSBtYXJnaW4udCArIG1hcmdpbi5iO1xyXG4gICAgICAgICAgICAgICAgICAgIG1hcmdpbi5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShtYXJnaW4sIF9jc3NNYXJnaW5DYWNoZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUF1dG9XcmFwcGluZ0NhY2hlID0gdGV4dGFyZWFBdXRvV3JhcHBpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0RpcmVjdGlvbkNhY2hlID0gY3NzRGlyZWN0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NCb3hTaXppbmdDYWNoZSA9IGJveFNpemluZztcclxuICAgICAgICAgICAgICAgICAgICBfd2lkdGhBdXRvQ2FjaGUgPSB3aWR0aEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2hlaWdodEF1dG9DYWNoZSA9IGhlaWdodEF1dG87XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc1BhZGRpbmdDYWNoZSA9IHBhZGRpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0JvcmRlckNhY2hlID0gYm9yZGVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jc3NNYXJnaW5DYWNoZSA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9JRUZpeCBkaXJlY3Rpb24gY2hhbmdlZFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkICYmIF9zaXplQXV0b09ic2VydmVyQWRkZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplQXV0b09ic2VydmVyRWxlbWVudC5jc3MoX3N0ckZsb2F0LCBpc1JUTFJpZ2h0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBwYWRkaW5nOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYWRkaW5nLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBzaXplQXV0b0NhcGFibGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDU1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhZGRpbmdWYWx1ZXMgPSBbcGFkZGluZy50LCBwYWRkaW5nLnIsIHBhZGRpbmcuYiwgcGFkZGluZy5sXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRvcFJpZ2h0Qm90dG9tTGVmdChjb250ZW50R2x1ZUVsZW1lbnRDU1MsIF9zdHJNYXJnaW5NaW51cywgWy1wYWRkaW5nLnQsIC1wYWRkaW5nLnIsIC1wYWRkaW5nLmIsIC1wYWRkaW5nLmxdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdBYnNvbHV0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KHBhZGRpbmdFbGVtZW50Q1NTLCBfc3RyRW1wdHksIHBhZGRpbmdWYWx1ZXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VG9wUmlnaHRCb3R0b21MZWZ0KF9pc1RleHRhcmVhID8gdGV4dGFyZWFDU1MgOiBjb250ZW50RWxlbWVudENTUywgX3N0clBhZGRpbmdNaW51cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQocGFkZGluZ0VsZW1lbnRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQoX2lzVGV4dGFyZWEgPyB0ZXh0YXJlYUNTUyA6IGNvbnRlbnRFbGVtZW50Q1NTLCBfc3RyUGFkZGluZ01pbnVzLCBwYWRkaW5nVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmNzcyhwYWRkaW5nRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmNzcyh0ZXh0YXJlYUNTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3ZpZXdwb3J0IHNpemUgaXMgcGFkZGluZyBjb250YWluZXIgYmVjYXVzZSBpdCBuZXZlciBoYXMgcGFkZGluZywgbWFyZ2luIGFuZCBhIGJvcmRlci5cclxuICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdXBkYXRlIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhU2l6ZSA9IF9pc1RleHRhcmVhID8gdGV4dGFyZWFVcGRhdGUoKSA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVNpemVDaGFuZ2VkID0gX2lzVGV4dGFyZWEgJiYgY2hlY2tDYWNoZUF1dG9Gb3JjZSh0ZXh0YXJlYVNpemUsIF90ZXh0YXJlYVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhRHluT3JpZ1NpemUgPSBfaXNUZXh0YXJlYSAmJiB0ZXh0YXJlYVNpemUgPyB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHc6IHRleHRhcmVhRHluV2lkdGggPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNXaWR0aCA6IHRleHRhcmVhU2l6ZS5fb3JpZ2luYWxXaWR0aCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5IZWlnaHQgPyB0ZXh0YXJlYVNpemUuX2R5bmFtaWNIZWlnaHQgOiB0ZXh0YXJlYVNpemUuX29yaWdpbmFsSGVpZ2h0XHJcbiAgICAgICAgICAgICAgICAgICAgfSA6IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYVNpemVDYWNoZSA9IHRleHRhcmVhU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9maXggaGVpZ2h0IGF1dG8gLyB3aWR0aCBhdXRvIGluIGNvb3BlcmF0aW9uIHdpdGggY3VycmVudCBwYWRkaW5nICYgYm94U2l6aW5nIGJlaGF2aW9yOlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoZWlnaHRBdXRvICYmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZy5jIHx8IGJvcmRlci5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChoZWlnaHRBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gX3N0ckh1bmRyZWRQZXJjZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvICYmICh3aWR0aEF1dG9DaGFuZ2VkIHx8IHBhZGRpbmdBYnNvbHV0ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nLmMgfHwgYm9yZGVyLmMgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0cldpZHRoXSA9IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ck1heE1pbnVzICsgX3N0cldpZHRoXSA9IF9zdHJIdW5kcmVkUGVyY2VudDsgLy9JRSBGaXhcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAod2lkdGhBdXRvQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJGbG9hdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyTWF4TWludXMgKyBfc3RyV2lkdGhdID0gX3N0ckVtcHR5OyAvL0lFIEZpeFxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWFEeW5PcmlnU2l6ZS53IHx8IF9zdHJBdXRvIDo6IGRvZXNudCB3b3JrcyBiZWNhdXNlIGFwcGxpZWQgbWFyZ2luIHdpbGwgc2hpZnQgd2lkdGhcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RyQXV0bztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eVZhbHVlKF9zdHJXaWR0aCwgJ21heC1jb250ZW50IGludHJpbnNpYycpIHx8IF9zdHJBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyRmxvYXRdID0gaXNSVExSaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3RleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF0gOjogdXNlIGZvciBhbnRpIHNjcm9sbCBqdW1waW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RySGVpZ2h0XSA9IHRleHRhcmVhRHluT3JpZ1NpemUuaCB8fCBfY29udGVudEVsZW1lbnROYXRpdmVbTEVYSUNPTi5jSF07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vQ0hFQ0tQT0lOVCBIRVJFIH5cclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2lmIFtjb250ZW50KGhvc3QpIGNsaWVudCAvIHNjcm9sbCBzaXplLCBvciB0YXJnZXQgZWxlbWVudCBkaXJlY3Rpb24sIG9yIGNvbnRlbnQoaG9zdCkgbWF4LXNpemVzXSBjaGFuZ2VkLCBvciBmb3JjZSBpcyB0cnVlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhvc3RTaXplQ2hhbmdlZCB8fCBjb250ZW50U2l6ZUNoYW5nZWQgfHwgdGV4dGFyZWFTaXplQ2hhbmdlZCB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgcGFkZGluZ0Fic29sdXRlQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHdpZHRoQXV0byB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGNsaXBBbHdheXNDaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgc2Nyb2xsYmFyc0RyYWdTY3JvbGxpbmdDaGFuZ2VkIHx8IHNjcm9sbGJhcnNDbGlja1Njcm9sbGluZ0NoYW5nZWQgfHwgdGV4dGFyZWFEeW5XaWR0aENoYW5nZWQgfHwgdGV4dGFyZWFEeW5IZWlnaHRDaGFuZ2VkIHx8IHRleHRhcmVhQXV0b1dyYXBwaW5nQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3cgPSAnb3ZlcmZsb3cnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dYID0gc3RyT3ZlcmZsb3cgKyAnLXgnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3ZlcmZsb3dZID0gc3RyT3ZlcmZsb3cgKyAnLXknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RySGlkZGVuID0gJ2hpZGRlbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJWaXNpYmxlID0gJ3Zpc2libGUnO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9SZXNldCB0aGUgdmlld3BvcnQgKHZlcnkgaW1wb3J0YW50IGZvciBuYXRpdmVseSBvdmVybGFpZCBzY3JvbGxiYXJzIGFuZCB6b29tIGNoYW5nZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2Rvbid0IGNoYW5nZSB0aGUgb3ZlcmZsb3cgcHJvcCBhcyBpdCBpcyB2ZXJ5IGV4cGVuc2l2ZSBhbmQgYWZmZWN0cyBwZXJmb3JtYW5jZSAhQSBMT1QhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydEVsZW1lbnRSZXNldENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc2V0WFRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnkgJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnlzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgPyBfdmlld3BvcnRFbGVtZW50LmNzcyhpc1JUTExlZnQpIDogLV9uYXRpdmVTY3JvbGxiYXJTaXplLnkpIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldEJvdHRvbVRtcCA9IF9oYXNPdmVyZmxvd0NhY2hlLnggJiYgX2hpZGVPdmVyZmxvd0NhY2hlLnhzICYmICFpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nID8gKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggPyBfdmlld3BvcnRFbGVtZW50LmNzcyhfc3RyQm90dG9tKSA6IC1fbmF0aXZlU2Nyb2xsYmFyU2l6ZS54KSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUb3BSaWdodEJvdHRvbUxlZnQodmlld3BvcnRFbGVtZW50UmVzZXRDU1MsIF9zdHJFbXB0eSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LmNzcyh2aWV3cG9ydEVsZW1lbnRSZXNldENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyZSBzZXZlcmFsIHNpemVzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudE1lYXN1cmVFbGVtZW50ID0gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaW4gRmlyZWZveCBjb250ZW50IGVsZW1lbnQgaGFzIHRvIGhhdmUgb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIGVsZW1lbnQgbWFyZ2lucyBhcmVuJ3QgY2FsY3VsYXRlZCBwcm9wZXJseSwgdGhpcyBlbGVtZW50IHByZXZlbnRzIHRoaXMgYnVnLCBidXQgb25seSBpZiBzY3JvbGxiYXJzIGFyZW4ndCBvdmVybGFpZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiB0ZXh0YXJlYUR5bk9yaWdTaXplLncgfHwgY29udGVudE1lYXN1cmVFbGVtZW50W0xFWElDT04uY1ddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogdGV4dGFyZWFEeW5PcmlnU2l6ZS5oIHx8IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLmNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSB0aGUgY29ycmVjdCB2aWV3cG9ydCBzdHlsZSBhbmQgbWVhc3VyZSB2aWV3cG9ydCBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTW19zdHJCb3R0b21dID0gd2FzSGVpZ2h0QXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0Qm90dG9tVG1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50UmVzZXRDU1NbaXNSVExMZWZ0XSA9IHdhc1dpZHRoQXV0byA/IF9zdHJFbXB0eSA6IHJlc2V0WFRtcDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuY3NzKHZpZXdwb3J0RWxlbWVudFJlc2V0Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRTaXplID0gZ2V0Vmlld3BvcnRTaXplKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYW5kIGNvcnJlY3Qgc2V2ZXJhbCBzaXplc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdFNpemUgPSBnZXRIb3N0U2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaG9zdEFic29sdXRlUmVjdFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBob3N0U2l6ZS53IC0gX21hcmdpblggLSBfYm9yZGVyWCAtIChfaXNCb3JkZXJCb3ggPyAwIDogX3BhZGRpbmdYKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGhvc3RTaXplLmggLSBfbWFyZ2luWSAtIF9ib3JkZXJZIC0gKF9pc0JvcmRlckJveCA/IDAgOiBfcGFkZGluZ1kpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50R2x1ZVNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsaWVudC9zY3JvbGxTaXplICsgQWJzb2x1dGVQYWRkaW5nIC0+IGJlY2F1c2UgcGFkZGluZyBpcyBvbmx5IGFwcGxpZWQgdG8gdGhlIHBhZGRpbmdFbGVtZW50IGlmIGl0cyBhYnNvbHV0ZSwgc28geW91IGhhdmUgdG8gYWRkIGl0IG1hbnVhbGx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2hvc3RTaXplIGlzIGNsaWVudFNpemUgLT4gc28gcGFkZGluZyBzaG91bGQgYmUgYWRkZWQgbWFudWFsbHksIHJpZ2h0PyBGQUxTRSEgQmVjYXVzZSBjb250ZW50IGdsdWUgaXMgaW5zaWRlIGhvc3RFbGVtZW50LCBzbyB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0IHBhZGRpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IE1BVEgubWF4KCh3aWR0aEF1dG8gPyBjb250ZW50U2l6ZS53IDogc2Nyb2xsU2l6ZS53KSArIHBhZGRpbmdBYnNvbHV0ZVgsIGhvc3RBYnNvbHV0ZVJlY3RTaXplLncpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaDogTUFUSC5tYXgoKGhlaWdodEF1dG8gPyBjb250ZW50U2l6ZS5oIDogc2Nyb2xsU2l6ZS5oKSArIHBhZGRpbmdBYnNvbHV0ZVksIGhvc3RBYnNvbHV0ZVJlY3RTaXplLmgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlU2l6ZS5jID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShjb250ZW50R2x1ZVNpemUsIF9jb250ZW50R2x1ZVNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZVNpemVDYWNoZSA9IGNvbnRlbnRHbHVlU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgY29ycmVjdCBjb250ZW50R2x1ZSBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vc2l6ZSBjb250ZW50R2x1ZSBjb3JyZWN0bHkgdG8gbWFrZSBzdXJlIHRoZSBlbGVtZW50IGhhcyBjb3JyZWN0IHNpemUgaWYgdGhlIHNpemluZyBzd2l0Y2hlcyB0byBhdXRvXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudEdsdWVTaXplLmMgfHwgKGhlaWdodEF1dG8gfHwgd2lkdGhBdXRvKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tfc3RyV2lkdGhdID0gY29udGVudEdsdWVTaXplLnc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEdsdWVFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gY29udGVudEdsdWVTaXplLmg7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGV4dGFyZWEtc2l6ZXMgYXJlIGFscmVhZHkgY2FsY3VsYXRlZCBjb3JyZWN0bHkgYXQgdGhpcyBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemUgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3VzZSBjbGllbnRTaXplIGJlY2F1c2UgbmF0aXZlbHkgb3ZlcmxhaWRTY3JvbGxiYXJzIGFkZCBib3JkZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3OiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jV10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoOiBjb250ZW50TWVhc3VyZUVsZW1lbnRbTEVYSUNPTi5jSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFDb3ZlckNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFycyA9IGdldFNjcm9sbGJhclZhcnMoaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHdoID0gc2Nyb2xsYmFyVmFycy5fd19oO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJXSCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXV0b1NpemUgPSBob3Jpem9udGFsID8gd2lkdGhBdXRvIDogaGVpZ2h0QXV0bztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYm9yZGVyU2l6ZSA9IGhvcml6b250YWwgPyBfYm9yZGVyWCA6IF9ib3JkZXJZO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nU2l6ZSA9IGhvcml6b250YWwgPyBfcGFkZGluZ1ggOiBfcGFkZGluZ1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblNpemUgPSBob3Jpem9udGFsID8gX21hcmdpblggOiBfbWFyZ2luWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF0gLSBib3JkZXJTaXplIC0gbWFyZ2luU2l6ZSAtIChfaXNCb3JkZXJCb3ggPyAwIDogcGFkZGluZ1NpemUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2UgY29udGVudEdsdWUgc2l6ZSAtMSBpZiBlbGVtZW50IGlzIG5vdCBhdXRvIHNpemVkLCB0byBtYWtlIHN1cmUgdGhhdCBhIHJlc2l6ZSBldmVudCBoYXBwZW5zIHdoZW4gdGhlIGVsZW1lbnQgc2hyaW5rc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghYXV0b1NpemUgfHwgKCFhdXRvU2l6ZSAmJiBib3JkZXIuYykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBob3N0QWJzb2x1dGVSZWN0U2l6ZVt3aF0gLSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIHNpemUgaXMgYXV0byBhbmQgaG9zdCBpcyBzbWFsbGVyIHRoYW4gc2l6ZSBhcyBtaW4gc2l6ZSwgbWFrZSBjb250ZW50IGdsdWUgc2l6ZSAtMSB0byBtYWtlIHN1cmUgc2l6ZSBjaGFuZ2VzIHdpbGwgYmUgZGV0ZWN0ZWQgKHRoaXMgaXMgb25seSBuZWVkZWQgaWYgcGFkZGluZyBpcyAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdXRvU2l6ZSAmJiAoY29udGVudFNpemVbd2hdIDwgdmlld3BvcnRTaXplKSAmJiAoaG9yaXpvbnRhbCAmJiBfaXNUZXh0YXJlYSA/ICF0ZXh0YXJlYUF1dG9XcmFwcGluZyA6IHRydWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhQ292ZXJDU1Nbc3RyV0hdID0gcGFyc2VUb1plcm9Pck51bWJlcihfdGV4dGFyZWFDb3ZlckVsZW1lbnQuY3NzKHN0cldIKSkgLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdIC09IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21ha2Ugc3VyZSBjb250ZW50IGdsdWUgc2l6ZSBpcyBhdCBsZWFzdCAxXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRTaXplW3doXSA+IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRHbHVlRWxlbWVudENTU1tzdHJXSF0gPSBNQVRILm1heCgxLCBjb250ZW50R2x1ZUVsZW1lbnRDU1Nbc3RyV0hdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50R2x1ZUVsZW1lbnRDU1NmdW5jdGlvbih0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRHbHVlRWxlbWVudENTU2Z1bmN0aW9uKGZhbHNlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzVGV4dGFyZWEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50LmNzcyh0ZXh0YXJlYUNvdmVyQ1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50R2x1ZUVsZW1lbnQuY3NzKGNvbnRlbnRHbHVlRWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoQXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBfc3RySHVuZHJlZFBlcmNlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8gJiYgIV9pc0JvcmRlckJveCAmJiAhX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckZsb2F0XSA9ICdub25lJztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXBwbHkgYW5kIHJlc2V0IGNvbnRlbnQgc3R5bGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgYWdhaW4sIGJ1dCB0aGlzIHRpbWUgYWxsIGNvcnJlY3Qgc2l6ZXM6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2Nyb2xsU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHc6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNXXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IGNvbnRlbnRNZWFzdXJlRWxlbWVudFtMRVhJQ09OLnNIXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNjcm9sbFNpemUuYyA9IGNvbnRlbnRTaXplQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoY29udGVudFNjcm9sbFNpemUsIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUgPSBjb250ZW50U2Nyb2xsU2l6ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVmcmVzaCB2aWV3cG9ydCBzaXplIGFmdGVyIGNvcnJlY3QgbWVhc3VyaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydFNpemUgPSBnZXRWaWV3cG9ydFNpemUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RTaXplID0gZ2V0SG9zdFNpemUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemVDaGFuZ2VkID0gY2hlY2tDYWNoZUF1dG9Gb3JjZShob3N0U2l6ZSwgX2hvc3RTaXplQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfaG9zdFNpemVDYWNoZSA9IGhvc3RTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEgPSBfaXNUZXh0YXJlYSAmJiAoX3ZpZXdwb3J0U2l6ZS53ID09PSAwIHx8IF92aWV3cG9ydFNpemUuaCA9PT0gMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwcmV2aW91c092ZXJmbG93QW1vdW50ID0gX292ZXJmbG93QW1vdW50Q2FjaGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvdmVyZmxvd0JlaGF2aW9ySXNWUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3ZlcmZsb3dCZWhhdmlvcklzVkggPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QmVoYXZpb3JJc1MgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG92ZXJmbG93QW1vdW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNPdmVyZmxvdyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGlkZU92ZXJmbG93ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYW5TY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZpZXdwb3J0UmVjdCA9IF9wYWRkaW5nRWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNldE92ZXJmbG93VmFyaWFibGVzID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQgPSBnZXRTY3JvbGxiYXJWYXJzKCFob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eUkgPSBzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aCA9IHNjcm9sbGJhclZhcnMuX3dfaDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aEhlaWdodCA9IHNjcm9sbGJhclZhcnMuX3dpZHRoX2hlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxNYXggPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3AgKyAnTWF4JztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSB2aWV3cG9ydFJlY3Rbd2lkdGhIZWlnaHRdID8gTUFUSC5hYnModmlld3BvcnRSZWN0W3dpZHRoSGVpZ2h0XSAtIF92aWV3cG9ydFNpemVbd2hdKSA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPSBwcmV2aW91c092ZXJmbG93QW1vdW50ICYmIHByZXZpb3VzT3ZlcmZsb3dBbW91bnRbeHldID4gMCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlW3Njcm9sbE1heF0gPT09IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3Ytcyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPSBvdmVyZmxvd0JlaGF2aW9yW3h5XSA9PT0gJ3YtaCc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSA9IG92ZXJmbG93QmVoYXZpb3JbeHldID09PSAncyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVyZmxvd0Ftb3VudFt4eV0gPSBNQVRILm1heCgwLCBNQVRILnJvdW5kKChjb250ZW50U2Nyb2xsU2l6ZVt3aF0gLSBfdmlld3BvcnRTaXplW3doXSkgKiAxMDApIC8gMTAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93QW1vdW50W3h5XSAqPSAoaGlkZU92ZXJmbG93Rm9yY2VUZXh0YXJlYSB8fCAoY2hlY2tGcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgJiYgZnJhY3Rpb25hbE92ZXJmbG93QW1vdW50ID4gMCAmJiBmcmFjdGlvbmFsT3ZlcmZsb3dBbW91bnQgPCAxKSkgPyAwIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc092ZXJmbG93W3h5XSA9IG92ZXJmbG93QW1vdW50W3h5XSA+IDA7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9oaWRlT3ZlcmZsb3c6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ggfHwgeSA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIiBPUiBcIm92ZXJmbG93OiBoaWRkZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy94cyB8fCB5cyA6IHRydWUgPT09IG92ZXJmbG93IGlzIGhpZGRlbiBieSBcIm92ZXJmbG93OiBzY3JvbGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93W3h5XSA9IG92ZXJmbG93QmVoYXZpb3JJc1ZTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSFt4eV0gPyAoaGFzT3ZlcmZsb3dbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVlNbeHlJXSAmJiAhb3ZlcmZsb3dCZWhhdmlvcklzVkhbeHlJXSkgOiBoYXNPdmVyZmxvd1t4eV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3dbeHkgKyAncyddID0gaGlkZU92ZXJmbG93W3h5XSA/IChvdmVyZmxvd0JlaGF2aW9ySXNTW3h5XSB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWU1t4eV0pIDogZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuU2Nyb2xsW3h5XSA9IGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRPdmVyZmxvd1ZhcmlhYmxlcyh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0T3ZlcmZsb3dWYXJpYWJsZXMoZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2Uob3ZlcmZsb3dBbW91bnQsIF9vdmVyZmxvd0Ftb3VudENhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX292ZXJmbG93QW1vdW50Q2FjaGUgPSBvdmVyZmxvd0Ftb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3cuYyA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoaGFzT3ZlcmZsb3csIF9oYXNPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhc092ZXJmbG93Q2FjaGUgPSBoYXNPdmVyZmxvdztcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGlkZU92ZXJmbG93LmMgPSBjaGVja0NhY2hlQXV0b0ZvcmNlKGhpZGVPdmVyZmxvdywgX2hpZGVPdmVyZmxvd0NhY2hlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hpZGVPdmVyZmxvd0NhY2hlID0gaGlkZU92ZXJmbG93O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiBuYXRpdmUgc2Nyb2xsYmFyIGlzIG92ZXJsYXkgYXQgeCBPUiB5IGF4aXMsIHByZXBhcmUgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54IHx8IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBib3JkZXJEZXNpZ24gPSAncHggc29saWQgdHJhbnNwYXJlbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRlbnRBcnJhbmdlRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFycmFuZ2VDb250ZW50ID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXJyYW5nZUNoYW5nZWQgPSBmb3JjZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzZXRDb250ZW50RWxlbWVudENTUztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzT3ZlcmZsb3cueCB8fCBoYXNPdmVyZmxvdy55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyYW5nZUNvbnRlbnQudyA9IF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkgJiYgaGFzT3ZlcmZsb3cueSA/IGNvbnRlbnRTY3JvbGxTaXplLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55IDogX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50LmggPSBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIGhhc092ZXJmbG93LnggPyBjb250ZW50U2Nyb2xsU2l6ZS5oICsgX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemUueCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IGNoZWNrQ2FjaGVBdXRvRm9yY2UoYXJyYW5nZUNvbnRlbnQsIF9hcnJhbmdlQ29udGVudFNpemVDYWNoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2FycmFuZ2VDb250ZW50U2l6ZUNhY2hlID0gYXJyYW5nZUNvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93LmMgfHwgaGlkZU92ZXJmbG93LmMgfHwgY29udGVudFNjcm9sbFNpemUuYyB8fCBjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQgfHwgd2lkdGhBdXRvIHx8IGhlaWdodEF1dG8gfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IGNvbnRlbnRFbGVtZW50Q1NTW19zdHJCb3JkZXJNaW51cyArIGlzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTID0gZnVuY3Rpb24gKGhvcml6b250YWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGhvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4eSA9IHNjcm9sbGJhclZhcnMuX3hfeTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckRpcmVjdGlvbiA9IGhvcml6b250YWwgPyBfc3RyQm90dG9tIDogaXNSVExMZWZ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW52ZXJ0ZWRBdXRvU2l6ZSA9IGhvcml6b250YWwgPyBoZWlnaHRBdXRvIDogd2lkdGhBdXRvO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSAmJiBoYXNPdmVyZmxvd1t4eV0gJiYgaGlkZU92ZXJmbG93W3h5ICsgJ3MnXSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IGludmVydGVkQXV0b1NpemUgPyAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZyA/IF9zdHJFbXB0eSA6IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSkgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyQm9yZGVyTWludXMgKyBzdHJEaXJlY3Rpb25dID0gKChob3Jpem9udGFsID8gIWludmVydGVkQXV0b1NpemUgOiB0cnVlKSAmJiAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykgPyAoX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbeHldICsgYm9yZGVyRGVzaWduKSA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDb250ZW50W3Njcm9sbGJhclZhcnNJbnZlcnRlZC5fd19oXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgc3RyRGlyZWN0aW9uXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEVsZW1lbnRDU1NbX3N0ckJvcmRlck1pbnVzICsgc3RyRGlyZWN0aW9uXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmFuZ2VDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbmF0aXZlU2Nyb2xsYmFyU3R5bGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlLCAhaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldENvbnRlbnRFbGVtZW50Q1NTKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRDb250ZW50RWxlbWVudENTUyhmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ29udGVudC53ID0gYXJyYW5nZUNvbnRlbnQuaCA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnJhbmdlQ2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJyYW5nZUNoYW5nZWQgJiYgIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSBoaWRlT3ZlcmZsb3cueSA/IGFycmFuZ2VDb250ZW50LncgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudEFycmFuZ2VFbGVtZW50Q1NTW19zdHJIZWlnaHRdID0gaGlkZU92ZXJmbG93LnggPyBhcnJhbmdlQ29udGVudC5oIDogX3N0ckVtcHR5O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9jb250ZW50QXJyYW5nZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudCA9IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lQ29udGVudEFycmFuZ2VFbGVtZW50KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQucHJlcGVuZChfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRBcnJhbmdlRWxlbWVudC5jc3MoY29udGVudEFycmFuZ2VFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoY29udGVudEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nRWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2V0Vmlld3BvcnRDU1M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgaGFzT3ZlcmZsb3cuYyB8fCBoaWRlT3ZlcmZsb3cuYyB8fCBjb250ZW50U2Nyb2xsU2l6ZS5jIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQgfHwgY3NzRGlyZWN0aW9uQ2hhbmdlZCB8fCBjbGlwQWx3YXlzQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW2lzUlRMUmlnaHRdID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1MgPSBmdW5jdGlvbiAoaG9yaXpvbnRhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhob3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyVmFyc0ludmVydGVkID0gZ2V0U2Nyb2xsYmFyVmFycyghaG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHh5ID0gc2Nyb2xsYmFyVmFycy5feF95O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBYWSA9IHNjcm9sbGJhclZhcnMuX1hfWTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RyRGlyZWN0aW9uID0gaG9yaXpvbnRhbCA/IF9zdHJCb3R0b20gOiBpc1JUTExlZnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50Qm9yZGVyU2l6ZVtzY3JvbGxiYXJWYXJzSW52ZXJ0ZWQuX3dfaF0gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc092ZXJmbG93W3h5XSAmJiBoaWRlT3ZlcmZsb3dbeHkgKyAncyddKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nIHx8IF9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW3N0ckRpcmVjdGlvbl0gPSAtKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkW3h5XSA/IF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplW3h5XSA6IF9uYXRpdmVTY3JvbGxiYXJTaXplW3h5XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEJvcmRlclNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl93X2hdID0gX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWRbeHldID8gX292ZXJsYXlTY3JvbGxiYXJEdW1teVNpemVbc2Nyb2xsYmFyVmFyc0ludmVydGVkLl94X3ldIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tzdHJPdmVyZmxvdyArIFhZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0Vmlld3BvcnRDU1ModHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRWaWV3cG9ydENTUyhmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHNjcm9sbCBjb250YWluZXIgaXMgdG9vIHNtYWxsIGFuZCBpZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgd2l0aCBubyBvdmVybGF5IHNjcm9sbGJhciAoYW5kIHNjcm9sbGJhciBzdHlsaW5nIGlzbid0IHBvc3NpYmxlKSwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHZpZXdwb3J0IGVsZW1lbnQgZ3JlYXRlciBpbiBzaXplIChGaXJlZm94IGhpZGUgU2Nyb2xsYmFycyBmaXgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGZpcmVmb3ggc3RhcnRzIGhpZGluZyBzY3JvbGxiYXJzIG9uIHRvbyBzbWFsbCBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2l0aCB0aGlzIGJlaGF2aW9yIHRoZSBvdmVyZmxvdyBjYWxjdWxhdGlvbiBtYXkgYmUgaW5jb3JyZWN0IG9yIHRoZSBzY3JvbGxiYXJzIHdvdWxkIGFwcGVhciBzdWRkZW5seVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkyMjg0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9uYXRpdmVTY3JvbGxiYXJTdHlsaW5nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgKF92aWV3cG9ydFNpemUuaCA8IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnggfHwgX3ZpZXdwb3J0U2l6ZS53IDwgX25hdGl2ZVNjcm9sbGJhck1pblNpemUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAoKGhhc092ZXJmbG93LnggJiYgaGlkZU92ZXJmbG93LnggJiYgIV9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLngpIHx8IChoYXNPdmVyZmxvdy55ICYmIGhpZGVPdmVyZmxvdy55ICYmICFfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55KSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID0gX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0ck1hcmdpbk1pbnVzICsgX3N0clRvcF0gPSAtX25hdGl2ZVNjcm9sbGJhck1pblNpemUueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMUmlnaHRdID0gLV9uYXRpdmVTY3JvbGxiYXJNaW5TaXplLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1NbX3N0clBhZGRpbmdNaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIF9zdHJUb3BdID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJQYWRkaW5nTWludXMgKyBpc1JUTFJpZ2h0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyTWFyZ2luTWludXMgKyBpc1JUTFJpZ2h0XSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTU1tfc3RyUGFkZGluZ01pbnVzICsgaXNSVExMZWZ0XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld3BvcnRFbGVtZW50Q1NTW19zdHJNYXJnaW5NaW51cyArIGlzUlRMTGVmdF0gPSBfc3RyRW1wdHk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhbnkgb3ZlcmZsb3cgKHggT1IgeSBheGlzKSBhbmQgdGhpcyBvdmVyZmxvdyBzaGFsbCBiZSBoaWRkZW4sIG1ha2Ugb3ZlcmZsb3cgaGlkZGVuLCBlbHNlIG92ZXJmbG93IHZpc2libGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoaGFzT3ZlcmZsb3cueCAmJiBoaWRlT3ZlcmZsb3cueCkgfHwgKGhhc092ZXJmbG93LnkgJiYgaGlkZU92ZXJmbG93LnkpIHx8IGhpZGVPdmVyZmxvd0ZvcmNlVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL29ubHkgaGlkZSBpZiBpcyBUZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSAmJiBoaWRlT3ZlcmZsb3dGb3JjZVRleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZGRpbmdFbGVtZW50Q1NTW3N0ck92ZXJmbG93WF0gPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0ckhpZGRlbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNsaXBBbHdheXMgfHwgKG92ZXJmbG93QmVoYXZpb3JJc1ZILnggfHwgb3ZlcmZsb3dCZWhhdmlvcklzVlMueCB8fCBvdmVyZmxvd0JlaGF2aW9ySXNWSC55IHx8IG92ZXJmbG93QmVoYXZpb3JJc1ZTLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vb25seSB1bi1oaWRlIGlmIFRleHRhcmVhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZ0VsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dYXSA9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydEVsZW1lbnRDU1Nbc3RyT3ZlcmZsb3dZXSA9IHN0clZpc2libGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudC5jc3MocGFkZGluZ0VsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5jc3Modmlld3BvcnRFbGVtZW50Q1NTKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2Ugc29mdCByZWRyYXcgaW4gd2Via2l0IGJlY2F1c2Ugd2l0aG91dCB0aGUgc2Nyb2xsYmFycyB3aWxsIG1heSBhcHBlYXIgYmVjYXVzZSBET00gd29udCBiZSByZWRyYXduIHVuZGVyIHNwZWNpYWwgY29uZGl0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChoYXNPdmVyZmxvdy5jIHx8IGJveFNpemluZ0NoYW5nZWQgfHwgd2lkdGhBdXRvQ2hhbmdlZCB8fCBoZWlnaHRBdXRvQ2hhbmdlZCkgJiYgIShfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTdHlsZSA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLnNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAnc2NhbGUoMSknO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdHlsZS5kaXNwbGF5ID0gJ3J1bi1pbic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVtcCA9IF9jb250ZW50RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUuZGlzcGxheSA9IF9zdHJFbXB0eTsgLy98fCBkdW1wOyAvL3VzZSBkdW1wIHRvIHByZXZlbnQgaXQgZnJvbSBkZWxldGlvbiBpZiBtaW5pZnlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3R5bGUud2Via2l0VHJhbnNmb3JtID0gX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yY2UgaGFyZCByZWRyYXcgaW4gd2Via2l0IGlmIG5hdGl2ZSBvdmVybGFpZCBzY3JvbGxiYXJzIHNoYWxsIGFwcGVhclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkICYmIGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkdW1wID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub0hdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5zaG93KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NoYW5nZSB0byBkaXJlY3Rpb24gUlRMIGFuZCB3aWR0aCBhdXRvIEJ1Z2ZpeCBpbiBXZWJraXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy93aXRob3V0IHRoaXMgZml4LCB0aGUgRE9NIHN0aWxsIHRoaW5rcyB0aGUgc2Nyb2xsYmFyIGlzIExUUiBhbmQgdGh1cyB0aGUgY29udGVudCBpcyBzaGlmdGVkIHRvIHRoZSBsZWZ0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjc3NEaXJlY3Rpb25DaGFuZ2VkIHx8IHdpZHRoQXV0b0NoYW5nZWQgfHwgaGVpZ2h0QXV0b0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwgJiYgd2lkdGhBdXRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZsb2F0VG1wID0gX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyRmxvYXQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aG91dEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgX3N0ckVtcHR5KS5jc3MoX3N0ckxlZnQsIF9zdHJFbXB0eSkucG9zaXRpb24oKS5sZWZ0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQuY3NzKF9zdHJGbG9hdCwgZmxvYXRUbXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NMZWZ0V2l0aEZsb2F0ID0gTUFUSC5yb3VuZChfY29udGVudEVsZW1lbnQucG9zaXRpb24oKS5sZWZ0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBvc0xlZnRXaXRob3V0RmxvYXQgIT09IHBvc0xlZnRXaXRoRmxvYXQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRFbGVtZW50Q1NTW19zdHJMZWZ0XSA9IHBvc0xlZnRXaXRob3V0RmxvYXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50RWxlbWVudENTU1tfc3RyTGVmdF0gPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhjb250ZW50RWxlbWVudENTUyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2hhbmRsZSBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhICYmIGNvbnRlbnRTaXplQ2hhbmdlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhSW5mbyA9IGdldFRleHRhcmVhSW5mbygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhSW5mbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYVJvd3NDaGFuZ2VkID0gX3RleHRhcmVhSW5mb0NhY2hlID09PSB1bmRlZmluZWQgPyB0cnVlIDogdGV4dGFyZWFJbmZvLl9yb3dzICE9PSBfdGV4dGFyZWFJbmZvQ2FjaGUuX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclJvdyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUm93O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUluZm8uX2N1cnNvckNvbHVtbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2lkZXN0Um93ID0gdGV4dGFyZWFJbmZvLl93aWRlc3RSb3c7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RSb3cgPSB0ZXh0YXJlYUluZm8uX3Jvd3M7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhc3RDb2wgPSB0ZXh0YXJlYUluZm8uX2NvbHVtbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvclBvcyA9IHRleHRhcmVhSW5mby5fY3Vyc29yUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGN1cnNvck1heCA9IHRleHRhcmVhSW5mby5fY3Vyc29yTWF4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JJc0xhc3RQb3NpdGlvbiA9IChjdXJzb3JQb3MgPj0gY3Vyc29yTWF4ICYmIF90ZXh0YXJlYUhhc0ZvY3VzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFTY3JvbGxBbW91bnQgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6ICghdGV4dGFyZWFBdXRvV3JhcHBpbmcgJiYgKGN1cnNvckNvbCA9PT0gbGFzdENvbCAmJiBjdXJzb3JSb3cgPT09IHdpZGVzdFJvdykpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueCA6IC0xLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiAodGV4dGFyZWFBdXRvV3JhcHBpbmcgPyBjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkICYmIChwcmV2aW91c092ZXJmbG93QW1vdW50ID8gKGN1cnJTY3JvbGwueSA9PT0gcHJldmlvdXNPdmVyZmxvd0Ftb3VudC55KSA6IGZhbHNlKSA6IChjdXJzb3JJc0xhc3RQb3NpdGlvbiB8fCB0ZXh0YXJlYVJvd3NDaGFuZ2VkKSAmJiBjdXJzb3JSb3cgPT09IGxhc3RSb3cpID8gX292ZXJmbG93QW1vdW50Q2FjaGUueSA6IC0xXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyU2Nyb2xsLnggPSB0ZXh0YXJlYVNjcm9sbEFtb3VudC54ID4gLTEgPyAoX2lzUlRMICYmIF9ub3JtYWxpemVSVExDYWNoZSAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IDAgOiB0ZXh0YXJlYVNjcm9sbEFtb3VudC54KSA6IGN1cnJTY3JvbGwueDsgLy9pZiBpbnZlcnRlZCwgc2Nyb2xsIHRvIDAgLT4gbm9ybWFsaXplZCB0aGlzIG1lYW5zIHRvIG1heCBzY3JvbGwgb2Zmc2V0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJTY3JvbGwueSA9IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgPiAtMSA/IHRleHRhcmVhU2Nyb2xsQW1vdW50LnkgOiBjdXJyU2Nyb2xsLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGV4dGFyZWFJbmZvQ2FjaGUgPSB0ZXh0YXJlYUluZm87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSAmJiBfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC55ICYmIGhhc092ZXJmbG93LnggJiYgX25vcm1hbGl6ZVJUTENhY2hlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyclNjcm9sbC54ICs9IF9jb250ZW50Qm9yZGVyU2l6ZS53IHx8IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aEF1dG8pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGVpZ2h0QXV0bylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oY3VyclNjcm9sbC54KVtfc3RyU2Nyb2xsVG9wXShjdXJyU2Nyb2xsLnkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGxiYXJzIG1hbmFnZW1lbnQ6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJzVmlzaWJpbGl0eVZpc2libGUgPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ3YnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4gPSBzY3JvbGxiYXJzVmlzaWJpbGl0eSA9PT0gJ2gnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyc1Zpc2liaWxpdHlBdXRvID0gc2Nyb2xsYmFyc1Zpc2liaWxpdHkgPT09ICdhJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eSA9IGZ1bmN0aW9uIChzaG93WCwgc2hvd1kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dZID0gc2hvd1kgPT09IHVuZGVmaW5lZCA/IHNob3dYIDogc2hvd1k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZSh0cnVlLCBzaG93WCwgY2FuU2Nyb2xsLngpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyQXBwZWFyYW5jZShmYWxzZSwgc2hvd1ksIGNhblNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgY2xhc3MgbmFtZSB3aGljaCBpbmRpY2F0ZXMgc2Nyb2xsYWJsZSBvdmVyZmxvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3csIGhpZGVPdmVyZmxvdy54IHx8IGhpZGVPdmVyZmxvdy55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdE92ZXJmbG93WCwgaGlkZU92ZXJmbG93LngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLCBoaWRlT3ZlcmZsb3cueSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBvciByZW1vdmUgcnRsIGNsYXNzIG5hbWUgZm9yIHN0eWxpbmcgcHVycG9zZXMgZXhjZXB0IHdoZW4gaXRzIGJvZHksIHRoZW4gdGhlIHNjcm9sbGJhciBzdGF5c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3NzRGlyZWN0aW9uQ2hhbmdlZCAmJiAhX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBfY2xhc3NOYW1lSG9zdFJUTCwgX2lzUlRMKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHJlc2l6ZSBmZWF0dXJlIChDU1MzIHJlc2l6ZSBcInBvbHlmaWxsXCIgZm9yIHRoaXMgcGx1Z2luKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNpemVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0UmVzaXplRGlzYWJsZWQsIF9yZXNpemVOb25lKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplLCAhX3Jlc2l6ZU5vbmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkUmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJDb3JuZXJSZXNpemVCLCBfcmVzaXplQm90aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCwgX2NsYXNzTmFtZVNjcm9sbGJhckNvcm5lclJlc2l6ZUgsIF9yZXNpemVIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFJlbW92ZUNsYXNzKF9zY3JvbGxiYXJDb3JuZXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyUmVzaXplViwgX3Jlc2l6ZVZlcnRpY2FsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgdGhlIHNjcm9sbGJhcnMgZ2VuZXJhbCB2aXNpYmlsaXR5ICsgdGhlIHNjcm9sbGJhciBpbnRlcmFjdGl2aXR5ICh1bnVzYWJsZSBjbGFzcyBuYW1lKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlDaGFuZ2VkIHx8IG92ZXJmbG93QmVoYXZpb3JDaGFuZ2VkIHx8IGhpZGVPdmVyZmxvdy5jIHx8IGhhc092ZXJmbG93LmMgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpZ25vcmVPdmVybGF5U2Nyb2xsYmFySGlkaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgX2NsYXNzTmFtZUhvc3RTY3JvbGxpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHNjcm9sbGJhcnNWaXNpYmlsaXR5QXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzVmlzaWJpbGl0eShjYW5TY3JvbGwueCwgY2FuU2Nyb2xsLnkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlWaXNpYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNWaXNpYmlsaXR5KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2Nyb2xsYmFyc1Zpc2liaWxpdHlIaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc1Zpc2liaWxpdHkoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSB0aGUgc2Nyb2xsYmFycyBhdXRvIGhpZGUgZmVhdHVyZSAoYXV0byBoaWRlIHRoZW0gYWZ0ZXIgc3BlY2lmaWMgYWN0aW9ucylcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNBdXRvSGlkZUNoYW5nZWQgfHwgaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwSG9zdE1vdXNlVG91Y2hFdmVudHMoIV9zY3JvbGxiYXJzQXV0b0hpZGVMZWF2ZSAmJiAhX3Njcm9sbGJhcnNBdXRvSGlkZU1vdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIsICFfc2Nyb2xsYmFyc0F1dG9IaWRlTmV2ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL21hbmFnZSBzY3JvbGxiYXJzIGhhbmRsZSBsZW5ndGggJiBvZmZzZXQgLSBkb24ndCByZW1vdmUhXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChob3N0U2l6ZUNoYW5nZWQgfHwgb3ZlcmZsb3dBbW91bnQuYyB8fCBoZWlnaHRBdXRvQ2hhbmdlZCB8fCB3aWR0aEF1dG9DaGFuZ2VkIHx8IHJlc2l6ZUNoYW5nZWQgfHwgYm94U2l6aW5nQ2hhbmdlZCB8fCBwYWRkaW5nQWJzb2x1dGVDaGFuZ2VkIHx8IGlnbm9yZU92ZXJsYXlTY3JvbGxiYXJIaWRpbmdDaGFuZ2VkIHx8IGNzc0RpcmVjdGlvbkNoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZUxlbmd0aChmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYW5hZ2UgaW50ZXJhY3Rpdml0eVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUodHJ1ZSwgc2Nyb2xsYmFyc0NsaWNrU2Nyb2xsaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2hhbmdlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzSW50ZXJhY3RpdmUoZmFsc2UsIHNjcm9sbGJhcnNEcmFnU2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsbGJhY2tzOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRpcmVjdGlvbkNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTDogX2lzUlRMLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyOiBjc3NEaXJlY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgY3NzRGlyZWN0aW9uQ2hhbmdlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uSG9zdFNpemVDaGFuZ2VkJywge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IF9ob3N0U2l6ZUNhY2hlLncsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IF9ob3N0U2l6ZUNhY2hlLmhcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgaG9zdFNpemVDaGFuZ2VkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Db250ZW50U2l6ZUNoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUudyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGUuaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBjb250ZW50U2l6ZUNoYW5nZWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbk92ZXJmbG93Q2hhbmdlZCcsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGhhc092ZXJmbG93LngsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBoYXNPdmVyZmxvdy55LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeFNjcm9sbGFibGU6IGhpZGVPdmVyZmxvdy54cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlTY3JvbGxhYmxlOiBoaWRlT3ZlcmZsb3cueXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwcGVkOiBoaWRlT3ZlcmZsb3cueCB8fCBoaWRlT3ZlcmZsb3cueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBoYXNPdmVyZmxvdy5jIHx8IGhpZGVPdmVyZmxvdy5jKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25PdmVyZmxvd0Ftb3VudENoYW5nZWQnLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBvdmVyZmxvd0Ftb3VudC54LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogb3ZlcmZsb3dBbW91bnQueVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9LCBvdmVyZmxvd0Ftb3VudC5jKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vZml4IGJvZHkgbWluIHNpemVcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSAmJiBfYm9keU1pblNpemVDYWNoZSAmJiAoX2hhc092ZXJmbG93Q2FjaGUuYyB8fCBfYm9keU1pblNpemVDYWNoZS5jKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2l0cyBwb3NzaWJsZSB0aGF0IG5vIG1pbiBzaXplIHdhcyBtZWFzdXJlZCB1bnRpbCBub3csIGJlY2F1c2UgdGhlIGNvbnRlbnQgYXJyYW5nZSBlbGVtZW50IHdhcyBqdXN0IGFkZGVkIG5vdywgaW4gdGhpcyBjYXNlLCBtZWFzdXJlIG5vdyB0aGUgbWluIHNpemUuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2JvZHlNaW5TaXplQ2FjaGUuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvZHlNaW5TaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiBfaGFzT3ZlcmZsb3dDYWNoZS54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNzcyhfc3RyTWluTWludXMgKyBfc3RyV2lkdGgsIF9ib2R5TWluU2l6ZUNhY2hlLncgKyBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX2hhc092ZXJmbG93Q2FjaGUueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5jc3MoX3N0ck1pbk1pbnVzICsgX3N0ckhlaWdodCwgX2JvZHlNaW5TaXplQ2FjaGUuaCArIF9vdmVybGF5U2Nyb2xsYmFyRHVtbXlTaXplLngpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYm9keU1pblNpemVDYWNoZS5jID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkICYmIGNoYW5nZWRPcHRpb25zLnVwZGF0ZU9uTG9hZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVFbGVtZW50c09uTG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9mcmVlemVSZXNpemVPYnNlcnZlcihfc2l6ZU9ic2VydmVyRWxlbWVudCwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZnJlZXplUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50LCBmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uVXBkYXRlZCcsIHsgZm9yY2VkOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFVwZGF0ZXMgdGhlIGZvdW5kIGVsZW1lbnRzIG9mIHdoaWNoIHRoZSBsb2FkIGV2ZW50IHNoYWxsIGJlIGhhbmRsZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghX2lzVGV4dGFyZWEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaFVwZGF0ZU9uTG9hZChmdW5jdGlvbiAoaSwgdXBkYXRlT25Mb2FkU2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZW50RWxlbWVudC5maW5kKHVwZGF0ZU9uTG9hZFNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uIChpLCBlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIGVsZW1lbnQgZG9lc24ndCBoYXZlIGEgdXBkYXRlT25Mb2FkQ2FsbGJhY2sgYXBwbGllZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmluQShlbCwgX3VwZGF0ZU9uTG9hZEVsbXMpIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcy5wdXNoKGVsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLKGVsKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm9mZihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjaylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5vbihfdXBkYXRlT25Mb2FkRXZlbnROYW1lLCB1cGRhdGVPbkxvYWRDYWxsYmFjayk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gT3B0aW9ucyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgbmV3IG9wdGlvbnMgYnV0IGRvZXNuJ3QgY2FsbCB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIFRoZSBvYmplY3Qgd2hpY2ggY29udGFpbnMgdGhlIG5ldyBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IEEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBjaGFuZ2VkIG9wdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldE9wdGlvbnMobmV3T3B0aW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWxpZGF0ZWRPcHRzID0gX3BsdWdpbnNPcHRpb25zLl92YWxpZGF0ZShuZXdPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBfY3VycmVudE9wdGlvbnMpXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF9jdXJyZW50T3B0aW9ucyA9IGV4dGVuZERlZXAoe30sIF9jdXJyZW50T3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fZGVmYXVsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMgPSBleHRlbmREZWVwKHt9LCBfY3VycmVudFByZXBhcmVkT3B0aW9ucywgdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsaWRhdGVkT3B0cy5fcHJlcGFyZWQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBTdHJ1Y3R1cmUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBCdWlsZHMgb3IgZGVzdHJveXMgdGhlIHdyYXBwZXIgYW5kIGhlbHBlciBET00gZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZGVzdHJveSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgRE9NIHNoYWxsIGJlIGJ1aWxkIG9yIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTdHJ1Y3R1cmVET00oZGVzdHJveSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJQYXJlbnQgPSAncGFyZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lUmVzaXplT2JzZXJ2ZXJIb3N0ID0gJ29zLXJlc2l6ZS1vYnNlcnZlci1ob3N0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50RnVsbCA9IF9jbGFzc05hbWVUZXh0YXJlYUVsZW1lbnQgKyBfc3RyU3BhY2UgKyBfY2xhc3NOYW1lVGV4dEluaGVyaXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ2xhc3MgPSBfaXNUZXh0YXJlYSA/IF9zdHJTcGFjZSArIF9jbGFzc05hbWVUZXh0SW5oZXJpdCA6IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYWRvcHRBdHRycyA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLnRleHRhcmVhLmluaGVyaXRlZEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhZG9wdEF0dHJzTWFwID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGx5QWRvcHRlZEF0dHJzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXBwbHlBZG9wdGVkQXR0cnNFbG0gPSBkZXN0cm95ID8gX3RhcmdldEVsZW1lbnQgOiBfaG9zdEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goYWRvcHRBdHRyc01hcCwgZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGtleSA9PSBMRVhJQ09OLmMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmFkZENsYXNzKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGx5QWRvcHRlZEF0dHJzRWxtLmF0dHIoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhvc3RFbGVtZW50Q2xhc3NOYW1lcyA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdEVsZW1lbnRGb3JlaWduLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSZXNpemVEaXNhYmxlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RTY3JvbGxiYXJWZXJ0aWNhbEhpZGRlbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RUcmFuc2l0aW9uLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lSG9zdFNjcm9sbGluZyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvdyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2NsYXNzTmFtZUhvc3RPdmVyZmxvd1gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVIb3N0T3ZlcmZsb3dZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGhlbWVOb25lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2xhc3NOYW1lVGV4dEluaGVyaXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jbGFzc05hbWVDYWNoZV0uam9pbihfc3RyU3BhY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBob3N0IGVsZW1lbnQgYXMgZmlyc3QgZWxlbWVudCwgYmVjYXVzZSB0aGF0J3MgdGhlIG1vc3QgdXBwZXIgZWxlbWVudCBhbmQgcmVxdWlyZWQgZm9yIHRoZSBvdGhlciBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudCA9IF9ob3N0RWxlbWVudCB8fCAoX2lzVGV4dGFyZWEgPyAoX2RvbUV4aXN0cyA/IF90YXJnZXRFbGVtZW50W3N0clBhcmVudF0oKVtzdHJQYXJlbnRdKClbc3RyUGFyZW50XSgpW3N0clBhcmVudF0oKSA6IEZSQU1FV09SSyhnZW5lcmF0ZURpdihfY2xhc3NOYW1lSG9zdFRleHRhcmVhRWxlbWVudCkpKSA6IF90YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnQgPSBfY29udGVudEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZUNvbnRlbnRFbGVtZW50ICsgdGV4dGFyZWFDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudCA9IF92aWV3cG9ydEVsZW1lbnQgfHwgc2VsZWN0T3JHZW5lcmF0ZURpdkJ5Q2xhc3MoX2NsYXNzTmFtZVZpZXdwb3J0RWxlbWVudCArIHRleHRhcmVhQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9wYWRkaW5nRWxlbWVudCA9IF9wYWRkaW5nRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lUGFkZGluZ0VsZW1lbnQgKyB0ZXh0YXJlYUNsYXNzKTtcclxuICAgICAgICAgICAgICAgICAgICBfc2l6ZU9ic2VydmVyRWxlbWVudCA9IF9zaXplT2JzZXJ2ZXJFbGVtZW50IHx8IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKGNsYXNzTmFtZVJlc2l6ZU9ic2VydmVySG9zdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhQ292ZXJFbGVtZW50ID0gX3RleHRhcmVhQ292ZXJFbGVtZW50IHx8IChfaXNUZXh0YXJlYSA/IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVUZXh0YXJlYUNvdmVyRWxlbWVudCkgOiB1bmRlZmluZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2FkZCB0aGlzIGNsYXNzIHRvIHdvcmthcm91bmQgY2xhc3MgY2hhbmdpbmcgaXNzdWVzIHdpdGggVUkgZnJhbWV3b3JrcyBlc3BlY2lhbGx5IFZ1ZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0RWxlbWVudEZvcmVpZ24pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL29uIGRlc3Ryb3ksIHJlbW92ZSBhbGwgZ2VuZXJhdGVkIGNsYXNzIG5hbWVzIGZyb20gdGhlIGhvc3QgZWxlbWVudCBiZWZvcmUgY29sbGVjdGluZyB0aGUgYWRvcHRlZCBhdHRyaWJ1dGVzIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vdG8gcHJldmVudCBhZG9wdGluZyBnZW5lcmF0ZWQgY2xhc3MgbmFtZXNcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZGVzdHJveSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2hvc3RFbGVtZW50LCBob3N0RWxlbWVudENsYXNzTmFtZXMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NvbGxlY3QgYWxsIGFkb3B0ZWQgYXR0cmlidXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIGFkb3B0QXR0cnMgPSB0eXBlKGFkb3B0QXR0cnMpID09IFRZUEVTLnMgPyBhZG9wdEF0dHJzLnNwbGl0KF9zdHJTcGFjZSkgOiBhZG9wdEF0dHJzO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShhZG9wdEF0dHJzKSAmJiBfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGFkb3B0QXR0cnMsIGZ1bmN0aW9uIChpLCB2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSh2KSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRvcHRBdHRyc01hcFt2XSA9IGRlc3Ryb3kgPyBfaG9zdEVsZW1lbnQuYXR0cih2KSA6IF90YXJnZXRFbGVtZW50LmF0dHIodik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNUZXh0YXJlYSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfY3VycmVudFByZXBhcmVkT3B0aW9ucy5zaXplQXV0b0NhcGFibGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3N0RWxlbWVudENTU1tfc3RyV2lkdGhdID0gX3RhcmdldEVsZW1lbnQuY3NzKF9zdHJXaWR0aCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSBfdGFyZ2V0RWxlbWVudC5jc3MoX3N0ckhlaWdodCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90YXJnZXRFbGVtZW50LmFkZENsYXNzKF9jbGFzc05hbWVUZXh0SW5oZXJpdCkud3JhcChfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50ID0gX3RhcmdldEVsZW1lbnRbc3RyUGFyZW50XSgpLmNzcyhob3N0RWxlbWVudENTUyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9hZGQgdGhlIGNvcnJlY3QgY2xhc3MgdG8gdGhlIHRhcmdldCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdGFyZ2V0RWxlbWVudCwgX2lzVGV4dGFyZWEgPyBjbGFzc05hbWVUZXh0YXJlYUVsZW1lbnRGdWxsIDogX2NsYXNzTmFtZUhvc3RFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3dyYXAgdGhlIGNvbnRlbnQgaW50byB0aGUgZ2VuZXJhdGVkIGVsZW1lbnRzIHRvIGNyZWF0ZSB0aGUgcmVxdWlyZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfaG9zdEVsZW1lbnQud3JhcElubmVyKF9jb250ZW50RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAud3JhcElubmVyKF92aWV3cG9ydEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLndyYXBJbm5lcihfcGFkZGluZ0VsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByZXBlbmQoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8valF1ZXJ5IGNsb25lcyBlbGVtZW50cyBpbiB3cmFwIGZ1bmN0aW9ucywgc28gd2UgaGF2ZSB0byBzZWxlY3QgdGhlbSBhZ2FpblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVDb250ZW50RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVWaWV3cG9ydEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50ID0gZmluZEZpcnN0KF9ob3N0RWxlbWVudCwgX3N0ckRvdCArIF9jbGFzc05hbWVQYWRkaW5nRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LnByZXBlbmQoX3RleHRhcmVhQ292ZXJFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBseUFkb3B0ZWRBdHRycygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfdmlld3BvcnRFbGVtZW50LCBfY2xhc3NOYW1lVmlld3BvcnROYXRpdmVTY3JvbGxiYXJzSW52aXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF92aWV3cG9ydEVsZW1lbnQsIF9jbGFzc05hbWVWaWV3cG9ydE5hdGl2ZVNjcm9sbGJhcnNPdmVybGFpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNCb2R5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2h0bWxFbGVtZW50LCBfY2xhc3NOYW1lSFRNTEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3NpemVPYnNlcnZlckVsZW1lbnROYXRpdmUgPSBfc2l6ZU9ic2VydmVyRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50TmF0aXZlID0gX2hvc3RFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfcGFkZGluZ0VsZW1lbnROYXRpdmUgPSBfcGFkZGluZ0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUgPSBfdmlld3BvcnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudEVsZW1lbnROYXRpdmUgPSBfY29udGVudEVsZW1lbnRbMF07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVWaWV3cG9ydEF0dHJzRnJvbVRhcmdldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9kb21FeGlzdHMgJiYgX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NsZWFyIHNpemUgb2JzZXJ2ZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zaXplT2JzZXJ2ZXJFbGVtZW50LmNoaWxkcmVuKCkucmVtb3ZlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhlIHN0eWxlIHByb3BlcnR5IGFuZCBjbGFzc2VzIGZyb20gYWxyZWFkeSBnZW5lcmF0ZWQgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhY2goW19wYWRkaW5nRWxlbWVudCwgX3ZpZXdwb3J0RWxlbWVudCwgX2NvbnRlbnRFbGVtZW50LCBfdGV4dGFyZWFDb3ZlckVsZW1lbnRdLCBmdW5jdGlvbiAoaSwgZWxtKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhlbG0ucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FkZCBjbGFzc2VzIHRvIHRoZSBob3N0IGVsZW1lbnQgd2hpY2ggd2FzIHJlbW92ZWQgcHJldmlvdXNseSB0byBtYXRjaCB0aGUgZXhwZWN0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9pc1RleHRhcmVhID8gX2NsYXNzTmFtZUhvc3RUZXh0YXJlYUVsZW1lbnQgOiBfY2xhc3NOYW1lSG9zdEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgc2l6ZSBvYnNlcnZlclxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3Vud3JhcCB0aGUgY29udGVudCB0byByZXN0b3JlIERPTVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRFbGVtZW50LmNvbnRlbnRzKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudW53cmFwKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQudW53cmFwKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9ob3N0RWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF90ZXh0YXJlYUNvdmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwbHlBZG9wdGVkQXR0cnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc0JvZHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaHRtbEVsZW1lbnQsIF9jbGFzc05hbWVIVE1MRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQWRkcyBvciByZW1vdmVzIGFsbCB3cmFwcGVyIGVsZW1lbnRzIGludGVyYWN0aXZpdHkgZXZlbnRzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIEV2ZW50cyBzaGFsbCBiZSBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFN0cnVjdHVyZUV2ZW50cygpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAxMTIsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIDEyMywgICAgLy9GMSB0byBGMTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgMzMsIDM0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGFnZSB1cCwgcGFnZSBkb3duXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDM3LCAzOCwgMzksIDQwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2xlZnQsIHVwLCByaWdodCwgZG93biBhcnJvd3NcclxuICAgICAgICAgICAgICAgICAgICAgICAgMTYsIDE3LCAxOCwgMTksIDIwLCAxNDQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vU2hpZnQsIEN0cmwsIEFsdCwgUGF1c2UsIENhcHNMb2NrLCBOdW1Mb2NrXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcFRpbWVvdXRJZDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsU3RvcERlbGF5ID0gMTc1O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJGb2N1cyA9ICdmb2N1cyc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVRleHRhcmVhKGRvQ2xlYXJJbnRlcnZhbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYVVwZGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUoX3N0ckF1dG8pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9DbGVhckludGVydmFsICYmIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25TY3JvbGwoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIF9ub3JtYWxpemVSVExDYWNoZSA/IDk5OTk5OTkgOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbkRyb3AoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlVGV4dGFyZWEoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNTApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiB0ZXh0YXJlYU9uRm9jdXMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF90ZXh0YXJlYUhhc0ZvY3VzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3MoX2hvc3RFbGVtZW50LCBzdHJGb2N1cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHRleHRhcmVhT25Gb2N1c291dCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RleHRhcmVhSGFzRm9jdXMgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ob3N0RWxlbWVudCwgc3RyRm9jdXMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGtleUNvZGUgPSBldmVudC5rZXlDb2RlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0W0xFWElDT04ubF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhVXBkYXRlSW50ZXJ2YWxJRCA9IHNldEludGVydmFsKHVwZGF0ZVRleHRhcmVhLCAxMDAwIC8gNjApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0KSA8IDApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGFyZWFLZXlEb3duS2V5Q29kZXNMaXN0LnB1c2goa2V5Q29kZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdGV4dGFyZWFPbktleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXlDb2RlID0gZXZlbnQua2V5Q29kZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gaW5BcnJheShrZXlDb2RlLCB0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3QpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoa2V5Q29kZSwgdGV4dGFyZWFLZXlEb3duUmVzdHJpY3RlZEtleUNvZGVzKSA8IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRhcmVhS2V5RG93bktleUNvZGVzTGlzdC5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZXh0YXJlYUtleURvd25LZXlDb2Rlc0xpc3RbTEVYSUNPTi5sXSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVUZXh0YXJlYSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb250ZW50T25UcmFuc2l0aW9uRW5kKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfYXV0b1VwZGF0ZUNhY2hlID09PSB0cnVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1NpemVBZmZlY3RpbmdDU1NQcm9wZXJ0eShldmVudC5wcm9wZXJ0eU5hbWUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gdmlld3BvcnRPblNjcm9sbChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zbGVlcGluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbFN0b3BUaW1lb3V0SWQgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsU3RvcFRpbWVvdXRJZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZSh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25TY3JvbGxTdGFydCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lmIGEgc2Nyb2xsYmFycyBoYW5kbGUgZ2V0cyBkcmFnZ2VkLCB0aGUgbW91c2Vtb3ZlIGV2ZW50IGlzIHJlc3BvbnNpYmxlIGZvciByZWZyZXNoaW5nIHRoZSBoYW5kbGUgb2Zmc2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2JlY2F1c2UgaWYgQ1NTIHNjcm9sbC1zbmFwIGlzIHVzZWQsIHRoZSBoYW5kbGUgb2Zmc2V0IGdldHMgb25seSByZWZyZXNoZWQgb24gZXZlcnkgc25hcCBwb2ludFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIGxvb2tzIGxhZ2d5ICYgY2x1bmt5LCBpdCBsb29rcyBtdWNoIGJldHRlciBpZiB0aGUgb2Zmc2V0IHJlZnJlc2hlcyB3aXRoIHRoZSBtb3VzZW1vdmVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsJywgZXZlbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFN0b3BUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9PblNjcm9sbFN0b3A6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChzY3JvbGxTdG9wVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsU3RvcFRpbWVvdXRJZCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5hdGl2ZU92ZXJsYXlTY3JvbGxiYXJzQXJlQWN0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0U2Nyb2xsaW5nKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soJ29uU2Nyb2xsU3RvcCcsIGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBzY3JvbGxTdG9wRGVsYXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1RleHRhcmVhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gPiA5IHx8ICFfYXV0b1VwZGF0ZVJlY29tbWVuZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCwgJ2lucHV0JywgdXBkYXRlVGV4dGFyZWEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3RhcmdldEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJLZXlEb3duRXZlbnQsIF9zdHJLZXlVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdGV4dGFyZWFPbktleURvd24sIHRleHRhcmVhT25LZXlVcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihfdGFyZ2V0RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2Nyb2xsLCAnZHJvcCcsIHN0ckZvY3VzLCBzdHJGb2N1cyArICdvdXQnXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0ZXh0YXJlYU9uU2Nyb2xsLCB0ZXh0YXJlYU9uRHJvcCwgdGV4dGFyZWFPbkZvY3VzLCB0ZXh0YXJlYU9uRm9jdXNvdXRdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF9jb250ZW50RWxlbWVudCwgX3N0clRyYW5zaXRpb25FbmRFdmVudCwgY29udGVudE9uVHJhbnNpdGlvbkVuZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJTY3JvbGwsIHZpZXdwb3J0T25TY3JvbGwsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFycyA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyBhbGwgc2Nyb2xsYmFyIERPTSBlbGVtZW50cyAoc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlc3Ryb3kgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIERPTSBzaGFsbCBiZSBidWlsZCBvciBkZXN0cm95ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldHVwU2Nyb2xsYmFyc0RPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00gPSBmdW5jdGlvbiAoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJDbGFzc05hbWUgPSBpc0hvcml6b250YWwgPyBfY2xhc3NOYW1lU2Nyb2xsYmFySG9yaXpvbnRhbCA6IF9jbGFzc05hbWVTY3JvbGxiYXJWZXJ0aWNhbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhciA9IHNlbGVjdE9yR2VuZXJhdGVEaXZCeUNsYXNzKF9jbGFzc05hbWVTY3JvbGxiYXIgKyBfc3RyU3BhY2UgKyBzY3JvbGxiYXJDbGFzc05hbWUsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyVHJhY2ssIHNjcm9sbGJhcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFySGFuZGxlLCBzY3JvbGxiYXIpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZG9tRXhpc3RzICYmICFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXIuYXBwZW5kKHRyYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmFwcGVuZChoYW5kbGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogc2Nyb2xsYmFyLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiB0cmFjayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9oYW5kbGU6IGhhbmRsZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsYmFyID0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2sgPSBzY3JvbGxiYXJWYXJzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZSA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChbc2Nyb2xsYmFyLCB0cmFjaywgaGFuZGxlXSwgZnVuY3Rpb24gKGksIGVsbSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKGVsbS5yZW1vdmVBdHRyKExFWElDT04ucyksIF9jbGFzc05hbWVzRHluYW1pY0Rlc3Ryb3kpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoc2Nyb2xsYmFyIHx8IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oaXNIb3Jpem9udGFsKS5fc2Nyb2xsYmFyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaG9yaXpvbnRhbEVsZW1lbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2ZXJ0aWNhbEVsZW1lbnRzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc3Ryb3kpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9yaXpvbnRhbEVsZW1lbnRzID0gc2VsZWN0T3JHZW5lcmF0ZVNjcm9sbGJhckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljYWxFbGVtZW50cyA9IHNlbGVjdE9yR2VuZXJhdGVTY3JvbGxiYXJET00oKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5fdHJhY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudCA9IGhvcml6b250YWxFbGVtZW50cy5faGFuZGxlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50ID0gdmVydGljYWxFbGVtZW50cy5fc2Nyb2xsYmFyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyVmVydGljYWxUcmFja0VsZW1lbnQgPSB2ZXJ0aWNhbEVsZW1lbnRzLl90cmFjaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCA9IHZlcnRpY2FsRWxlbWVudHMuX2hhbmRsZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhZGRpbmdFbGVtZW50LmFmdGVyKF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc2V0U2Nyb2xsYmFyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNldFNjcm9sbGJhckRPTSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGFsbCBzY3JvbGxiYXIgaW50ZXJhY3Rpdml0eSBldmVudHMuICh0cmFjayBhbmQgaGFuZGxlIGRyYWdnaW5nLCBjbGlja2luZywgc2Nyb2xsaW5nKVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGlzSG9yaXpvbnRhbCBUcnVlIGlmIHRoZSB0YXJnZXQgc2Nyb2xsYmFyIGlzIHRoZSBob3Jpem9udGFsIHNjcm9sbGJhciwgZmFsc2UgaWYgdGhlIHRhcmdldCBzY3JvbGxiYXIgaXMgdGhlIHZlcnRpY2FsIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJFdmVudHMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnMgPSBnZXRTY3JvbGxiYXJWYXJzKGlzSG9yaXpvbnRhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhclZhcnNJbmZvID0gc2Nyb2xsYmFyVmFycy5faW5mbztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zaWRlSUZyYW1lID0gX3dpbmRvd0VsZW1lbnROYXRpdmUudG9wICE9PSBfd2luZG93RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSBzY3JvbGxiYXJWYXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIFhZID0gc2Nyb2xsYmFyVmFycy5fWF9ZO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBfc3RyU2Nyb2xsICsgc2Nyb2xsYmFyVmFycy5fTGVmdF9Ub3A7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ckFjdGl2ZSA9ICdhY3RpdmUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJTbmFwSGFuZGxlID0gJ3NuYXBIYW5kbGUnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDbGlja0V2ZW50ID0gJ2NsaWNrJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmNyZWFzZURlY3JlYXNlU2Nyb2xsQW1vdW50S2V5Q29kZXMgPSBbMTYsIDE3XTsgLy9zaGlmdCwgY3RybFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja1RpbWVvdXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZURvd25JbnZlcnRlZFNjYWxlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQb2ludGVyUG9zaXRpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9tc2llVmVyc2lvbiAmJiBpbnNpZGVJRnJhbWUgPyBldmVudFsnc2NyZWVuJyArIFhZXSA6IENPTVBBVElCSUxJVFkucGFnZShldmVudClbeHldOyAvL3VzZSBzY3JlZW4gY29vcmRpbmF0ZXMgaW4gRURHRSAmIElFIGJlY2F1c2UgdGhlIHBhZ2UgdmFsdWVzIGFyZSBpbmNvcnJlY3QgaW4gZnJhbWVzLlxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24obmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMuc2Nyb2xsYmFyc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsRHVyYXRpb25GYWN0b3IgPSAwLjU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbER1cmF0aW9uRmFjdG9yID0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbihldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleURvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluQXJyYXkoZXZlbnQua2V5Q29kZSwgaW5jcmVhc2VEZWNyZWFzZVNjcm9sbEFtb3VudEtleUNvZGVzKSA+IC0xKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudEtleVVwKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbkFycmF5KGV2ZW50LmtleUNvZGUsIGluY3JlYXNlRGVjcmVhc2VTY3JvbGxBbW91bnRLZXlDb2RlcykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25Nb3VzZVRvdWNoRG93bkNvbnRpbnVlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudCB8fCBldmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzVG91Y2hFdmVudCA9IG9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3NsZWVwaW5nIHx8IF9kZXN0cm95ZWQgfHwgbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB8fCAhX3Njcm9sbGJhcnNEcmFnU2Nyb2xsaW5nQ2FjaGUgfHwgKGlzVG91Y2hFdmVudCAmJiAhZ2V0UHJlcGFyZWRTY3JvbGxiYXJzT3B0aW9uKCd0b3VjaFN1cHBvcnQnKSkgPyBmYWxzZSA6IENPTVBBVElCSUxJVFkubUJ0bihldmVudCkgPT09IDEgfHwgaXNUb3VjaEV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhY2tMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5fdHJhY2tMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlTGVuZ3RoID0gc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF3ID0gKGdldFBvaW50ZXJQb3NpdGlvbihldmVudCkgLSBtb3VzZURvd25PZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEZWx0YVBlcmNlbnQgPSBzY3JvbGxSYXcgLyAodHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbERlbHRhID0gKHNjcm9sbFJhbmdlICogc2Nyb2xsRGVsdGFQZXJjZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhID0gaXNGaW5pdGUoc2Nyb2xsRGVsdGEpID8gc2Nyb2xsRGVsdGEgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbERlbHRhICo9IC0xO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbc2Nyb2xsXShNQVRILnJvdW5kKG1vdXNlRG93blNjcm9sbCArIHNjcm9sbERlbHRhKSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgbW91c2VEb3duU2Nyb2xsICsgc2Nyb2xsRGVsdGEpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3N1cHBvcnRQYXNzaXZlRXZlbnRzKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRNb3VzZVRvdWNoVXAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudCA9IGV2ZW50IHx8IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0cktleURvd25FdmVudCwgX3N0cktleVVwRXZlbnQsIF9zdHJTZWxlY3RTdGFydEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudERyYWdNb3ZlLCBkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuckFGKCkoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsIHN0ckNsaWNrRXZlbnQsIHN0b3BDbGlja0V2ZW50UHJvcGFnYXRpb24sIHRydWUsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVDbGFzcyhzY3JvbGxiYXJWYXJzLl90cmFjaywgc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25PZmZzZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93bkludmVydGVkU2NhbGUgPSAxO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZGVjcmVhc2VUcmFja1Njcm9sbEFtb3VudCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrVGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVjdCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLmJDUl0oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb3VzZUluc2lkZUhvc3QgPSBldmVudC5jbGllbnRYID49IHJlY3QubGVmdCAmJiBldmVudC5jbGllbnRYIDw9IHJlY3QucmlnaHQgJiYgZXZlbnQuY2xpZW50WSA+PSByZWN0LnRvcCAmJiBldmVudC5jbGllbnRZIDw9IHJlY3QuYm90dG9tO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYgbW91c2UgaXMgb3V0c2lkZSBob3N0IGVsZW1lbnRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbW91c2VJbnNpZGVIb3N0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RPbk1vdXNlTGVhdmUoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFyc0F1dG9IaWRlKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbkhhbmRsZU1vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25IYW5kbGVNb3VzZVRvdWNoRG93bkFjdGlvbihldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uSGFuZGxlTW91c2VUb3VjaERvd25BY3Rpb24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2Nyb2xsID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IGlzTmFOKG1vdXNlRG93blNjcm9sbCkgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLm4gfHwgIV9pc1JUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNjcm9sbCA9IG1vdXNlRG93blNjcm9sbCA8IDAgPyAwIDogbW91c2VEb3duU2Nyb2xsO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IGdldEhvc3RFbGVtZW50SW52ZXJ0ZWRTY2FsZSgpW3h5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gZ2V0UG9pbnRlclBvc2l0aW9uKGV2ZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzSGFuZGxlc0RlZmluZVNjcm9sbFBvcyA9ICFnZXRQcmVwYXJlZFNjcm9sbGJhcnNPcHRpb24oc3RyU25hcEhhbmRsZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5faGFuZGxlLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIHN0ckFjdGl2ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF9kb2N1bWVudEVsZW1lbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5yQUYoKShmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCwgc3RyQ2xpY2tFdmVudCwgc3RvcENsaWNrRXZlbnRQcm9wYWdhdGlvbiwgZmFsc2UsIHsgX2NhcHR1cmU6IHRydWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXNpZVZlcnNpb24gfHwgIV9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gb25UcmFja01vdXNlVG91Y2hEb3duKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVG9WaWV3cG9ydFJhdGlvID0gc2Nyb2xsYmFyVmFycy5faW5mby5faGFuZGxlTGVuZ3RoIC8gTWF0aC5yb3VuZChNQVRILm1pbigxLCBfdmlld3BvcnRTaXplW3Njcm9sbGJhclZhcnMuX3dfaF0gLyBfY29udGVudFNjcm9sbFNpemVDYWNoZVtzY3JvbGxiYXJWYXJzLl93X2hdKSAqIHNjcm9sbGJhclZhcnMuX2luZm8uX3RyYWNrTGVuZ3RoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEaXN0YW5jZSA9IE1BVEgucm91bmQoX3ZpZXdwb3J0U2l6ZVtzY3JvbGxiYXJWYXJzLl93X2hdICogaGFuZGxlVG9WaWV3cG9ydFJhdGlvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxCYXNlRHVyYXRpb24gPSAyNzAgKiBoYW5kbGVUb1ZpZXdwb3J0UmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsRmlyc3RJdGVyYXRpb25EZWxheSA9IDQwMCAqIGhhbmRsZVRvVmlld3BvcnRSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja09mZnNldCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrLm9mZnNldCgpW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdHJsS2V5ID0gZXZlbnQuY3RybEtleTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW50U2Nyb2xsID0gZXZlbnQuc2hpZnRLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFRyYW5zaXRpb24gPSBpbnN0YW50U2Nyb2xsICYmIGN0cmxLZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNGaXJzdEl0ZXJhdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZWFzaW5nID0gJ2xpbmVhcic7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZmluaXNoZWRDb25kaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uRmluc2lzaGVkID0gZnVuY3Rpb24gKHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoU2Nyb2xsYmFySGFuZGxlT2Zmc2V0KGlzSG9yaXpvbnRhbCwgdHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEFjdGlvbkluc3RhbnRGaW5pc2hlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb25GaW5zaXNoZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkhhbmRsZU1vdXNlVG91Y2hEb3duQWN0aW9uKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsQWN0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VPZmZzZXQgPSAobW91c2VEb3duT2Zmc2V0IC0gdHJhY2tPZmZzZXQpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZU9mZnNldCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxSYW5nZSA9IHNjcm9sbGJhclZhcnNJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyU2Nyb2xsID0gc2Nyb2xsYmFyVmFyc0luZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxEdXJhdGlvbiA9IHNjcm9sbEJhc2VEdXJhdGlvbiAqIHNjcm9sbER1cmF0aW9uRmFjdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdGltZW91dERlbGF5ID0gaXNGaXJzdEl0ZXJhdGlvbiA/IE1BVEgubWF4KHNjcm9sbEZpcnN0SXRlcmF0aW9uRGVsYXksIHNjcm9sbER1cmF0aW9uKSA6IHNjcm9sbER1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gc2Nyb2xsUmFuZ2UgKiAoKG1vdXNlT2Zmc2V0IC0gKGhhbmRsZUxlbmd0aCAvIDIpKSAvICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCkpOyAvLyAxMDAlICogcG9zaXRpb25QZXJjZW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBydGxJc05vcm1hbCA9IF9pc1JUTCAmJiBpc0hvcml6b250YWwgJiYgKCghX3J0bFNjcm9sbEJlaGF2aW9yLmkgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5uKSB8fCBfbm9ybWFsaXplUlRMQ2FjaGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcmVhc2VTY3JvbGxDb25kaXRpb24gPSBydGxJc05vcm1hbCA/IGhhbmRsZU9mZnNldCA8IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ID4gbW91c2VPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFuaW1hdGlvbk9iaiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVhc2luZzogZWFzaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcDogZnVuY3Rpb24gKG5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0hhbmRsZXNEZWZpbmVTY3JvbGxQb3MpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKG5vdyk7IC8vaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvaXNzdWVzLzQzNDBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIG5vdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBpc0Zpbml0ZShpbnN0YW50U2Nyb2xsUG9zaXRpb24pID8gaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX2lzUlRMICYmIGlzSG9yaXpvbnRhbCAmJiAhX3J0bFNjcm9sbEJlaGF2aW9yLmkgPyAoc2Nyb2xsUmFuZ2UgLSBpbnN0YW50U2Nyb2xsUG9zaXRpb24pIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9fYmFzZS5zY3JvbGxTdG9wKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFudFNjcm9sbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGluc3RhbnRTY3JvbGxQb3NpdGlvbik7IC8vc2Nyb2xsIGluc3RhbnRseSB0byBuZXcgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW50U2Nyb2xsVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZ2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gYWZ0ZXIgaW5zdGFudCBzY3JvbGwgKGluIGNhc2UgQ1NTIFNuYXAgUG9pbnRzIGFyZSB1c2VkKSB0byBnZXQgdGhlIGNvcnJlY3Qgc25hcHBlZCBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2FuZCB0aGUgYW5pbWF0aW9uIHN0b3BzIGF0IHRoZSBjb3JyZWN0IHBvaW50XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9zY3JvbGwgYmFjayB0byB0aGUgcG9zaXRpb24gYmVmb3JlIGluc3RhbnQgc2Nyb2xsaW5nIHNvIGFuaW1hdGlvbiBjYW4gYmUgcGVyZm9ybWVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtzY3JvbGxdKGN1cnJTY3JvbGwpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW50U2Nyb2xsUG9zaXRpb24gPSBydGxJc05vcm1hbCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaSA/IChzY3JvbGxSYW5nZSAtIGluc3RhbnRTY3JvbGxQb3NpdGlvbikgOiBpbnN0YW50U2Nyb2xsUG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFudFNjcm9sbFBvc2l0aW9uID0gcnRsSXNOb3JtYWwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gPyAtaW5zdGFudFNjcm9sbFBvc2l0aW9uIDogaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gaW5zdGFudFNjcm9sbFBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbChzY3JvbGxPYmosIGV4dGVuZERlZXAoYW5pbWF0aW9uT2JqLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAxMzAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBzY3JvbGxBY3Rpb25JbnN0YW50RmluaXNoZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsQWN0aW9uSW5zdGFudEZpbmlzaGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNyZWFzZVNjcm9sbCA9IGlzRmlyc3RJdGVyYXRpb24gPyBkZWNyZWFzZVNjcm9sbENvbmRpdGlvbiA6IGRlY3JlYXNlU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluaXNoZWRDb25kaXRpb24gPSBydGxJc05vcm1hbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKGRlY3JlYXNlU2Nyb2xsID8gaGFuZGxlT2Zmc2V0IDw9IG1vdXNlT2Zmc2V0IDogaGFuZGxlT2Zmc2V0ICsgaGFuZGxlTGVuZ3RoID49IG1vdXNlT2Zmc2V0KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluaXNoZWRDb25kaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodHJhY2tUaW1lb3V0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5zY3JvbGxTdG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tUaW1lb3V0ID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbEFjdGlvbkZpbnNpc2hlZCh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrVGltZW91dCA9IHNldFRpbWVvdXQoc2Nyb2xsQWN0aW9uLCB0aW1lb3V0RGVsYXkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxPYmpbeHldID0gKGRlY3JlYXNlU2Nyb2xsID8gJy09JyA6ICcrPScpICsgc2Nyb2xsRGlzdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2Jhc2Uuc2Nyb2xsKHNjcm9sbE9iaiwgZXh0ZW5kRGVlcChhbmltYXRpb25PYmosIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb246IHNjcm9sbER1cmF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdEl0ZXJhdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdHJsS2V5KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY3JlYXNlVHJhY2tTY3JvbGxBbW91bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKClbeHldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duT2Zmc2V0ID0gQ09NUEFUSUJJTElUWS5wYWdlKGV2ZW50KVt4eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVzRGVmaW5lU2Nyb2xsUG9zID0gIWdldFByZXBhcmVkU2Nyb2xsYmFyc09wdGlvbihzdHJTbmFwSGFuZGxlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKF9ib2R5RWxlbWVudCwgX2NsYXNzTmFtZURyYWdnaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZENsYXNzKHNjcm9sbGJhclZhcnMuX3RyYWNrLCBzdHJBY3RpdmUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkQ2xhc3Moc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyLCBzdHJBY3RpdmUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHVwUmVzcG9uc2l2ZUV2ZW50TGlzdGVuZXIoX2RvY3VtZW50RWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hVcEV2ZW50LCBfc3RyS2V5RG93bkV2ZW50LCBfc3RyS2V5VXBFdmVudCwgX3N0clNlbGVjdFN0YXJ0RXZlbnRdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE1vdXNlVG91Y2hVcCwgZG9jdW1lbnRLZXlEb3duLCBkb2N1bWVudEtleVVwLCBkb2N1bWVudE9uU2VsZWN0U3RhcnRdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxBY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkucHJ2RChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT01QQVRJQklMSVRZLnN0cFAoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9tYWtlIHN1cmUgYm90aCBzY3JvbGxiYXJzIHdpbGwgc3RheSB2aXNpYmxlIGlmIG9uZSBzY3JvbGxiYXIgaXMgaG92ZXJlZCBpZiBhdXRvSGlkZSBpcyBcInNjcm9sbFwiIG9yIFwibW92ZVwiLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyc0hhbmRsZUhvdmVyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcnNIYW5kbGVIb3ZlcmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlU2Nyb2xsIHx8IF9zY3JvbGxiYXJzQXV0b0hpZGVNb3ZlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaFNjcm9sbGJhcnNBdXRvSGlkZShmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIG9uU2Nyb2xsYmFyTW91c2VUb3VjaERvd24oZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX2hhbmRsZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uSGFuZGxlTW91c2VUb3VjaERvd24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZERlc3Ryb3lFdmVudExpc3RlbmVyKHNjcm9sbGJhclZhcnMuX3RyYWNrLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbX3N0ck1vdXNlVG91Y2hEb3duRXZlbnQsIF9zdHJNb3VzZUVudGVyLCBfc3RyTW91c2VMZWF2ZV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtvblRyYWNrTW91c2VUb3VjaERvd24sIG9uVHJhY2tNb3VzZVRvdWNoRW50ZXIsIG9uVHJhY2tNb3VzZVRvdWNoTGVhdmVdKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvblNjcm9sbGJhck1vdXNlVG91Y2hEb3duKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9zdXBwb3J0VHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGREZXN0cm95RXZlbnRMaXN0ZW5lcihzY3JvbGxiYXJWYXJzLl9zY3JvbGxiYXIsIF9zdHJUcmFuc2l0aW9uRW5kRXZlbnQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnRhcmdldCAhPT0gc2Nyb2xsYmFyVmFycy5fc2Nyb2xsYmFyWzBdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoaXNIb3Jpem9udGFsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2hvd3Mgb3IgaGlkZXMgdGhlIGdpdmVuIHNjcm9sbGJhciBhbmQgYXBwbGllZCBhIGNsYXNzIG5hbWUgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBzY3JvbGxiYXIgaXMgc2Nyb2xsYWJsZSBvciBub3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIGlzIHRoZSB0YXJnZXQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgaXMgdGhlIHRhcmdldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzaGFsbEJlVmlzaWJsZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXIgc2hhbGwgYmUgc2hvd24sIGZhbHNlIGlmIGhpZGRlbi5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjYW5TY3JvbGwgVHJ1ZSBpZiB0aGUgc2Nyb2xsYmFyIGlzIHNjcm9sbGFibGUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckFwcGVhcmFuY2UoaXNIb3Jpem9udGFsLCBzaGFsbEJlVmlzaWJsZSwgY2FuU2Nyb2xsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSA9IGlzSG9yaXpvbnRhbCA/IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFySG9yaXpvbnRhbEhpZGRlbiA6IF9jbGFzc05hbWVIb3N0U2Nyb2xsYmFyVmVydGljYWxIaWRkZW47XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbGJhckVsZW1lbnQgPSBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQgOiBfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhfaG9zdEVsZW1lbnQsIHNjcm9sbGJhckhpZGRlbkNsYXNzTmFtZSwgIXNoYWxsQmVWaXNpYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICBhZGRSZW1vdmVDbGFzcyhzY3JvbGxiYXJFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyVW51c2FibGUsICFjYW5TY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQXV0b3Nob3dzIC8gYXV0b2hpZGVzIGJvdGggc2Nyb2xsYmFycyB3aXRoLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHNoYWxsQmVWaXNpYmxlIFRydWUgaWYgdGhlIHNjcm9sbGJhcnMgc2hhbGwgYmUgYXV0b3Nob3duIChvbmx5IHRoZSBjYXNlIGlmIHRoZXkgYXJlIGhpZGRlbiBieSBhIGF1dG9oaWRlKSwgZmFsc2UgaWYgdGhlIHNoYWxsIGJlIGF1dG8gaGlkZGVuLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlbGF5ZnJlZSBUcnVlIGlmIHRoZSBzY3JvbGxiYXJzIHNoYWxsIGJlIGhpZGRlbiB3aXRob3V0IGEgZGVsYXksIGZhbHNlIG9yIHVuZGVmaW5lZCBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJzQXV0b0hpZGUoc2hhbGxCZVZpc2libGUsIGRlbGF5ZnJlZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChfc2Nyb2xsYmFyc0F1dG9IaWRlVGltZW91dElkKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoc2hhbGxCZVZpc2libGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9pZihfaGFzT3ZlcmZsb3dDYWNoZS54ICYmIF9oaWRlT3ZlcmZsb3dDYWNoZS54cylcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vaWYoX2hhc092ZXJmbG93Q2FjaGUueSAmJiBfaGlkZU92ZXJmbG93Q2FjaGUueXMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzKF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhbnlBY3RpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdHJBY3RpdmUgPSAnYWN0aXZlJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhpZGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9zY3JvbGxiYXJzSGFuZGxlSG92ZXJlZCAmJiAhX2Rlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueUFjdGl2ZSA9IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudC5oYXNDbGFzcyhzdHJBY3RpdmUpIHx8IF9zY3JvbGxiYXJWZXJ0aWNhbEhhbmRsZUVsZW1lbnQuaGFzQ2xhc3Moc3RyQWN0aXZlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFySG9yaXpvbnRhbEVsZW1lbnQsIF9jbGFzc05hbWVTY3JvbGxiYXJBdXRvSGlkZGVuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFueUFjdGl2ZSAmJiAoX3Njcm9sbGJhcnNBdXRvSGlkZVNjcm9sbCB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTW92ZSB8fCBfc2Nyb2xsYmFyc0F1dG9IaWRlTGVhdmUpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfc2Nyb2xsYmFyVmVydGljYWxFbGVtZW50LCBfY2xhc3NOYW1lU2Nyb2xsYmFyQXV0b0hpZGRlbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc2Nyb2xsYmFyc0F1dG9IaWRlRGVsYXkgPiAwICYmIGRlbGF5ZnJlZSAhPT0gdHJ1ZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zY3JvbGxiYXJzQXV0b0hpZGVUaW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhpZGUsIF9zY3JvbGxiYXJzQXV0b0hpZGVEZWxheSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBsZW5ndGggb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVMZW5ndGgoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZ2l0ID0gMTAwMDAwMDtcclxuICAgICAgICAgICAgICAgICAgICAvL2dldCBhbmQgYXBwbHkgaW50ZW5kZWQgaGFuZGxlIGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVSYXRpbyA9IE1BVEgubWluKDEsIF92aWV3cG9ydFNpemVbc2Nyb2xsYmFyVmFycy5fd19oXSAvIF9jb250ZW50U2Nyb2xsU2l6ZUNhY2hlW3Njcm9sbGJhclZhcnMuX3dfaF0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZUNTU1tzY3JvbGxiYXJWYXJzLl93aWR0aF9oZWlnaHRdID0gKE1BVEguZmxvb3IoaGFuZGxlUmF0aW8gKiAxMDAgKiBkaWdpdCkgLyBkaWdpdCkgKyAnJSc7IC8vdGhlIGxhc3QgKiBkaWdpdCAvIGRpZ2l0IGlzIGZvciBmbG9vcmluZyB0byB0aGUgNHRoIGRpZ2l0XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhoYW5kbGVDU1MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL21lYXN1cmUgdGhlIGhhbmRsZSBsZW5ndGggdG8gcmVzcGVjdCBtaW4gJiBtYXggbGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aCA9IHNjcm9sbGJhclZhcnMuX2hhbmRsZVswXVsnb2Zmc2V0JyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF07XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX2hhbmRsZUxlbmd0aFJhdGlvID0gaGFuZGxlUmF0aW87XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZWZyZXNoZXMgdGhlIGhhbmRsZSBvZmZzZXQgb2YgdGhlIGdpdmVuIHNjcm9sbGJhci5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc0hvcml6b250YWwgVHJ1ZSBpZiB0aGUgaG9yaXpvbnRhbCBzY3JvbGxiYXIgaGFuZGxlIHNoYWxsIGJlIHJlZnJlc2hlZCwgZmFsc2UgaWYgdGhlIHZlcnRpY2FsIG9uZSBzaGFsbCBiZSByZWZyZXNoZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2Nyb2xsT3JUcmFuc2l0aW9uIFRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIGdpdmVuIHNjcm9sbGJhciBheGlzIHRvIHdoaWNoIHRoZSBoYW5kbGUgc2hhbGwgYmUgbW92ZWQgb3IgYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIGEgdHJhbnNpdGlvbiBzaGFsbCBiZSBhcHBsaWVkLiBJZiB1bmRlZmluZWQgb3IgYm9vbGVhbiBpZiB0aGUgY3VycmVudCBzY3JvbGwtb2Zmc2V0IGlzIHRha2VuLiAoaWYgaXNIb3Jpem9udGFsID8gc2Nyb2xsTGVmdCA6IHNjcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhckhhbmRsZU9mZnNldChpc0hvcml6b250YWwsIHNjcm9sbE9yVHJhbnNpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uID0gdHlwZShzY3JvbGxPclRyYW5zaXRpb24pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zaXRpb25EdXJhdGlvbiA9IDI1MDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc0hvcml6b250YWwgPSBfaXNSVEwgJiYgaXNIb3Jpem9udGFsO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc0hvcml6b250YWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxiYXJWYXJzSW5mbyA9IHNjcm9sbGJhclZhcnMuX2luZm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zbGF0ZUJyYWNlID0gJ3RyYW5zbGF0ZSgnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJUcmFuc2Zvcm0gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNmb3JtJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0clRyYW5zaXRpb24gPSBWRU5ET1JTLl9jc3NQcm9wZXJ0eSgndHJhbnNpdGlvbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuYXRpdmVTY3JvbGwgPSBpc0hvcml6b250YWwgPyBfdmlld3BvcnRFbGVtZW50W19zdHJTY3JvbGxMZWZ0XSgpIDogX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsVG9wXSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJyZW50U2Nyb2xsID0gc2Nyb2xsT3JUcmFuc2l0aW9uID09PSB1bmRlZmluZWQgfHwgdHJhbnNpdGlvbiA/IG5hdGl2ZVNjcm9sbCA6IHNjcm9sbE9yVHJhbnNpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9tZWFzdXJlIHRoZSBoYW5kbGUgbGVuZ3RoIHRvIHJlc3BlY3QgbWluICYgbWF4IGxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVMZW5ndGggPSBzY3JvbGxiYXJWYXJzSW5mby5faGFuZGxlTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFja0xlbmd0aCA9IHNjcm9sbGJhclZhcnMuX3RyYWNrWzBdWydvZmZzZXQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaGFuZGxlVHJhY2tEaWZmID0gdHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhhbmRsZUNTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2Zvcm1PZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL0RPTlQgdXNlIHRoZSB2YXJpYWJsZSAnX2NvbnRlbnRTY3JvbGxTaXplQ2FjaGVbc2Nyb2xsYmFyVmFycy5fd19oXScgaW5zdGVhZCBvZiAnX3ZpZXdwb3J0RWxlbWVudFswXVsnc2Nyb2xsJyArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0nXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYSBiaXQgYmVoaW5kIGR1cmluZyB0aGUgc21hbGwgZGVsYXkgd2hlbiBjb250ZW50IHNpemUgdXBkYXRlc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vKGRlbGF5ID0gbXV0YXRpb25PYnNlcnZlckNvbnRlbnRMYWcsIGlmIGl0cyAwIHRoZW4gdGhpcyB2YXIgY291bGQgYmUgdXNlZClcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWF4U2Nyb2xsID0gKF92aWV3cG9ydEVsZW1lbnROYXRpdmVbX3N0clNjcm9sbCArIHNjcm9sbGJhclZhcnMuX1dpZHRoX0hlaWdodF0gLSBfdmlld3BvcnRFbGVtZW50TmF0aXZlWydjbGllbnQnICsgc2Nyb2xsYmFyVmFycy5fV2lkdGhfSGVpZ2h0XSkgKiAoX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgaXNSVExpc0hvcml6b250YWwgPyAtMSA6IDEpOyAvLyogLTEgaWYgcnRsIHNjcm9sbCBtYXggaXMgbmVnYXRpdmVcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZ2V0U2Nyb2xsUmF0aW8gPSBmdW5jdGlvbiAoYmFzZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXNOYU4oYmFzZSAvIG1heFNjcm9sbCkgPyAwIDogTUFUSC5tYXgoMCwgTUFUSC5taW4oMSwgYmFzZSAvIG1heFNjcm9sbCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGdldEhhbmRsZU9mZnNldCA9IGZ1bmN0aW9uIChzY3JvbGxSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gaGFuZGxlVHJhY2tEaWZmICogc2Nyb2xsUmF0aW87XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IGlzTmFOKG9mZnNldCkgPyAwIDogb2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAoaXNSVExpc0hvcml6b250YWwgJiYgIV9ydGxTY3JvbGxCZWhhdmlvci5pKSA/ICh0cmFja0xlbmd0aCAtIGhhbmRsZUxlbmd0aCAtIG9mZnNldCkgOiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IE1BVEgubWF4KDAsIG9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsUmF0aW8gPSBnZXRTY3JvbGxSYXRpbyhuYXRpdmVTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1bnNuYXBwZWRTY3JvbGxSYXRpbyA9IGdldFNjcm9sbFJhdGlvKGN1cnJlbnRTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGVPZmZzZXQgPSBnZXRIYW5kbGVPZmZzZXQodW5zbmFwcGVkU2Nyb2xsUmF0aW8pO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzbmFwcGVkSGFuZGxlT2Zmc2V0ID0gZ2V0SGFuZGxlT2Zmc2V0KHNjcm9sbFJhdGlvKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX21heFNjcm9sbCA9IG1heFNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbCA9IG5hdGl2ZVNjcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJWYXJzSW5mby5fY3VycmVudFNjcm9sbFJhdGlvID0gc2Nyb2xsUmF0aW87XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zZm9ybSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm1PZmZzZXQgPSBpc1JUTGlzSG9yaXpvbnRhbCA/IC0odHJhY2tMZW5ndGggLSBoYW5kbGVMZW5ndGggLSBoYW5kbGVPZmZzZXQpIDogaGFuZGxlT2Zmc2V0OyAvL2luIHB4XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdHJhbnNmb3JtT2Zmc2V0ID0gKHRyYW5zZm9ybU9mZnNldCAvIHRyYWNrTGVuZ3RoICogMTAwKSAqICh0cmFja0xlbmd0aCAvIGhhbmRsZUxlbmd0aCk7IC8vaW4gJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGVWYWx1ZSA9IGlzSG9yaXpvbnRhbCA/IHN0clRyYW5zbGF0ZUJyYWNlICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4LCAwKScgOiBzdHJUcmFuc2xhdGVCcmFjZSArICcwLCAnICsgdHJhbnNmb3JtT2Zmc2V0ICsgJ3B4KSc7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNmb3JtXSA9IHRyYW5zbGF0ZVZhbHVlO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9hcHBseSBvciBjbGVhciB1cCB0cmFuc2l0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDU1Nbc3RyVHJhbnNpdGlvbl0gPSB0cmFuc2l0aW9uICYmIE1BVEguYWJzKGhhbmRsZU9mZnNldCAtIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQpID4gMSA/IGdldENTU1RyYW5zaXRpb25TdHJpbmcoc2Nyb2xsYmFyVmFycy5faGFuZGxlKSArICcsICcgKyAoc3RyVHJhbnNmb3JtICsgX3N0clNwYWNlICsgdHJhbnNpdGlvbkR1cmF0aW9uICsgJ21zJykgOiBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlQ1NTW3Njcm9sbGJhclZhcnMuX2xlZnRfdG9wXSA9IGhhbmRsZU9mZnNldDtcclxuXHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vb25seSBhcHBseSBjc3MgaWYgb2Zmc2V0IGhhcyBjaGFuZ2VkIGFuZCBvdmVyZmxvdyBleGlzdHMuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuYXRpdmVPdmVybGF5U2Nyb2xsYmFyc0FyZUFjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5jc3MoaGFuZGxlQ1NTKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vY2xlYXIgdXAgdHJhbnNpdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N1cHBvcnRUcmFuc2Zvcm0gJiYgX3N1cHBvcnRUcmFuc2l0aW9uICYmIHRyYW5zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnMuX2hhbmRsZS5vbmUoX3N0clRyYW5zaXRpb25FbmRFdmVudCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFycy5faGFuZGxlLmNzcyhzdHJUcmFuc2l0aW9uLCBfc3RyRW1wdHkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl9oYW5kbGVPZmZzZXQgPSBoYW5kbGVPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgc2Nyb2xsYmFyVmFyc0luZm8uX3NuYXBwZWRIYW5kbGVPZmZzZXQgPSBzbmFwcGVkSGFuZGxlT2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZhcnNJbmZvLl90cmFja0xlbmd0aCA9IHRyYWNrTGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVmcmVzaGVzIHRoZSBpbnRlcmFjdGl2aXR5IG9mIHRoZSBnaXZlbiBzY3JvbGxiYXIgZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBpc1RyYWNrIFRydWUgaWYgdGhlIHRyYWNrIGVsZW1lbnQgaXMgdGhlIHRhcmdldCwgZmFsc2UgaWYgdGhlIGhhbmRsZSBlbGVtZW50IGlzIHRoZSB0YXJnZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWUgVHJ1ZSBmb3IgaW50ZXJhY3Rpdml0eSBmYWxzZSBmb3Igbm8gaW50ZXJhY3Rpdml0eS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcmVmcmVzaFNjcm9sbGJhcnNJbnRlcmFjdGl2ZShpc1RyYWNrLCB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb24gPSB2YWx1ZSA/ICdyZW1vdmVDbGFzcycgOiAnYWRkQ2xhc3MnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50MSA9IGlzVHJhY2sgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJIb3Jpem9udGFsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudDIgPSBpc1RyYWNrID8gX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2xhc3NOYW1lID0gaXNUcmFjayA/IF9jbGFzc05hbWVTY3JvbGxiYXJUcmFja09mZiA6IF9jbGFzc05hbWVTY3JvbGxiYXJIYW5kbGVPZmY7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQxW2FjdGlvbl0oY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50MlthY3Rpb25dKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGlzIHVzZWQgZm9yIGZhc3QgYWNjZXNzIGZvciBzcGVjaWZpYyB2YXJpYWJsZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gaXNIb3Jpem9udGFsIFRydWUgaWYgdGhlIGhvcml6b250YWwgc2Nyb2xsYmFyIHZhcnMgc2hhbGwgYmUgYWNjZXNzZWQsIGZhbHNlIGlmIHRoZSB2ZXJ0aWNhbCBzY3JvbGxiYXIgdmFycyBzaGFsbCBiZSBhY2Nlc3NlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7d2g6IHN0cmluZywgV0g6IHN0cmluZywgbHQ6IHN0cmluZywgX3doOiBzdHJpbmcsIF9sdDogc3RyaW5nLCB0OiAqLCBoOiAqLCBjOiB7fSwgczogKn19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFNjcm9sbGJhclZhcnMoaXNIb3Jpem9udGFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3dpZHRoX2hlaWdodDogaXNIb3Jpem9udGFsID8gX3N0cldpZHRoIDogX3N0ckhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1dpZHRoX0hlaWdodDogaXNIb3Jpem9udGFsID8gJ1dpZHRoJyA6ICdIZWlnaHQnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfbGVmdF90b3A6IGlzSG9yaXpvbnRhbCA/IF9zdHJMZWZ0IDogX3N0clRvcCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX0xlZnRfVG9wOiBpc0hvcml6b250YWwgPyAnTGVmdCcgOiAnVG9wJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3hfeTogaXNIb3Jpem9udGFsID8gX3N0clggOiBfc3RyWSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX1hfWTogaXNIb3Jpem9udGFsID8gJ1gnIDogJ1knLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd19oOiBpc0hvcml6b250YWwgPyAndycgOiAnaCcsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9sX3Q6IGlzSG9yaXpvbnRhbCA/ICdsJyA6ICd0JyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RyYWNrOiBpc0hvcml6b250YWwgPyBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudCA6IF9zY3JvbGxiYXJWZXJ0aWNhbFRyYWNrRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2hhbmRsZTogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsSGFuZGxlRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhcjogaXNIb3Jpem9udGFsID8gX3Njcm9sbGJhckhvcml6b250YWxFbGVtZW50IDogX3Njcm9sbGJhclZlcnRpY2FsRWxlbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgX2luZm86IGlzSG9yaXpvbnRhbCA/IF9zY3JvbGxIb3Jpem9udGFsSW5mbyA6IF9zY3JvbGxWZXJ0aWNhbEluZm9cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2Nyb2xsYmFyIENvcm5lciA9PT09Ly9cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEJ1aWxkcyBvciBkZXN0cm95cyB0aGUgc2Nyb2xsYmFyIGNvcm5lciBET00gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkZXN0cm95IEluZGljYXRlcyB3aGV0aGVyIHRoZSBET00gc2hhbGwgYmUgYnVpbGQgb3IgZGVzdHJveWVkLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXR1cFNjcm9sbGJhckNvcm5lckRPTShkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Njcm9sbGJhckNvcm5lckVsZW1lbnQgPSBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCB8fCBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhfY2xhc3NOYW1lU2Nyb2xsYmFyQ29ybmVyLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXN0cm95KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2hvc3RFbGVtZW50LmFwcGVuZChfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZG9tRXhpc3RzICYmIF9pbml0aWFsaXplZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVtb3ZlQXR0cihMRVhJQ09OLnMpLCBfY2xhc3NOYW1lc0R5bmFtaWNEZXN0cm95KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhbGwgc2Nyb2xsYmFyIGNvcm5lciBpbnRlcmFjdGl2aXR5IGV2ZW50cy5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gc2V0dXBTY3JvbGxiYXJDb3JuZXJFdmVudHMoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc2lkZUlGcmFtZSA9IF93aW5kb3dFbGVtZW50TmF0aXZlLnRvcCAhPT0gX3dpbmRvd0VsZW1lbnROYXRpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blBvc2l0aW9uID0ge307XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1vdXNlRG93blNpemUgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbW91c2VEb3duSW52ZXJ0ZWRTY2FsZSA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZWNvbm5lY3RNdXRhdGlvbk9ic2VydmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudERyYWdNb3ZlKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFnZU9mZnNldCA9IGdldENvb3JkaW5hdGVzKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBob3N0RWxlbWVudENTUyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9yZXNpemVIb3Jpem9udGFsIHx8IF9yZXNpemVCb3RoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50Q1NTW19zdHJXaWR0aF0gPSAobW91c2VEb3duU2l6ZS53ICsgKHBhZ2VPZmZzZXQueCAtIG1vdXNlRG93blBvc2l0aW9uLngpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS54KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfcmVzaXplVmVydGljYWwgfHwgX3Jlc2l6ZUJvdGgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zdEVsZW1lbnRDU1NbX3N0ckhlaWdodF0gPSAobW91c2VEb3duU2l6ZS5oICsgKHBhZ2VPZmZzZXQueSAtIG1vdXNlRG93blBvc2l0aW9uLnkpICogbW91c2VEb3duSW52ZXJ0ZWRTY2FsZS55KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0RWxlbWVudC5jc3MoaG9zdEVsZW1lbnRDU1MpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5zdHBQKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50TW91c2VUb3VjaFVwKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb2N1bWVudE1vdXNlVG91Y2hVcChldmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXZlbnRJc1RydXN0ZWQgPSBldmVudCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW19zdHJTZWxlY3RTdGFydEV2ZW50LCBfc3RyTW91c2VUb3VjaE1vdmVFdmVudCwgX3N0ck1vdXNlVG91Y2hVcEV2ZW50XSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkb2N1bWVudE9uU2VsZWN0U3RhcnQsIGRvY3VtZW50RHJhZ01vdmUsIGRvY3VtZW50TW91c2VUb3VjaFVwXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlQ2xhc3MoX2JvZHlFbGVtZW50LCBfY2xhc3NOYW1lRHJhZ2dpbmcpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQucmVsZWFzZUNhcHR1cmUpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5yZWxlYXNlQ2FwdHVyZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50SXNUcnVzdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0TXV0YXRpb25PYnNlcnZlcilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TXV0YXRpb25PYnNlcnZlcnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBvbk1vdXNlVG91Y2hEb3duQ29udGludWUoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNUb3VjaEV2ZW50ID0gb3JpZ2luYWxFdmVudC50b3VjaGVzICE9PSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfc2xlZXBpbmcgfHwgX2Rlc3Ryb3llZCA/IGZhbHNlIDogQ09NUEFUSUJJTElUWS5tQnRuKGV2ZW50KSA9PT0gMSB8fCBpc1RvdWNoRXZlbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldENvb3JkaW5hdGVzKGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfbXNpZVZlcnNpb24gJiYgaW5zaWRlSUZyYW1lID8geyB4OiBldmVudC5zY3JlZW5YLCB5OiBldmVudC5zY3JlZW5ZIH0gOiBDT01QQVRJQklMSVRZLnBhZ2UoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWRkRGVzdHJveUV2ZW50TGlzdGVuZXIoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9uTW91c2VUb3VjaERvd25Db250aW51ZShldmVudCkgJiYgIV9yZXNpemVOb25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX211dGF0aW9uT2JzZXJ2ZXJzQ29ubmVjdGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0TXV0YXRpb25PYnNlcnZlciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE11dGF0aW9uT2JzZXJ2ZXJzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duUG9zaXRpb24gPSBnZXRDb29yZGluYXRlcyhldmVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW91c2VEb3duU2l6ZS53ID0gX2hvc3RFbGVtZW50TmF0aXZlW0xFWElDT04ub1ddIC0gKCFfaXNCb3JkZXJCb3ggPyBfcGFkZGluZ1ggOiAwKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlRG93blNpemUuaCA9IF9ob3N0RWxlbWVudE5hdGl2ZVtMRVhJQ09OLm9IXSAtICghX2lzQm9yZGVyQm94ID8gX3BhZGRpbmdZIDogMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3VzZURvd25JbnZlcnRlZFNjYWxlID0gZ2V0SG9zdEVsZW1lbnRJbnZlcnRlZFNjYWxlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtfc3RyU2VsZWN0U3RhcnRFdmVudCwgX3N0ck1vdXNlVG91Y2hNb3ZlRXZlbnQsIF9zdHJNb3VzZVRvdWNoVXBFdmVudF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RvY3VtZW50T25TZWxlY3RTdGFydCwgZG9jdW1lbnREcmFnTW92ZSwgZG9jdW1lbnRNb3VzZVRvdWNoVXBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfYm9keUVsZW1lbnQsIF9jbGFzc05hbWVEcmFnZ2luZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3Njcm9sbGJhckNvcm5lckVsZW1lbnQuc2V0Q2FwdHVyZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfc2Nyb2xsYmFyQ29ybmVyRWxlbWVudC5zZXRDYXB0dXJlKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09NUEFUSUJJTElUWS5wcnZEKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkuc3RwUChldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgICAgICAgICAgLy89PT09IFV0aWxzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogQ2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIG5hbWUuIFRoZSBDb250ZXh0IG9mIHRoaXMgY2FsbGJhY2sgaXMgYWx3YXlzIF9iYXNlICh0aGlzKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgd2hpY2ggc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3Mgd2l0aCB3aGljaCB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGRlcGVuZGVudCBCb29sZWFuIHdoaWNoIGRlY2lkZXMgd2hldGhlciB0aGUgY2FsbGJhY2sgc2hhbGwgYmUgZmlyZWQsIHVuZGVmaW5lZCBpcyBsaWtlIGEgXCJ0cnVlXCIgdmFsdWUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGRpc3BhdGNoQ2FsbGJhY2sobmFtZSwgYXJncywgZGVwZW5kZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRlcGVuZGVudCA9PT0gZmFsc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2luaXRpYWxpemVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IF9jdXJyZW50UHJlcGFyZWRPcHRpb25zLmNhbGxiYWNrc1tuYW1lXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGV4dGVuc2lvbk9uTmFtZSA9IG5hbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBleHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5zaW9uT25OYW1lLnN1YnN0cigwLCAyKSA9PT0gJ29uJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk9uTmFtZSA9IGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMiwgMSkudG9Mb3dlckNhc2UoKSArIGV4dGVuc2lvbk9uTmFtZS5zdWJzdHIoMyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShjYWxsYmFjaykgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoX2Jhc2UsIGFyZ3MpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChfZXh0ZW5zaW9ucywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ID0gdGhpcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGV4dC5vbikgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQub24oZXh0ZW5zaW9uT25OYW1lLCBhcmdzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFfZGVzdHJveWVkKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY2FsbGJhY2tzSW5pdFFldWV1ZS5wdXNoKHsgbjogbmFtZSwgYTogYXJncyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgcHJvcGVydGllcywgd2l0aCBhIGdpdmVuIHByZWZpeCwgb2YgdGhlIGdpdmVuIGNzcyBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0Q1NTT2JqZWN0IFRoZSBjc3Mgb2JqZWN0IHRvIHdoaWNoIHRoZSB2YWx1ZXMgc2hhbGwgYmUgYXBwbGllZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwcmVmaXggVGhlIHByZWZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdwYWRkaW5nLScgaXMgYSB2YWxpZCBwcmVmaXgpXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsdWVzIEEgYXJyYXkgb2YgdmFsdWVzIHdoaWNoIHNoYWxsIGJlIGFwcGxpZWQgdG8gdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgLXByb3BlcnRpZXMuIFRoZSBhcnJheSBvcmRlciBpcyBbdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XS5cclxuICAgICAgICAgICAgICAgICAqIElmIHRoaXMgYXJndW1lbnQgaXMgdW5kZWZpbmVkIHRoZSB2YWx1ZSAnJyAoZW1wdHkgc3RyaW5nKSB3aWxsIGJlIGFwcGxpZWQgdG8gYWxsIHByb3BlcnRpZXMuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldFRvcFJpZ2h0Qm90dG9tTGVmdCh0YXJnZXRDU1NPYmplY3QsIHByZWZpeCwgdmFsdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gcHJlZml4IHx8IF9zdHJFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMgfHwgW19zdHJFbXB0eSwgX3N0ckVtcHR5LCBfc3RyRW1wdHksIF9zdHJFbXB0eV07XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldENTU09iamVjdFtwcmVmaXggKyBfc3RyVG9wXSA9IHZhbHVlc1swXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0clJpZ2h0XSA9IHZhbHVlc1sxXTtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRDU1NPYmplY3RbcHJlZml4ICsgX3N0ckJvdHRvbV0gPSB2YWx1ZXNbMl07XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0Q1NTT2JqZWN0W3ByZWZpeCArIF9zdHJMZWZ0XSA9IHZhbHVlc1szXTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIFwidG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XCIgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIENTUyBwcm9wZXJ0eSB3aXRoIHRoZSBnaXZlbiBwcmVmaXggZnJvbSB0aGUgaG9zdCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHByZWZpeCBUaGUgcHJlZml4IG9mIHRoZSBcInRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFwiIGNzcyBwcm9wZXJ0aWVzLiAoZXhhbXBsZTogJ3BhZGRpbmctJyBpcyBhIHZhbGlkIHByZWZpeClcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzdWZmaXggVGhlIHN1ZmZpeCBvZiB0aGUgXCJ0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcIiBjc3MgcHJvcGVydGllcy4gKGV4YW1wbGU6ICdib3JkZXItJyBpcyBhIHZhbGlkIHByZWZpeCB3aXRoICctd2lkdGgnIGlzIGEgdmFsaWQgc3VmZml4KVxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9YIFRydWUgaWYgdGhlIHggYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHplcm9ZIFRydWUgaWYgdGhlIHkgYXhpcyBzaGFsbCBiZSAwLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t9fSBUaGUgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBudW1iZXJzIG9mIHRoZSByZWFkIENTUyBwcm9wZXJ0aWVzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRUb3BSaWdodEJvdHRvbUxlZnRIb3N0KHByZWZpeCwgc3VmZml4LCB6ZXJvWCwgemVyb1kpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWZmaXggPSBzdWZmaXggfHwgX3N0ckVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeCA9IHByZWZpeCB8fCBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdDogemVyb1kgPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJUb3AgKyBzdWZmaXgpKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcjogemVyb1ggPyAwIDogcGFyc2VUb1plcm9Pck51bWJlcihfaG9zdEVsZW1lbnQuY3NzKHByZWZpeCArIF9zdHJSaWdodCArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBiOiB6ZXJvWSA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckJvdHRvbSArIHN1ZmZpeCkpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBsOiB6ZXJvWCA/IDAgOiBwYXJzZVRvWmVyb09yTnVtYmVyKF9ob3N0RWxlbWVudC5jc3MocHJlZml4ICsgX3N0ckxlZnQgKyBzdWZmaXgpKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIHRoZSBjb21wdXRlZCBDU1MgdHJhbnNpdGlvbiBzdHJpbmcgZnJvbSB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IGZyb20gd2hpY2ggdGhlIHRyYW5zaXRpb24gc3RyaW5nIHNoYWxsIGJlIHJldHVybmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIENTUyB0cmFuc2l0aW9uIHN0cmluZyBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRDU1NUcmFuc2l0aW9uU3RyaW5nKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblN0ciA9IFZFTkRPUlMuX2Nzc1Byb3BlcnR5KCd0cmFuc2l0aW9uJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFzc2VtYmxlZFZhbHVlID0gZWxlbWVudC5jc3ModHJhbnNpdGlvblN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFzc2VtYmxlZFZhbHVlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXNzZW1ibGVkVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ0V4cFN0cmluZyA9ICdcXFxccyooJyArICcoW14sKF0rKFxcXFwoLis/XFxcXCkpPykrJyArICcpW1xcXFxzLF0qJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwTWFpbiA9IG5ldyBSZWdFeHAocmVnRXhwU3RyaW5nKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVnRXhwVmFsaWRhdGUgPSBuZXcgUmVnRXhwKCdeKCcgKyByZWdFeHBTdHJpbmcgKyAnKSskJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSAncHJvcGVydHkgZHVyYXRpb24gdGltaW5nLWZ1bmN0aW9uIGRlbGF5Jy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyUmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFycmF5O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgajtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRDc3NTdHlsZUJ5Q29tbWEgPSBmdW5jdGlvbiAoc3RyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0clJlc3VsdCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXN0ci5tYXRjaChyZWdFeHBWYWxpZGF0ZSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3RyLm1hdGNoKHJlZ0V4cE1haW4pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJSZXN1bHQucHVzaChSZWdFeHAuJDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyID0gc3RyLnJlcGxhY2UocmVnRXhwTWFpbiwgX3N0ckVtcHR5KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0clJlc3VsdDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJvcGVydGllc1tMRVhJQ09OLmxdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJheSA9IHNwbGl0Q3NzU3R5bGVCeUNvbW1hKGVsZW1lbnQuY3NzKHRyYW5zaXRpb25TdHIgKyAnLScgKyBwcm9wZXJ0aWVzW2ldKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCB2YWx1ZUFycmF5W0xFWElDT04ubF07IGorKylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdFtqXSA9IChyZXN1bHRbal0gPyByZXN1bHRbal0gKyBfc3RyU3BhY2UgOiBfc3RyRW1wdHkpICsgdmFsdWVBcnJheVtqXTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5qb2luKCcsICcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogR2VuZXJhdGVzIGEgUmVndWxhciBFeHByZXNzaW9uIHdoaWNoIG1hdGNoZXMgd2l0aCBhIHN0cmluZyB3aGljaCBzdGFydHMgd2l0aCAnb3MtaG9zdCcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHdpdGhDdXJyQ2xhc3NOYW1lT3B0aW9uIFRoZSBSZWd1bGFyIEV4cHJlc3Npb24gYWxzbyBtYXRjaGVzIGlmIHRoZSBzdHJpbmcgaXMgdGhlIGN1cnJlbnQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gd2l0aE9sZENsYXNzTmFtZU9wdGlvbiBUaGUgUmVndWxhciBFeHByZXNzaW9uIGFsc28gbWF0Y2hlcyBpZiB0aGUgc3RyaW5nIGlzIHRoZSBvbGQgQ2xhc3NOYW1lIG9wdGlvbiAobXVsdGlwbGUgdmFsdWVzIHNwbGl0dGVkIGJ5IHNwYWNlIHBvc3NpYmxlKS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gY3JlYXRlSG9zdENsYXNzTmFtZVJlZ0V4cCh3aXRoQ3VyckNsYXNzTmFtZU9wdGlvbiwgd2l0aE9sZENsYXNzTmFtZU9wdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzcGxpdDtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXBwZW5kaXg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFwcGVuZENsYXNzZXMgPSBmdW5jdGlvbiAoY2xhc3NlcywgY29uZGl0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ID0gJyc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25kaXRpb24gJiYgdHlwZW9mIGNsYXNzZXMgPT0gVFlQRVMucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgPSBjbGFzc2VzLnNwbGl0KF9zdHJTcGFjZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc3BsaXRbTEVYSUNPTi5sXTsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcGVuZGl4ICs9ICd8JyArIHNwbGl0W2ldICsgJyQnO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BsaXRbaV0ucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csICdcXFxcJCYnKSBmb3IgZXNjYXBpbmcgcmVnZXggY2hhcmFjdGVyc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBlbmRpeDtcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJlZ0V4cChcclxuICAgICAgICAgICAgICAgICAgICAgICAgJyheJyArIF9jbGFzc05hbWVIb3N0RWxlbWVudCArICcoWy1fXS4rfCkkKScgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhcHBlbmRDbGFzc2VzKF9jbGFzc05hbWVDYWNoZSwgd2l0aEN1cnJDbGFzc05hbWVPcHRpb24pICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kQ2xhc3Nlcyhfb2xkQ2xhc3NOYW1lLCB3aXRoT2xkQ2xhc3NOYW1lT3B0aW9uKSwgJ2cnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENhbGN1bGF0ZXMgdGhlIGhvc3QtZWxlbWVudHMgaW52ZXJ0ZWQgc2NhbGUuIChpbnZlcnRlZFNjYWxlID0gMSAvIHNjYWxlKVxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3t4OiBudW1iZXIsIHk6IG51bWJlcn19IFRoZSBzY2FsZSBvZiB0aGUgaG9zdC1lbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRIb3N0RWxlbWVudEludmVydGVkU2NhbGUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlY3QgPSBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5iQ1JdKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgeDogX3N1cHBvcnRUcmFuc2Zvcm0gPyAxIC8gKE1BVEgucm91bmQocmVjdC53aWR0aCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vV10pIHx8IDEgOiAxLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiBfc3VwcG9ydFRyYW5zZm9ybSA/IDEgLyAoTUFUSC5yb3VuZChyZWN0LmhlaWdodCkgLyBfcGFkZGluZ0VsZW1lbnROYXRpdmVbTEVYSUNPTi5vSF0pIHx8IDEgOiAxXHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBvIFRoZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY2hlY2tlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBIVE1MRWxlbWVudCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBpc0hUTUxFbGVtZW50KG8pIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyT3duZXJEb2N1bWVudCA9ICdvd25lckRvY3VtZW50JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySFRNTEVsZW1lbnQgPSAnSFRNTEVsZW1lbnQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3bmQgPSBvICYmIG9bc3RyT3duZXJEb2N1bWVudF0gPyAob1tzdHJPd25lckRvY3VtZW50XS5wYXJlbnRXaW5kb3cgfHwgd2luZG93KSA6IHdpbmRvdztcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlb2Ygd25kW3N0ckhUTUxFbGVtZW50XSA9PSBUWVBFUy5vID8gbyBpbnN0YW5jZW9mIHduZFtzdHJIVE1MRWxlbWVudF0gOiAvL0RPTTJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8gJiYgdHlwZW9mIG8gPT0gVFlQRVMubyAmJiBvICE9PSBudWxsICYmIG8ubm9kZVR5cGUgPT09IDEgJiYgdHlwZW9mIG8ubm9kZU5hbWUgPT0gVFlQRVMuc1xyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyAyIGFycmF5cyBhbmQgcmV0dXJucyB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGVtIGFzIGEgYXJyYXkuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gYTEgVGhlIGZpcnN0IGFycmF5IHdoaWNoIHNoYWxsIGJlIGNvbXBhcmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGEyIFRoZSBzZWNvbmQgYXJyYXkgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7QXJyYXl9IFRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gYXJyYXlzLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRBcnJheURpZmZlcmVuY2VzKGExLCBhMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRpZmYgPSBbXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaztcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTEubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFbYTFbaV1dID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYTIubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFbYTJbaV1dKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGFbYTJbaV1dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhW2EyW2ldXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoayBpbiBhKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmLnB1c2goayk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpZmY7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIFplcm8gb3IgdGhlIG51bWJlciB0byB3aGljaCB0aGUgdmFsdWUgY2FuIGJlIHBhcnNlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgd2hpY2ggc2hhbGwgYmUgcGFyc2VkLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHRvRmxvYXQgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIG51bWJlciBzaGFsbCBiZSBwYXJzZWQgdG8gYSBmbG9hdC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcGFyc2VUb1plcm9Pck51bWJlcih2YWx1ZSwgdG9GbG9hdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBudW0gPSB0b0Zsb2F0ID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiBwYXJzZUludCh2YWx1ZSwgMTApO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc05hTihudW0pID8gMCA6IG51bTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgc2V2ZXJhbCBpbmZvcm1hdGlvbiBvZiB0aGUgdGV4dGFyZWEgYW5kIHJldHVybnMgdGhlbSBhcyBhIG9iamVjdCBvciB1bmRlZmluZWQgaWYgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0IGl0LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge3tjdXJzb3JSb3c6IE51bWJlciwgY3Vyc29yQ29sLCByb3dzOiBOdW1iZXIsIGNvbHM6IG51bWJlciwgd1JvdzogbnVtYmVyLCBwb3M6IG51bWJlciwgbWF4IDogbnVtYmVyfX0gb3IgdW5kZWZpbmVkIGlmIG5vdCBzdXBwb3J0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGdldFRleHRhcmVhSW5mbygpIHtcclxuICAgICAgICAgICAgICAgICAgICAvL3JlYWQgbmVlZGVkIHZhbHVlc1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUN1cnNvclBvc2l0aW9uID0gX3RhcmdldEVsZW1lbnROYXRpdmUuc2VsZWN0aW9uU3RhcnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRhcmVhQ3Vyc29yUG9zaXRpb24gPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFWYWx1ZSA9IF90YXJnZXRFbGVtZW50LnZhbCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxlbmd0aCA9IHRleHRhcmVhVmFsdWVbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGV4dGFyZWFSb3dTcGxpdCA9IHRleHRhcmVhVmFsdWUuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RSb3cgPSB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRleHRhcmVhQ3VycmVudEN1cnNvclJvd1NwbGl0ID0gdGV4dGFyZWFWYWx1ZS5zdWJzdHIoMCwgdGV4dGFyZWFDdXJzb3JQb3NpdGlvbikuc3BsaXQoJ1xcbicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWRlc3RSb3cgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB0ZXh0YXJlYUxhc3RDb2wgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JSb3cgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjdXJzb3JDb2wgPSB0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFt0ZXh0YXJlYUN1cnJlbnRDdXJzb3JSb3dTcGxpdFtMRVhJQ09OLmxdIC0gMV1bTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcm93Q29scztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9nZXQgd2lkZXN0IFJvdyBhbmQgdGhlIGxhc3QgY29sdW1uIG9mIHRoZSB0ZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0ZXh0YXJlYVJvd1NwbGl0W0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByb3dDb2xzID0gdGV4dGFyZWFSb3dTcGxpdFtpXVtMRVhJQ09OLmxdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocm93Q29scyA+IHRleHRhcmVhTGFzdENvbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkZXN0Um93ID0gaSArIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0YXJlYUxhc3RDb2wgPSByb3dDb2xzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUm93OiBjdXJzb3JSb3csIC8vY3Vyc29yUm93XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JDb2x1bW46IGN1cnNvckNvbCwgLy9jdXJzb3JDb2xcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3Jvd3M6IHRleHRhcmVhTGFzdFJvdywgLy9yb3dzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb2x1bW5zOiB0ZXh0YXJlYUxhc3RDb2wsIC8vY29sc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfd2lkZXN0Um93OiB3aWRlc3RSb3csIC8vd1Jvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfY3Vyc29yUG9zaXRpb246IHRleHRhcmVhQ3Vyc29yUG9zaXRpb24sIC8vcG9zXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jdXJzb3JNYXg6IHRleHRhcmVhTGVuZ3RoIC8vbWF4XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIERldGVybWluZXMgd2hldGhlciBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBuYXRpdmUgb3ZlcmxheSBzY3JvbGxiYXJzIGFyZSBhY3RpdmUsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gbmF0aXZlT3ZlcmxheVNjcm9sbGJhcnNBcmVBY3RpdmUoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChfaWdub3JlT3ZlcmxheVNjcm9sbGJhckhpZGluZ0NhY2hlICYmIChfbmF0aXZlU2Nyb2xsYmFySXNPdmVybGFpZC54ICYmIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnkpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdldHMgdGhlIGVsZW1lbnQgd2hpY2ggaXMgdXNlZCB0byBtZWFzdXJlIHRoZSBjb250ZW50IHNpemUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGV4dGFyZWFDb3ZlciBpZiB0YXJnZXQgZWxlbWVudCBpcyB0ZXh0YXJlYSBlbHNlIHRoZSBDb250ZW50RWxlbWVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0Q29udGVudE1lYXN1cmVFbGVtZW50KCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfaXNUZXh0YXJlYSA/IF90ZXh0YXJlYUNvdmVyRWxlbWVudFswXSA6IF9jb250ZW50RWxlbWVudE5hdGl2ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEdlbmVyYXRlcyBhIHN0cmluZyB3aGljaCByZXByZXNlbnRzIGEgSFRNTCBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3NlcyBvciBhdHRyaWJ1dGVzLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzZXNPckF0dHJzIFRoZSBjbGFzcyBvZiB0aGUgZGl2IGFzIHN0cmluZyBvciBhIG9iamVjdCB3aGljaCByZXByZXNlbnRzIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBkaXYuIChUaGUgY2xhc3MgYXR0cmlidXRlIGNhbiBhbHNvIGJlIHdyaXR0ZW4gYXMgXCJjbGFzc05hbWVcIi4pXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgY29udGVudCBvZiB0aGUgZGl2IGFzIHN0cmluZy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb25jYXRlZCBzdHJpbmcgd2hpY2ggcmVwcmVzZW50cyBhIEhUTUwgZGl2IGFuZCBpdHMgY29udGVudC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVEaXYoY2xhc3Nlc09yQXR0cnMsIGNvbnRlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxkaXYgJyArIChjbGFzc2VzT3JBdHRycyA/IHR5cGUoY2xhc3Nlc09yQXR0cnMpID09IFRZUEVTLnMgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnY2xhc3M9XCInICsgY2xhc3Nlc09yQXR0cnMgKyAnXCInIDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnMgPSBfc3RyRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoY2xhc3Nlc09yQXR0cnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChrZXkgaW4gY2xhc3Nlc09yQXR0cnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzICs9IChrZXkgPT09ICdjJyA/ICdjbGFzcycgOiBrZXkpICsgJz1cIicgKyBjbGFzc2VzT3JBdHRyc1trZXldICsgJ1wiICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYXR0cnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKCkgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc3RyRW1wdHkpICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgJz4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnRlbnQgfHwgX3N0ckVtcHR5KSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICc8L2Rpdj4nO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogU2VsZWN0cyBvciBnZW5lcmF0ZXMgYSBkaXYgd2l0aCB0aGUgZ2l2ZW4gY2xhc3MgYXR0cmlidXRlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNsYXNzTmFtZSBUaGUgY2xhc3MgbmFtZXMgKGRpdmlkZWQgYnkgc3BhY2VzKSBvZiB0aGUgZGl2IHdoaWNoIHNoYWxsIGJlIHNlbGVjdGVkIG9yIGdlbmVyYXRlZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiBUaGUgcGFyZW50IGVsZW1lbnQgZnJvbSB3aGljaCBvZiB0aGUgZWxlbWVudCBzaGFsbCBiZSBzZWxlY3RlZC4gKGlmIHVuZGVmaW5lZCBvciBib29sZWFuIGl0cyBob3N0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAqIElmIGl0cyBhIGJvb2xlYW4gaXQgZGVjaWRlcyB3aGV0aGVyIG9ubHkgdGhlIGNoaWxkcmVuIG9mIHRoZSBob3N0IGVsZW1lbnQgc2hhbGwgYmUgc2VsZWN0ZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGdlbmVyYXRlZCBvciBzZWxlY3RlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RPckdlbmVyYXRlRGl2QnlDbGFzcyhjbGFzc05hbWUsIHNlbGVjdFBhcmVudE9yT25seUNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9ubHlDaGlsZHJlbiA9IHR5cGUoc2VsZWN0UGFyZW50T3JPbmx5Q2hpbGRyZW4pID09IFRZUEVTLmI7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdFBhcmVudCA9IG9ubHlDaGlsZHJlbiA/IF9ob3N0RWxlbWVudCA6IChzZWxlY3RQYXJlbnRPck9ubHlDaGlsZHJlbiB8fCBfaG9zdEVsZW1lbnQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKF9kb21FeGlzdHMgJiYgIXNlbGVjdFBhcmVudFtMRVhJQ09OLmxdKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG51bGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfZG9tRXhpc3RzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHNlbGVjdFBhcmVudFtvbmx5Q2hpbGRyZW4gPyAnY2hpbGRyZW4nIDogJ2ZpbmQnXShfc3RyRG90ICsgY2xhc3NOYW1lLnJlcGxhY2UoL1xccy9nLCBfc3RyRG90KSkuZXEoMClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogRlJBTUVXT1JLKGdlbmVyYXRlRGl2KGNsYXNzTmFtZSkpXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIHRoZSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGZyb20gd2hpY2ggdGhlIHByb3BlcnR5IHZhbHVlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBwYXRoIFRoZSBwcm9wZXJ0eSBvZiB3aGljaCB0aGUgdmFsdWUgc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHZhbHVlIG9mIHRoZSBzZWFyY2hlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWQgb2YgdGhlIHByb3BlcnR5IHdhc24ndCBmb3VuZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0T2JqZWN0UHJvcFZhbChvYmosIHBhdGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BsaXRzID0gcGF0aC5zcGxpdChfc3RyRG90KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbDtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW9ialtMRVhJQ09OLmhPUF0oc3BsaXRzW2ldKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gb2JqW3NwbGl0c1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpIDwgc3BsaXRzLmxlbmd0aCAmJiB0eXBlKHZhbCkgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaiA9IHZhbDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNldHMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBwcm9wZXJ0eSBmcm9tIHRoZSBnaXZlbiBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgZnJvbSB3aGljaCB0aGUgcHJvcGVydHkgdmFsdWUgc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHBhdGggVGhlIHByb3BlcnR5IG9mIHdoaWNoIHRoZSB2YWx1ZSBzaGFsbCBiZSBzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdmFsIFRoZSB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgd2hpY2ggc2hhbGwgYmUgc2V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBzZXRPYmplY3RQcm9wVmFsKG9iaiwgcGF0aCwgdmFsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0cyA9IHBhdGguc3BsaXQoX3N0ckRvdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNwbGl0c0xlbmd0aCA9IHNwbGl0cy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHRlbmRPYmogPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kT2JqUm9vdCA9IGV4dGVuZE9iajtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgaSA8IHNwbGl0c0xlbmd0aDsgaSsrKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbmRPYmogPSBleHRlbmRPYmpbc3BsaXRzW2ldXSA9IGkgKyAxIDwgc3BsaXRzTGVuZ3RoID8ge30gOiB2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLmV4dGVuZChvYmosIGV4dGVuZE9ialJvb3QsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIC8qKlx0XHJcbiAgICAgICAgICAgICAgICAgKiBSdW5zIGEgYWN0aW9uIGZvciBlYWNoIHNlbGVjdG9yIGluc2lkZSB0aGUgdXBkYXRlT25Mb2FkIG9wdGlvbi5cdFxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIFRoZSBhY3Rpb24gZm9yIGVhY2ggdXBkYXRlT25Mb2FkIHNlbGVjdG9yLCB0aGUgYXJndW1lbnRzIHRoZSBmdW5jdGlvbiB0YWtlcyBpcyB0aGUgaW5kZXggYW5kIHRoZSB2YWx1ZSAodGhlIHNlbGVjdG9yKS5cdFxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBlYWNoVXBkYXRlT25Mb2FkKGFjdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVPbkxvYWQgPSBfY3VycmVudFByZXBhcmVkT3B0aW9ucy51cGRhdGVPbkxvYWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlT25Mb2FkID0gdHlwZSh1cGRhdGVPbkxvYWQpID09IFRZUEVTLnMgPyB1cGRhdGVPbkxvYWQuc3BsaXQoX3N0clNwYWNlKSA6IHVwZGF0ZU9uTG9hZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKHVwZGF0ZU9uTG9hZCkgJiYgIV9kZXN0cm95ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCh1cGRhdGVPbkxvYWQsIGFjdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gVXRpbHMgQ2FjaGUgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb21wYXJlcyB0d28gdmFsdWVzIG9yIG9iamVjdHMgYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGV5IGFyZW4ndCBlcXVhbC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBjdXJyZW50IFRoZSBmaXJzdCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY2FjaGUgVGhlIHNlY29uZCB2YWx1ZSBvciBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgY29tcGFyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgSWYgdHJ1ZSB0aGUgcmV0dXJuZWQgdmFsdWUgaXMgYWx3YXlzIHRydWUuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBib3RoIHZhbHVlcyBvciBvYmplY3RzIGFyZW4ndCBlcXVhbCBvciBmb3JjZSBpcyB0cnVlLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrQ2FjaGUoY3VycmVudCwgY2FjaGUsIGZvcmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9yY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUoY3VycmVudCkgPT0gVFlQRVMubyAmJiB0eXBlKGNhY2hlKSA9PSBUWVBFUy5vKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHByb3AgaW4gY3VycmVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3AgIT09ICdjJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50W0xFWElDT04uaE9QXShwcm9wKSAmJiBjYWNoZVtMRVhJQ09OLmhPUF0ocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoZWNrQ2FjaGUoY3VycmVudFtwcm9wXSwgY2FjaGVbcHJvcF0pKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50ICE9PSBjYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgICAgICAgICAvLz09PT0gU2hvcnRjdXRzID09PT0vL1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogalF1ZXJ5IGV4dGVuZCBtZXRob2Qgc2hvcnRjdXQgd2l0aCBhIGFwcGVuZGVkIFwidHJ1ZVwiIGFzIGZpcnN0IGFyZ3VtZW50LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBleHRlbmREZWVwKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBGUkFNRVdPUksuZXh0ZW5kLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQoW10uc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgYWRkQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBhZGRDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uYWRkQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBqUXVlcnkgcmVtb3ZlQ2xhc3MgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgY2xhc3Nlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8ucmVtb3ZlQ2xhc3MuY2FsbChlbCwgY2xhc3Nlcyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBBZGRzIG9yIHJlbW92ZXMgdGhlIGdpdmVuIGNsYXNzZXMgZGVwZW5kZW50IG9uIHRoZSBib29sZWFuIHZhbHVlLiBUcnVlIGZvciBhZGQsIGZhbHNlIGZvciByZW1vdmUuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGFkZFJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzLCBkb0FkZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb0FkZCA/IGFkZENsYXNzKGVsLCBjbGFzc2VzKSA6IHJlbW92ZUNsYXNzKGVsLCBjbGFzc2VzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIGpRdWVyeSByZW1vdmUgbWV0aG9kIHNob3J0Y3V0LlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiByZW1vdmUoZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2ZyYW1ld29ya1Byb3RvLnJlbW92ZS5jYWxsKGVsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEZpbmRzIHRoZSBmaXJzdCBjaGlsZCBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHNlbGVjdG9yIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGVsIFRoZSByb290IGVsZW1lbnQgZnJvbSB3aGljaCB0aGUgc2VsZWN0b3Igc2hhbGwgYmUgdmFsaWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIG9mIHRoZSBzZWFyY2hlZCBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMgeyp9IFRoZSBmaXJzdCBlbGVtZW50IHdoaWNoIGlzIGEgY2hpbGQgb2YgdGhlIGdpdmVuIGVsZW1lbnQgYW5kIG1hdGNoZXMgdGhlIGdpdmVucyBzZWxlY3Rvci5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gZmluZEZpcnN0KGVsLCBzZWxlY3Rvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfZnJhbWV3b3JrUHJvdG8uZmluZC5jYWxsKGVsLCBzZWxlY3RvcikuZXEoMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG5cclxuICAgICAgICAgICAgICAgIC8vPT09PSBBUEkgPT09PS8vXHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBQdXRzIHRoZSBpbnN0YW5jZSB0byBzbGVlcC4gSXQgd29udCByZXNwb25kIHRvIGFueSBjaGFuZ2VzIGluIHRoZSBET00gYW5kIHdvbid0IHVwZGF0ZS4gU2Nyb2xsYmFyIEludGVyYWN0aXZpdHkgaXMgYWxzbyBkaXNhYmxlZCBhcyB3ZWxsIGFzIHRoZSByZXNpemUgaGFuZGxlLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBiZWhhdmlvciBjYW4gYmUgcmVzZXQgYnkgY2FsbGluZyB0aGUgdXBkYXRlIG1ldGhvZC5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgX2Jhc2Uuc2xlZXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBVcGRhdGVzIHRoZSBwbHVnaW4gYW5kIERPTSB0byB0aGUgY3VycmVudCBvcHRpb25zLlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIGEgdXBkYXRlIGlzIDEwMCUgcmVxdWlyZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZm9yY2UgVHJ1ZSBpZiBldmVyeSBwcm9wZXJ0eSBzaGFsbCBiZSB1cGRhdGVkIGFuZCB0aGUgY2FjaGUgc2hhbGwgYmUgaWdub3JlZC5cclxuICAgICAgICAgICAgICAgICAqICFJTlRFUk5BTCBVU0FHRSEgOiBmb3JjZSBjYW4gYmUgYSBzdHJpbmcgXCJhdXRvXCIsIFwic3luY1wiIG9yIFwiem9vbVwiIHRvb1xyXG4gICAgICAgICAgICAgICAgICogaWYgXCJhdXRvXCIgdGhlbiBiZWZvcmUgYSByZWFsIHVwZGF0ZSB0aGUgY29udGVudCBzaXplIGFuZCBob3N0IGVsZW1lbnQgYXR0cmlidXRlcyBnZXRzIGNoZWNrZWQsIGFuZCBpZiB0aGV5IGNoYW5nZWQgb25seSB0aGVuIHRoZSB1cGRhdGUgbWV0aG9kIHdpbGwgYmUgY2FsbGVkLlxyXG4gICAgICAgICAgICAgICAgICogaWYgXCJzeW5jXCIgdGhlbiB0aGUgYXN5bmMgdXBkYXRlIHByb2Nlc3MgKE11dGF0aW9uT2JzZXJ2ZXIgb3IgVXBkYXRlTG9vcCkgZ2V0cyBzeW5jaHJvbml6ZWQgYW5kIGEgY29ycmVzcG9uZGluZyB1cGRhdGUgdGFrZXMgcGxhY2UgaWYgb25lIHdhcyBuZWVkZWQgZHVlIHRvIHBlbmRpbmcgY2hhbmdlcy5cclxuICAgICAgICAgICAgICAgICAqIGlmIFwiem9vbVwiIHRoZW4gYSB1cGRhdGUgdGFrZXMgcGxhY2Ugd2hlcmUgaXQncyBhc3N1bWVkIHRoYXQgY29udGVudCBhbmQgaG9zdCBzaXplIGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufHVuZGVmaW5lZH0gXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcInN5bmNcIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGljaCBpbmRpY2F0ZXMgd2hldGhlciBhIHVwZGF0ZSB3YXMgbmVlZGVkIGR1ZSB0byBwZW5kaW5nIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiBJZiBmb3JjZSBpcyBcImF1dG9cIiB0aGVuIGEgYm9vbGVhbiBpcyByZXR1cm5lZCB3aGV0aGVyIGEgdXBkYXRlIHdhcyBuZWVkZWQgZHVlIHRvIGF0dHJpYnV0ZSBvciBzaXplIGNoYW5nZXMuXHJcbiAgICAgICAgICAgICAgICAgKiB1bmRlZmluZWQgb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS51cGRhdGUgPSBmdW5jdGlvbiAoZm9yY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2Rlc3Ryb3llZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cnNDaGFuZ2VkO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250ZW50U2l6ZUM7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShmb3JjZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZG9VcGRhdGVBdXRvO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRIb3N0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtdXRDb250ZW50O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZvcmNlID09PSBfc3RyQXV0bykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNDaGFuZ2VkID0gbWVhbmluZ2Z1bEF0dHJzQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudFNpemVDID0gdXBkYXRlQXV0b0NvbnRlbnRTaXplQ2hhbmdlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9VcGRhdGVBdXRvID0gYXR0cnNDaGFuZ2VkIHx8IGNvbnRlbnRTaXplQztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1VwZGF0ZUF1dG8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGVudFNpemVDaGFuZ2VkOiBjb250ZW50U2l6ZUMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9jaGFuZ2VkT3B0aW9uczogX2luaXRpYWxpemVkID8gdW5kZWZpbmVkIDogX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gX3N0clN5bmMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX211dGF0aW9uT2JzZXJ2ZXJIb3N0Q2FsbGJhY2soX211dGF0aW9uT2JzZXJ2ZXJIb3N0LnRha2VSZWNvcmRzKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dENvbnRlbnQgPSBfbXV0YXRpb25PYnNlcnZlckNvbnRlbnRDYWxsYmFjayhfbXV0YXRpb25PYnNlcnZlckNvbnRlbnQudGFrZVJlY29yZHMoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRIb3N0ID0gX2Jhc2UudXBkYXRlKF9zdHJBdXRvKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChmb3JjZSA9PT0gJ3pvb20nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9ob3N0U2l6ZUNoYW5nZWQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRlbnRTaXplQ2hhbmdlZDogdHJ1ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlID0gX3NsZWVwaW5nIHx8IGZvcmNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfc2xlZXBpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfYmFzZS51cGRhdGUoX3N0clN5bmMpIHx8IGZvcmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHsgX2ZvcmNlOiBmb3JjZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUVsZW1lbnRzT25Mb2FkKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkb1VwZGF0ZUF1dG8gfHwgbXV0SG9zdCB8fCBtdXRDb250ZW50O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICBHZXRzIG9yIHNldHMgdGhlIGN1cnJlbnQgb3B0aW9ucy4gVGhlIHVwZGF0ZSBtZXRob2Qgd2lsbCBiZSBjYWxsZWQgYXV0b21hdGljYWxseSBpZiBuZXcgb3B0aW9ucyB3ZXJlIHNldC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBuZXdPcHRpb25zIElmIG5ldyBvcHRpb25zIGFyZSBnaXZlbiwgdGhlbiB0aGUgbmV3IG9wdGlvbnMgd2lsbCBiZSBzZXQsIGlmIG5ldyBvcHRpb25zIGFyZW4ndCBnaXZlbiAodW5kZWZpbmVkIG9yIGEgbm90IGEgcGxhaW4gb2JqZWN0KSB0aGVuIHRoZSBjdXJyZW50IG9wdGlvbnMgd2lsbCBiZSByZXR1cm5lZC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSB2YWx1ZSBJZiBuZXcgb3B0aW9ucyBpcyBhIHByb3BlcnR5IHBhdGggc3RyaW5nLCB0aGVuIHRoaXMgdmFsdWUgd2lsbCBiZSB1c2VkIHRvIHNldCB0aGUgb3B0aW9uIHRvIHdoaWNoIHRoZSBwcm9wZXJ0eSBwYXRoIHN0cmluZyBsZWFkcy5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5vcHRpb25zID0gZnVuY3Rpb24gKG5ld09wdGlvbnMsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9wdGlvbiA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGFuZ2VkT3BzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JldHVybiBjdXJyZW50IG9wdGlvbnMgaWYgbmV3T3B0aW9ucyBhcmUgdW5kZWZpbmVkIG9yIGVtcHR5XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKEZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KG5ld09wdGlvbnMpIHx8ICFGUkFNRVdPUksuaXNQbGFpbk9iamVjdChuZXdPcHRpb25zKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShuZXdPcHRpb25zKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRPYmplY3RQcm9wVmFsKG9wdGlvbiwgbmV3T3B0aW9ucywgdmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZWRPcHMgPSBzZXRPcHRpb25zKG9wdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE9iamVjdFByb3BWYWwoX2N1cnJlbnRPcHRpb25zLCBuZXdPcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2N1cnJlbnRPcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlZE9wcyA9IHNldE9wdGlvbnMobmV3T3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc0VtcHR5T2JqZWN0KGNoYW5nZWRPcHMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh7IF9jaGFuZ2VkT3B0aW9uczogY2hhbmdlZE9wcyB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmVzdG9yZSB0aGUgRE9NLCBkaXNjb25uZWN0cyBhbGwgb2JzZXJ2ZXJzLCByZW1vdmUgYWxsIHJlc2l6ZSBvYnNlcnZlcnMgYW5kIHB1dCB0aGUgaW5zdGFuY2UgdG8gc2xlZXAuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIGF1dG8gdXBkYXRlIGxvb3BcclxuICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlTG9vcC5yZW1vdmUoX2Jhc2UpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2Rpc2Nvbm5lY3QgYWxsIG11dGF0aW9uIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcmVzaXplIG9ic2VydmVyc1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVBdXRvT2JzZXJ2ZXJFbGVtZW50KTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBleHROYW1lIGluIF9leHRlbnNpb25zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQoZXh0TmFtZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCAnZGVzdHJveScgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKF9kZXN0cm95RXZlbnRzW0xFWElDT04ubF0gPiAwKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBfZGVzdHJveUV2ZW50cy5wb3AoKSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZXZlbnRzIGZyb20gaG9zdCBlbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBIb3N0TW91c2VUb3VjaEV2ZW50cyh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgYWxsIGhlbHBlciAvIGRldGVjdGlvbiBlbGVtZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfY29udGVudEdsdWVFbGVtZW50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmUoX2NvbnRlbnRHbHVlRWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9jb250ZW50QXJyYW5nZUVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZShfY29udGVudEFycmFuZ2VFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoX3NpemVBdXRvT2JzZXJ2ZXJBZGRlZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlKF9zaXplQXV0b09ic2VydmVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIGFsbCBnZW5lcmF0ZWQgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTY3JvbGxiYXJzRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyQ29ybmVyRE9NKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU3RydWN0dXJlRE9NKHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgZ2VuZXJhdGVkIGltYWdlIGxvYWQgZXZlbnRzXHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBfdXBkYXRlT25Mb2FkRWxtc1tMRVhJQ09OLmxdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSyhfdXBkYXRlT25Mb2FkRWxtc1tpXSkub2ZmKF91cGRhdGVPbkxvYWRFdmVudE5hbWUsIHVwZGF0ZU9uTG9hZENhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgICAgICBfdXBkYXRlT25Mb2FkRWxtcyA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3NsZWVwaW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy9yZW1vdmUgdGhpcyBpbnN0YW5jZSBmcm9tIHRoZSBpbnN0YW5jZXMgbGlzdFxyXG4gICAgICAgICAgICAgICAgICAgIElOU1RBTkNFUyhwbHVnaW5UYXJnZXRFbGVtZW50LCAwKTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkRlc3Ryb3llZCcpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL3JlbW92ZSBhbGwgcHJvcGVydGllcyBhbmQgbWV0aG9kc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgcHJvcGVydHkgaW4gX2Jhc2UpXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgZGVsZXRlIF9iYXNlW3Byb3BlcnR5XTtcclxuICAgICAgICAgICAgICAgICAgICAvL19iYXNlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFNjcm9sbHMgdG8gYSBnaXZlbiBwb3NpdGlvbiBvciBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGNvb3JkaW5hdGVzXHJcbiAgICAgICAgICAgICAgICAgKiAxLiBDYW4gYmUgXCJjb29yZGluYXRlc1wiIHdoaWNoIGxvb2tzIGxpa2U6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7IHggOiA/LCB5IDogPyB9IE9SICAgICAgICAgIE9iamVjdCB3aXRoIHggYW5kIHkgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsZWZ0IDogPywgdG9wIDogPyB9IE9SICAgICBPYmplY3Qgd2l0aCBsZWZ0IGFuZCB0b3AgcHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICogICAgeyBsIDogPywgdCA6ID8gfSBPUiAgICAgICAgICBPYmplY3Qgd2l0aCBsIGFuZCB0IHByb3BlcnRpZXNcclxuICAgICAgICAgICAgICAgICAqICAgIFsgPywgPyBdIE9SICAgICAgICAgICAgICAgICAgQXJyYXkgd2hlcmUgdGhlIGZpcnN0IHR3byBlbGVtZW50IGFyZSB0aGUgY29vcmRpbmF0ZXMgKGZpcnN0IGlzIHgsIHNlY29uZCBpcyB5KVxyXG4gICAgICAgICAgICAgICAgICogICAgPyAgICAgICAgICAgICAgICAgICAgICAgICAgICBBIHNpbmdsZSB2YWx1ZSB3aGljaCBzdGF5cyBmb3IgYm90aCBheGlzXHJcbiAgICAgICAgICAgICAgICAgKiAgICBBIHZhbHVlIGNhbiBiZSBhIG51bWJlciwgYSBzdHJpbmcgb3IgYSBjYWxjdWxhdGlvbi5cclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBPcGVyYXRvcnM6XHJcbiAgICAgICAgICAgICAgICAgKiAgICBbTk9ORV0gIFRoZSBjdXJyZW50IHNjcm9sbCB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IHRoZSB2YWx1ZS5cclxuICAgICAgICAgICAgICAgICAqICAgICcrPScgICAgVGhlIHZhbHVlIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJy09JyAgICBUaGUgdmFsdWUgd2lsbCBiZSBzdWJ0cmFjdGVkIGZyb20gdGhlIGN1cnJlbnQgc2Nyb2xsIG9mZnNldFxyXG4gICAgICAgICAgICAgICAgICogICAgJyo9JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICogICAgJy89JyAgICBUaGUgY3VycmVudCBzY3JvbGwgd2lsIGJlIGRpdmlkZWQgYnkgdGhlIHZhbHVlLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFVuaXRzOlxyXG4gICAgICAgICAgICAgICAgICogICAgW05PTkVdICBUaGUgdmFsdWUgaXMgdGhlIGZpbmFsIHNjcm9sbCBhbW91bnQuICAgICAgICAgICAgICAgICAgIGZpbmFsID0gKHZhbHVlICogMSlcclxuICAgICAgICAgICAgICAgICAqICAgICdweCcgICAgU2FtZSBhcyBub25lXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnJScgICAgIFRoZSB2YWx1ZSBpcyBkZXBlbmRlbnQgb24gdGhlIGN1cnJlbnQgc2Nyb2xsIHZhbHVlLiAgICAgZmluYWwgPSAoKGN1cnJlbnRTY3JvbGxWYWx1ZSAvIDEwMCkgKiB2YWx1ZSlcclxuICAgICAgICAgICAgICAgICAqICAgICd2dycgICAgVGhlIHZhbHVlIGlzIG11bHRpcGxpY2F0ZWQgYnkgdGhlIHZpZXdwb3J0IHdpZHRoLiAgICAgICBmaW5hbCA9ICh2YWx1ZSAqIHZpZXdwb3J0V2lkdGgpXHJcbiAgICAgICAgICAgICAgICAgKiAgICAndmgnICAgIFRoZSB2YWx1ZSBpcyBtdWx0aXBsaWNhdGVkIGJ5IHRoZSB2aWV3cG9ydCBoZWlnaHQuICAgICAgZmluYWwgPSAodmFsdWUgKiB2aWV3cG9ydEhlaWdodClcclxuICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgKiAgICBleGFtcGxlIGZpbmFsIHZhbHVlczpcclxuICAgICAgICAgICAgICAgICAqICAgIDIwMCwgJzIwMHB4JywgJzUwJScsICcxdncnLCAnMXZoJywgJys9MjAwJywgJy89MXZ3JywgJyo9MnB4JywgJy09NXZoJywgJys9MzMlJywgJys9IDUwJSAtIDJweCcsICctPSAxdncgLSA1MCUnXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogMi4gQ2FuIGJlIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudDpcclxuICAgICAgICAgICAgICAgICAqICAgIFRoZSBmaW5hbCBzY3JvbGwgb2Zmc2V0IGlzIHRoZSBvZmZzZXQgKHdpdGhvdXQgbWFyZ2luKSBvZiB0aGUgZ2l2ZW4gSFRNTCAvIGpRdWVyeSBlbGVtZW50LlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIDMuIENhbiBiZSBhIG9iamVjdCB3aXRoIGEgSFRNTCBvciBqUXVlcnkgZWxlbWVudCB3aXRoIGFkZGl0aW9uYWwgc2V0dGluZ3M6XHJcbiAgICAgICAgICAgICAgICAgKiAgICB7XHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIGVsIDogW0hUTUxFbGVtZW50LCBqUXVlcnkgZWxlbWVudF0sICAgICAgICAgICAgIE1VU1QgYmUgc3BlY2lmaWVkLCBlbHNlIHRoaXMgb2JqZWN0IGlzbid0IHZhbGlkLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBzY3JvbGwgOiBbc3RyaW5nLCBhcnJheSwgb2JqZWN0XSwgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdhbHdheXMnLlxyXG4gICAgICAgICAgICAgICAgICogICAgICBibG9jayA6IFtzdHJpbmcsIGFycmF5LCBvYmplY3RdLCAgICAgICAgICAgICAgICBEZWZhdWx0IHZhbHVlIGlzICdiZWdpbicuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAgIG1hcmdpbiA6IFtudW1iZXIsIGJvb2xlYW4sIGFycmF5LCBvYmplY3RdICAgICAgIERlZmF1bHQgdmFsdWUgaXMgZmFsc2UuXHJcbiAgICAgICAgICAgICAgICAgKiAgICB9XHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgc2Nyb2xsIHNldHRpbmdzIGFyZTpcclxuICAgICAgICAgICAgICAgICAqICAgICdhbHdheXMnICAgICAgU2Nyb2xscyBhbHdheXMuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnaWZuZWVkZWQnICAgIFNjcm9sbHMgb25seSBpZiB0aGUgZWxlbWVudCBpc250IGZ1bGx5IGluIHZpZXcuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnbmV2ZXInICAgICAgIFNjcm9sbHMgbmV2ZXIuXHJcbiAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICogICAgUG9zc2libGUgYmxvY2sgc2V0dGluZ3MgYXJlOlxyXG4gICAgICAgICAgICAgICAgICogICAgJ2JlZ2luJyAgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gdGhlIFwiYmVnaW5cIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSB0b3AgYW5kIGxlZnQgZWRnZSBvZiB0aGUgdmlld3BvcnQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICAnZW5kJyAgICAgQm90aCBheGlzIHNoYWxsIGJlIGRvY2tlZCB0byB0aGUgXCJlbmRcIiBlZGdlLiAtIFRoZSBlbGVtZW50IHdpbGwgYmUgZG9ja2VkIHRvIHRoZSBib3R0b20gYW5kIHJpZ2h0IGVkZ2Ugb2YgdGhlIHZpZXdwb3J0LiAoSWYgZGlyZWN0aW9uIGlzIFJUTCB0byB0aGUgYm90dG9tIGFuZCBsZWZ0IGVkZ2UuKVxyXG4gICAgICAgICAgICAgICAgICogICAgJ2NlbnRlcicgIEJvdGggYXhpcyBzaGFsbCBiZSBkb2NrZWQgdG8gXCJjZW50ZXJcIi4gLSBUaGUgZWxlbWVudCB3aWxsIGJlIGNlbnRlcmVkIGluIHRoZSB2aWV3cG9ydC5cclxuICAgICAgICAgICAgICAgICAqICAgICduZWFyZXN0JyBUaGUgZWxlbWVudCB3aWxsIGJlIGRvY2tlZCB0byB0aGUgbmVhcmVzdCBlZGdlKHMpLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqICAgIFBvc3NpYmxlIG1hcmdpbiBzZXR0aW5ncyBhcmU6IC0tIFRoZSBhY3R1YWwgbWFyZ2luIG9mIHRoZSBlbGVtZW50IHdvbnQgYmUgYWZmZWN0LCB0aGlzIG9wdGlvbiBhZmZlY3RzIG9ubHkgdGhlIGZpbmFsIHNjcm9sbCBvZmZzZXQuXHJcbiAgICAgICAgICAgICAgICAgKiAgICBbQk9PTEVBTl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmIHRydWUgdGhlIGNzcyBtYXJnaW4gb2YgdGhlIGVsZW1lbnQgd2lsbCBiZSB1c2VkLCBpZiBmYWxzZSBubyBtYXJnaW4gd2lsbCBiZSB1c2VkLlxyXG4gICAgICAgICAgICAgICAgICogICAgW05VTUJFUl0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgbWFyZ2luIHdpbGwgYmUgdXNlZCBmb3IgYWxsIGVkZ2VzLlxyXG4gICAgICAgICAgICAgICAgICpcclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHNjcm9sbCBhbmltYXRpb24sIE9SIGEgalF1ZXJ5IGFuaW1hdGlvbiBjb25maWd1cmF0aW9uIG9iamVjdC5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBlYXNpbmcgVGhlIGFuaW1hdGlvbiBlYXNpbmcuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gY29tcGxldGUgVGhlIGFuaW1hdGlvbiBjb21wbGV0ZSBjYWxsYmFjay5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7XHJcbiAgICAgICAgICAgICAgICAgKiAgIHBvc2l0aW9uOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICByYXRpbzoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgbWF4OiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9LFxyXG4gICAgICAgICAgICAgICAgICogICBoYW5kbGVPZmZzZXQ6IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGhhbmRsZUxlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaGFuZGxlTGVuZ3RoUmF0aW86IHt4OiBudW1iZXIsIHk6IG51bWJlcn0sIHRcclxuICAgICAgICAgICAgICAgICAqICAgcmFja0xlbmd0aDoge3g6IG51bWJlciwgeTogbnVtYmVyfSxcclxuICAgICAgICAgICAgICAgICAqICAgaXNSVEw6IGJvb2xlYW4sXHJcbiAgICAgICAgICAgICAgICAgKiAgIGlzUlRMTm9ybWFsaXplZDogYm9vbGVhblxyXG4gICAgICAgICAgICAgICAgICogIH19XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbCA9IGZ1bmN0aW9uIChjb29yZGluYXRlcywgZHVyYXRpb24sIGVhc2luZywgY29tcGxldGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCBjb29yZGluYXRlcyA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbmZvWCA9IF9zY3JvbGxIb3Jpem9udGFsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGluZm9ZID0gX3Njcm9sbFZlcnRpY2FsSW5mbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZUludmVydCA9IF9ub3JtYWxpemVSVExDYWNoZSAmJiBfaXNSVEwgJiYgX3J0bFNjcm9sbEJlaGF2aW9yLmk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVOZWdhdGUgPSBfbm9ybWFsaXplUlRMQ2FjaGUgJiYgX2lzUlRMICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWCA9IGluZm9YLl9jdXJyZW50U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2Nyb2xsWFJhdGlvID0gaW5mb1guX2N1cnJlbnRTY3JvbGxSYXRpbztcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1heFNjcm9sbFggPSBpbmZvWC5fbWF4U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYUmF0aW8gPSBub3JtYWxpemVJbnZlcnQgPyAxIC0gc2Nyb2xsWFJhdGlvIDogc2Nyb2xsWFJhdGlvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYID0gbm9ybWFsaXplSW52ZXJ0ID8gbWF4U2Nyb2xsWCAtIHNjcm9sbFggOiBzY3JvbGxYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxYICo9IG5vcm1hbGl6ZU5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4U2Nyb2xsWCAqPSBub3JtYWxpemVOZWdhdGUgPyAtMSA6IDE7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9jdXJyZW50U2Nyb2xsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF0aW86IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBzY3JvbGxYUmF0aW8sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2N1cnJlbnRTY3JvbGxSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IG1heFNjcm9sbFgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX21heFNjcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZU9mZnNldDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVPZmZzZXQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aDoge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IGluZm9YLl9oYW5kbGVMZW5ndGgsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogaW5mb1kuX2hhbmRsZUxlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZUxlbmd0aFJhdGlvOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX2hhbmRsZUxlbmd0aFJhdGlvLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl9oYW5kbGVMZW5ndGhSYXRpb1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrTGVuZ3RoOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogaW5mb1guX3RyYWNrTGVuZ3RoLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGluZm9ZLl90cmFja0xlbmd0aFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNuYXBwZWRIYW5kbGVPZmZzZXQ6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBpbmZvWC5fc25hcHBlZEhhbmRsZU9mZnNldCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiBpbmZvWS5fc25hcHBlZEhhbmRsZU9mZnNldFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzUlRMOiBfaXNSVEwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JUTE5vcm1hbGl6ZWQ6IF9ub3JtYWxpemVSVExDYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Jhc2UudXBkYXRlKF9zdHJTeW5jKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vcm1hbGl6ZVJUTCA9IF9ub3JtYWxpemVSVExDYWNoZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNYQXhpc1Byb3BzID0gW19zdHJYLCBfc3RyTGVmdCwgJ2wnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNZQXhpc1Byb3BzID0gW19zdHJZLCBfc3RyVG9wLCAndCddO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb29yZGluYXRlc09wZXJhdG9ycyA9IFsnKz0nLCAnLT0nLCAnKj0nLCAnLz0nXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb25Jc09iamVjdCA9IHR5cGUoZHVyYXRpb24pID09IFRZUEVTLm87XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbXBsZXRlQ2FsbGJhY2sgPSBkdXJhdGlvbklzT2JqZWN0ID8gZHVyYXRpb24uY29tcGxldGUgOiBjb21wbGV0ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZmluYWxTY3JvbGwgPSB7fTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3BlY2lhbEVhc2luZyA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkb1Njcm9sbExlZnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRvU2Nyb2xsVG9wO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBhbmltYXRpb25PcHRpb25zO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJFbmQgPSAnZW5kJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQmVnaW4gPSAnYmVnaW4nO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJDZW50ZXIgPSAnY2VudGVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyTmVhcmVzdCA9ICduZWFyZXN0JztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyQWx3YXlzID0gJ2Fsd2F5cyc7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0ck5ldmVyID0gJ25ldmVyJztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc3RySWZOZWVkZWQgPSAnaWZuZWVkZWQnO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdHJMZW5ndGggPSBMRVhJQ09OLmw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQXhpcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgc2V0dGluZ3NTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzQmxvY2s7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNldHRpbmdzTWFyZ2luO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbEVsZW1lbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMgPSBbX3N0clgsIF9zdHJZLCAneHknLCAneXgnXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzQmxvY2tWYWx1ZXMgPSBbc3RyQmVnaW4sIHN0ckVuZCwgc3RyQ2VudGVyLCBzdHJOZWFyZXN0XTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzID0gW3N0ckFsd2F5cywgc3RyTmV2ZXIsIHN0cklmTmVlZGVkXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPSBjb29yZGluYXRlc1tMRVhJQ09OLmhPUF0oJ2VsJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudCA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuZWwgOiBjb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcG9zc2libGVFbGVtZW50SXNKUXVlcnkgPSBwb3NzaWJsZUVsZW1lbnQgaW5zdGFuY2VvZiBGUkFNRVdPUksgfHwgSlFVRVJZID8gcG9zc2libGVFbGVtZW50IGluc3RhbmNlb2YgSlFVRVJZIDogZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBvc3NpYmxlRWxlbWVudElzSFRNTEVsZW1lbnQgPSBwb3NzaWJsZUVsZW1lbnRJc0pRdWVyeSA/IGZhbHNlIDogaXNIVE1MRWxlbWVudChwb3NzaWJsZUVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGVTY3JvbGxiYXJJbmZvcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQodHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2hTY3JvbGxiYXJIYW5kbGVPZmZzZXQoZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3h5Q29tcGxldGVDYWxsYmFjayA9IHR5cGUoY29tcGxldGVDYWxsYmFjaykgIT0gVFlQRVMuZiA/IHVuZGVmaW5lZCA6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlU2Nyb2xsYmFySW5mb3MoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGVDYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGN1cnJWYWx1ZSwgYWxsb3dlZFZhbHVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYWxsb3dlZFZhbHVlc1tzdHJMZW5ndGhdOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyVmFsdWUgPT09IGFsbG93ZWRWYWx1ZXNbaV0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRSYXdTY3JvbGwoaXNYLCBjb29yZGluYXRlcykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29vcmRpbmF0ZVByb3BzID0gaXNYID8gY29vcmRpbmF0ZXNYQXhpc1Byb3BzIDogY29vcmRpbmF0ZXNZQXhpc1Byb3BzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLnMgfHwgdHlwZShjb29yZGluYXRlcykgPT0gVFlQRVMubiA/IFtjb29yZGluYXRlcywgY29vcmRpbmF0ZXNdIDogY29vcmRpbmF0ZXM7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoQ09NUEFUSUJJTElUWS5pc0EoY29vcmRpbmF0ZXMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlzWCA/IGNvb3JkaW5hdGVzWzBdIDogY29vcmRpbmF0ZXNbMV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGUoY29vcmRpbmF0ZXMpID09IFRZUEVTLm8pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZGVjaWRlcyBSVEwgbm9ybWFsaXphdGlvbiBcImhhY2tcIiB3aXRoIC5uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL25vcm1hbGl6ZVJUTCA9IHR5cGUoY29vcmRpbmF0ZXMubikgPT0gVFlQRVMuYiA/IGNvb3JkaW5hdGVzLm4gOiBub3JtYWxpemVSVEw7IFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb3JkaW5hdGVQcm9wc1tzdHJMZW5ndGhdOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb3JkaW5hdGVQcm9wc1tpXSBpbiBjb29yZGluYXRlcylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzW2Nvb3JkaW5hdGVQcm9wc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gZ2V0RmluYWxTY3JvbGwoaXNYLCByYXdTY3JvbGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGlzU3RyaW5nID0gdHlwZShyYXdTY3JvbGwpID09IFRZUEVTLnM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbEluZm8gPSBpc1ggPyBfc2Nyb2xsSG9yaXpvbnRhbEluZm8gOiBfc2Nyb2xsVmVydGljYWxJbmZvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY3VyclNjcm9sbCA9IHNjcm9sbEluZm8uX2N1cnJlbnRTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXhTY3JvbGwgPSBzY3JvbGxJbmZvLl9tYXhTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtdWx0ID0gJyAqICc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNSVExpc1ggPSBfaXNSVEwgJiYgaXNYO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbm9ybWFsaXplU2hvcnRjdXRzID0gaXNSVExpc1ggJiYgX3J0bFNjcm9sbEJlaGF2aW9yLm4gJiYgIW5vcm1hbGl6ZVJUTDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHN0clJlcGxhY2UgPSAncmVwbGFjZSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBldmFsRnVuYyA9IGV2YWw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2hlY2sgb3BlcmF0b3JcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdTY3JvbGxbc3RyTGVuZ3RoXSA+IDIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NzaWJsZU9wZXJhdG9yID0gcmF3U2Nyb2xsLnN1YnN0cigwLCAyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5BcnJheShwb3NzaWJsZU9wZXJhdG9yLCBjb29yZGluYXRlc09wZXJhdG9ycykgPiAtMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3IgPSBwb3NzaWJsZU9wZXJhdG9yO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vY2FsY3VsYXRlIHVuaXRzIGFuZCBzaG9ydGN1dHNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IG9wZXJhdG9yID8gcmF3U2Nyb2xsLnN1YnN0cigyKSA6IHJhd1Njcm9sbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd1Njcm9sbCA9IHJhd1Njcm9sbFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC9taW4vZywgMCkgLy8nbWluJyA9IDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oLzwvZywgMCkgICAvLyc8JyAgID0gMCVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvbWF4L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAvLydtYXgnID0gMTAwJVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0clJlcGxhY2VdKC8+L2csIChub3JtYWxpemVTaG9ydGN1dHMgPyAnLScgOiBfc3RyRW1wdHkpICsgX3N0ckh1bmRyZWRQZXJjZW50KSAgICAgIC8vJz4nICAgPSAxMDAlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3B4L2csIF9zdHJFbXB0eSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHJSZXBsYWNlXSgvJS9nLCBtdWx0ICsgKG1heFNjcm9sbCAqIChpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IC0xIDogMSkgLyAxMDAuMCkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3Z3L2csIG11bHQgKyBfdmlld3BvcnRTaXplLncpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3RyUmVwbGFjZV0oL3ZoL2csIG11bHQgKyBfdmlld3BvcnRTaXplLmgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcGFyc2VUb1plcm9Pck51bWJlcihpc05hTihyYXdTY3JvbGwpID8gcGFyc2VUb1plcm9Pck51bWJlcihldmFsRnVuYyhyYXdTY3JvbGwpLCB0cnVlKS50b0ZpeGVkKCkgOiByYXdTY3JvbGwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYW1vdW50ID0gcmF3U2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW1vdW50ICE9PSB1bmRlZmluZWQgJiYgIWlzTmFOKGFtb3VudCkgJiYgdHlwZShhbW91bnQpID09IFRZUEVTLm4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub3JtYWxpemVJc1JUTGlzWCA9IG5vcm1hbGl6ZVJUTCAmJiBpc1JUTGlzWDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvcGVyYXRvckN1cnJTY3JvbGwgPSBjdXJyU2Nyb2xsICogKG5vcm1hbGl6ZUlzUlRMaXNYICYmIF9ydGxTY3JvbGxCZWhhdmlvci5uID8gLTEgOiAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpbnZlcnQgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IuaTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZWdhdGUgPSBub3JtYWxpemVJc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yQ3VyclNjcm9sbCA9IGludmVydCA/IChtYXhTY3JvbGwgLSBvcGVyYXRvckN1cnJTY3JvbGwpIDogb3BlcmF0b3JDdXJyU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJys9JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCArIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnLT0nOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gb3BlcmF0b3JDdXJyU2Nyb2xsIC0gYW1vdW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICcqPSc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBvcGVyYXRvckN1cnJTY3JvbGwgKiBhbW91bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJy89JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IG9wZXJhdG9yQ3VyclNjcm9sbCAvIGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxWYWx1ZSA9IGFtb3VudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlID0gaW52ZXJ0ID8gbWF4U2Nyb2xsIC0gZmluYWxWYWx1ZSA6IGZpbmFsVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFZhbHVlICo9IG5lZ2F0ZSA/IC0xIDogMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsVmFsdWUgPSBpc1JUTGlzWCAmJiBfcnRsU2Nyb2xsQmVoYXZpb3IubiA/IE1BVEgubWluKDAsIE1BVEgubWF4KG1heFNjcm9sbCwgZmluYWxWYWx1ZSkpIDogTUFUSC5tYXgoMCwgTUFUSC5taW4obWF4U2Nyb2xsLCBmaW5hbFZhbHVlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVmFsdWUgPT09IGN1cnJTY3JvbGwgPyB1bmRlZmluZWQgOiBmaW5hbFZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZXRQZXJBeGlzVmFsdWUodmFsdWUsIHZhbHVlSW50ZXJuYWxUeXBlLCBkZWZhdWx0VmFsdWUsIGFsbG93ZWRWYWx1ZXMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdERlZmF1bHQgPSBbZGVmYXVsdFZhbHVlLCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVUeXBlID0gdHlwZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZUFyckxlbmd0aDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlQXJySXRlbTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vdmFsdWUgY2FuIGJlIFsgc3RyaW5nLCBvciBhcnJheSBvZiB0d28gc3RyaW5ncyBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZVR5cGUgPT0gdmFsdWVJbnRlcm5hbFR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlLCB2YWx1ZV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWVUeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlQXJyTGVuZ3RoID0gdmFsdWVbc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA+IDIgfHwgdmFsdWVBcnJMZW5ndGggPCAxKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcmVzdWx0RGVmYXVsdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZUFyckxlbmd0aCA9PT0gMSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMV0gPSBkZWZhdWx0VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlQXJyTGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVBcnJJdGVtID0gdmFsdWVbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKHZhbHVlQXJySXRlbSkgIT0gdmFsdWVJbnRlcm5hbFR5cGUgfHwgIWNoZWNrU2V0dGluZ3NTdHJpbmdWYWx1ZSh2YWx1ZUFyckl0ZW0sIGFsbG93ZWRWYWx1ZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh2YWx1ZVR5cGUgPT0gVFlQRVMubylcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gW3ZhbHVlW19zdHJYXSB8fCBkZWZhdWx0VmFsdWUsIHZhbHVlW19zdHJZXSB8fCBkZWZhdWx0VmFsdWVdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHJlc3VsdERlZmF1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHg6IHZhbHVlWzBdLCB5OiB2YWx1ZVsxXSB9O1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZU1hcmdpbihtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyVmFsdWVUeXBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmFsdWVEaXJlY3Rpb25zID0gW19zdHJUb3AsIF9zdHJSaWdodCwgX3N0ckJvdHRvbSwgX3N0ckxlZnRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbWFyZ2luVG9wUmlnaHRCb3R0b21MZWZ0QXJyYXlbc3RyTGVuZ3RoXTsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gdmFsdWVEaXJlY3Rpb25zW3N0ckxlbmd0aF0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyVmFsdWUgPSBtYXJnaW5Ub3BSaWdodEJvdHRvbUxlZnRBcnJheVtpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJWYWx1ZVR5cGUgPSB0eXBlKGN1cnJWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VyclZhbHVlVHlwZSA9PSBUWVBFUy5iKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZSA/IHBhcnNlVG9aZXJvT3JOdW1iZXIoZmluYWxFbGVtZW50LmNzcyhfc3RyTWFyZ2luTWludXMgKyB2YWx1ZURpcmVjdGlvbnNbaV0pKSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJWYWx1ZVR5cGUgPT0gVFlQRVMubiA/IGN1cnJWYWx1ZSA6IDApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAocG9zc2libGVFbGVtZW50SXNKUXVlcnkgfHwgcG9zc2libGVFbGVtZW50SXNIVE1MRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2dldCBzZXR0aW5nc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luID0gY29vcmRpbmF0ZXNJc0VsZW1lbnRPYmogPyBjb29yZGluYXRlcy5tYXJnaW4gOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXhpcyA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYXhpcyA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGwgPSBjb29yZGluYXRlc0lzRWxlbWVudE9iaiA/IGNvb3JkaW5hdGVzLnNjcm9sbCA6IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IGNvb3JkaW5hdGVzSXNFbGVtZW50T2JqID8gY29vcmRpbmF0ZXMuYmxvY2sgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWFyZ2luRGVmYXVsdCA9IFswLCAwLCAwLCAwXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmdpblR5cGUgPSB0eXBlKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXJnaW5MZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsRWxlbWVudCA9IHBvc3NpYmxlRWxlbWVudElzSlF1ZXJ5ID8gcG9zc2libGVFbGVtZW50IDogRlJBTUVXT1JLKHBvc3NpYmxlRWxlbWVudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxFbGVtZW50W3N0ckxlbmd0aF0gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL21hcmdpbiBjYW4gYmUgWyBib29sZWFuLCBudW1iZXIsIGFycmF5IG9mIDIsIGFycmF5IG9mIDQsIG9iamVjdCBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5uIHx8IG1hcmdpblR5cGUgPT0gVFlQRVMuYilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luLCBtYXJnaW4sIG1hcmdpbiwgbWFyZ2luXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChtYXJnaW5UeXBlID09IFRZUEVTLmEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5MZW5ndGggPSBtYXJnaW5bc3RyTGVuZ3RoXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFyZ2luTGVuZ3RoID09PSAyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBnZW5lcmF0ZU1hcmdpbihbbWFyZ2luWzBdLCBtYXJnaW5bMV0sIG1hcmdpblswXSwgbWFyZ2luWzFdXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luTGVuZ3RoID49IDQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKG1hcmdpbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWFyZ2luVHlwZSA9PSBUWVBFUy5vKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGdlbmVyYXRlTWFyZ2luKFttYXJnaW5bX3N0clRvcF0sIG1hcmdpbltfc3RyUmlnaHRdLCBtYXJnaW5bX3N0ckJvdHRvbV0sIG1hcmdpbltfc3RyTGVmdF1dKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW5EZWZhdWx0O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vYmxvY2sgPSB0eXBlKGJsb2NrKSA9PT0gVFlQRVMuYiA/IGJsb2NrID8gWyBzdHJOZWFyZXN0LCBzdHJCZWdpbiBdIDogWyBzdHJOZWFyZXN0LCBzdHJFbmQgXSA6IGJsb2NrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dGluZ3NBeGlzID0gY2hlY2tTZXR0aW5nc1N0cmluZ1ZhbHVlKGF4aXMsIGVsZW1lbnRPYmpTZXR0aW5nc0F4aXNWYWx1ZXMpID8gYXhpcyA6ICd4eSc7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc1Njcm9sbCA9IGdldFBlckF4aXNWYWx1ZShzY3JvbGwsIFRZUEVTLnMsIHN0ckFsd2F5cywgZWxlbWVudE9ialNldHRpbmdzU2Nyb2xsVmFsdWVzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzQmxvY2sgPSBnZXRQZXJBeGlzVmFsdWUoYmxvY2ssIFRZUEVTLnMsIHN0ckJlZ2luLCBlbGVtZW50T2JqU2V0dGluZ3NCbG9ja1ZhbHVlcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nc01hcmdpbiA9IG1hcmdpbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRTY3JvbGwgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbDogX3Njcm9sbEhvcml6b250YWxJbmZvLl9jdXJyZW50U2Nyb2xsLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQ6IF9zY3JvbGxWZXJ0aWNhbEluZm8uX2N1cnJlbnRTY3JvbGxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgcGFkZGluZyBlbGVtZW50IGluc3RlYWQgb2Ygdmlld3BvcnQgZWxlbWVudCBiZWNhdXNlIHBhZGRpbmcgZWxlbWVudCBoYXMgbmV2ZXIgcGFkZGluZywgbWFyZ2luIG9yIHBvc2l0aW9uIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdmlld3BvcnRPZmZzZXQgPSBfcGFkZGluZ0VsZW1lbnQub2Zmc2V0KCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9nZXQgY29vcmRpbmF0ZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50T2Zmc2V0ID0gZmluYWxFbGVtZW50Lm9mZnNldCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGRvTm90U2Nyb2xsID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHg6IHNldHRpbmdzU2Nyb2xsLnggPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJZLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RyTmV2ZXIgfHwgc2V0dGluZ3NBeGlzID09IF9zdHJYXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudE9mZnNldFtfc3RyVG9wXSAtPSBzZXR0aW5nc01hcmdpblswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC09IHNldHRpbmdzTWFyZ2luWzNdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcyA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBNQVRILnJvdW5kKGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdIC0gdmlld3BvcnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogTUFUSC5yb3VuZChlbGVtZW50T2Zmc2V0W19zdHJUb3BdIC0gdmlld3BvcnRPZmZzZXRbX3N0clRvcF0gKyB2aWV3cG9ydFNjcm9sbC50KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfaXNSVEwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIV9ydGxTY3JvbGxCZWhhdmlvci5uICYmICFfcnRsU2Nyb2xsQmVoYXZpb3IuaSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgdmlld3BvcnRTY3JvbGwubCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5uICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggKj0gLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9ydGxTY3JvbGxCZWhhdmlvci5pICYmIG5vcm1hbGl6ZVJUTClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudFNjcm9sbENvb3JkaW5hdGVzLnggPSBNQVRILnJvdW5kKHZpZXdwb3J0T2Zmc2V0W19zdHJMZWZ0XSAtIGVsZW1lbnRPZmZzZXRbX3N0ckxlZnRdICsgKF9zY3JvbGxIb3Jpem9udGFsSW5mby5fbWF4U2Nyb2xsIC0gdmlld3BvcnRTY3JvbGwubCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVhc3VyaW5nIGlzIHJlcXVpcmVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2V0dGluZ3NCbG9jay54ICE9IHN0ckJlZ2luIHx8IHNldHRpbmdzQmxvY2sueSAhPSBzdHJCZWdpbiB8fCBzZXR0aW5nc1Njcm9sbC54ID09IHN0cklmTmVlZGVkIHx8IHNldHRpbmdzU2Nyb2xsLnkgPT0gc3RySWZOZWVkZWQgfHwgX2lzUlRMKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lYXN1cmluZ0VsbSA9IGZpbmFsRWxlbWVudFswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmF3RWxlbWVudFNpemUgPSBfc3VwcG9ydFRyYW5zZm9ybSA/IG1lYXN1cmluZ0VsbVtMRVhJQ09OLmJDUl0oKSA6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IG1lYXN1cmluZ0VsbVtMRVhJQ09OLm9XXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBtZWFzdXJpbmdFbG1bTEVYSUNPTi5vSF1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50U2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdzogcmF3RWxlbWVudFNpemVbX3N0cldpZHRoXSArIHNldHRpbmdzTWFyZ2luWzNdICsgc2V0dGluZ3NNYXJnaW5bMV0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGg6IHJhd0VsZW1lbnRTaXplW19zdHJIZWlnaHRdICsgc2V0dGluZ3NNYXJnaW5bMF0gKyBzZXR0aW5nc01hcmdpblsyXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZpbmFsaXplQmxvY2sgPSBmdW5jdGlvbiAoaXNYKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2YXJzID0gZ2V0U2Nyb2xsYmFyVmFycyhpc1gpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2ggPSB2YXJzLl93X2g7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsdCA9IHZhcnMuX2xlZnRfdG9wO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgeHkgPSB2YXJzLl94X3k7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzRW5kID0gc2V0dGluZ3NCbG9ja1t4eV0gPT0gKGlzWCA/IF9pc1JUTCA/IHN0ckJlZ2luIDogc3RyRW5kIDogc3RyRW5kKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJsb2NrSXNDZW50ZXIgPSBzZXR0aW5nc0Jsb2NrW3h5XSA9PSBzdHJDZW50ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBibG9ja0lzTmVhcmVzdCA9IHNldHRpbmdzQmxvY2tbeHldID09IHN0ck5lYXJlc3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzY3JvbGxOZXZlciA9IHNldHRpbmdzU2Nyb2xsW3h5XSA9PSBzdHJOZXZlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNjcm9sbElmTmVlZGVkID0gc2V0dGluZ3NTY3JvbGxbeHldID09IHN0cklmTmVlZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgdnBTaXplID0gX3ZpZXdwb3J0U2l6ZVt3aF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2cE9mZnNldCA9IHZpZXdwb3J0T2Zmc2V0W2x0XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsU2l6ZSA9IGVsZW1lbnRTaXplW3doXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsT2Zmc2V0ID0gZWxlbWVudE9mZnNldFtsdF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkaXZpZGUgPSBibG9ja0lzQ2VudGVyID8gMiA6IDE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbGVtZW50Q2VudGVyT2Zmc2V0ID0gZWxPZmZzZXQgKyAoZWxTaXplIC8gMik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2aWV3cG9ydENlbnRlck9mZnNldCA9IHZwT2Zmc2V0ICsgKHZwU2l6ZSAvIDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNJblZpZXcgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxTaXplIDw9IHZwU2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgZWxPZmZzZXQgPj0gdnBPZmZzZXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIGVsT2Zmc2V0ICsgZWxTaXplIDw9IHZwT2Zmc2V0ICsgdnBTaXplO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcm9sbE5ldmVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoIWRvTm90U2Nyb2xsW3h5XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJsb2NrSXNOZWFyZXN0IHx8IHNjcm9sbElmTmVlZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9Ob3RTY3JvbGxbeHldID0gc2Nyb2xsSWZOZWVkZWQgPyBpc0luVmlldyA6IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrSXNFbmQgPSBlbFNpemUgPCB2cFNpemUgPyBlbGVtZW50Q2VudGVyT2Zmc2V0ID4gdmlld3BvcnRDZW50ZXJPZmZzZXQgOiBlbGVtZW50Q2VudGVyT2Zmc2V0IDwgdmlld3BvcnRDZW50ZXJPZmZzZXQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXNbeHldIC09IGJsb2NrSXNFbmQgfHwgYmxvY2tJc0NlbnRlciA/ICgodnBTaXplIC8gZGl2aWRlKSAtIChlbFNpemUgLyBkaXZpZGUpKSAqIChpc1ggJiYgX2lzUlRMICYmIG5vcm1hbGl6ZVJUTCA/IC0xIDogMSkgOiAwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbGl6ZUJsb2NrKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsaXplQmxvY2soZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC55KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb05vdFNjcm9sbC54KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBlbGVtZW50U2Nyb2xsQ29vcmRpbmF0ZXMueDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcyA9IGVsZW1lbnRTY3JvbGxDb29yZGluYXRlcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbExlZnRdID0gZ2V0RmluYWxTY3JvbGwodHJ1ZSwgZ2V0UmF3U2Nyb2xsKHRydWUsIGNvb3JkaW5hdGVzKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gPSBnZXRGaW5hbFNjcm9sbChmYWxzZSwgZ2V0UmF3U2Nyb2xsKGZhbHNlLCBjb29yZGluYXRlcykpO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsTGVmdCA9IGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvU2Nyb2xsVG9wID0gZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0gIT09IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKChkb1Njcm9sbExlZnQgfHwgZG9TY3JvbGxUb3ApICYmIChkdXJhdGlvbiA+IDAgfHwgZHVyYXRpb25Jc09iamVjdCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uSXNPYmplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uLmNvbXBsZXRlID0gcHJveHlDb21wbGV0ZUNhbGxiYWNrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBkdXJhdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltYXRpb25PcHRpb25zID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTogcHJveHlDb21wbGV0ZUNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkuaXNBKGVhc2luZykgfHwgRlJBTUVXT1JLLmlzUGxhaW5PYmplY3QoZWFzaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbExlZnRdID0gZWFzaW5nWzBdIHx8IGVhc2luZy54O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWxFYXNpbmdbX3N0clNjcm9sbFRvcF0gPSBlYXNpbmdbMV0gfHwgZWFzaW5nLnk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9uT3B0aW9ucy5zcGVjaWFsRWFzaW5nID0gc3BlY2lhbEVhc2luZztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbk9wdGlvbnMuZWFzaW5nID0gZWFzaW5nO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudC5hbmltYXRlKGZpbmFsU2Nyb2xsLCBhbmltYXRpb25PcHRpb25zKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvU2Nyb2xsTGVmdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKGZpbmFsU2Nyb2xsW19zdHJTY3JvbGxMZWZ0XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb1Njcm9sbFRvcClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oZmluYWxTY3JvbGxbX3N0clNjcm9sbFRvcF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVTY3JvbGxiYXJJbmZvcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBTdG9wcyBhbGwgc2Nyb2xsIGFuaW1hdGlvbnMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGN1cnJlbnQgT3ZlcmxheVNjcm9sbGJhcnMgaW5zdGFuY2UgKGZvciBjaGFpbmluZykuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLnNjcm9sbFN0b3AgPSBmdW5jdGlvbiAocGFyYW0xLCBwYXJhbTIsIHBhcmFtMykge1xyXG4gICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuc3RvcChwYXJhbTEsIHBhcmFtMiwgcGFyYW0zKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogUmV0dXJucyBhbGwgcmVsZXZhbnQgZWxlbWVudHMuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZWxlbWVudE5hbWUgVGhlIG5hbWUgb2YgdGhlIGVsZW1lbnQgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3RhcmdldDogKiwgaG9zdDogKiwgcGFkZGluZzogKiwgdmlld3BvcnQ6ICosIGNvbnRlbnQ6ICosIHNjcm9sbGJhckhvcml6b250YWw6IHtzY3JvbGxiYXI6ICosIHRyYWNrOiAqLCBoYW5kbGU6ICp9LCBzY3JvbGxiYXJWZXJ0aWNhbDoge3Njcm9sbGJhcjogKiwgdHJhY2s6ICosIGhhbmRsZTogKn0sIHNjcm9sbGJhckNvcm5lcjogKn0gfCAqfVxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5nZXRFbGVtZW50cyA9IGZ1bmN0aW9uIChlbGVtZW50TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvYmogPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldDogX3RhcmdldEVsZW1lbnROYXRpdmUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvc3Q6IF9ob3N0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogX3BhZGRpbmdFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3cG9ydDogX3ZpZXdwb3J0RWxlbWVudE5hdGl2ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogX2NvbnRlbnRFbGVtZW50TmF0aXZlLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXJIb3Jpem9udGFsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJIb3Jpem9udGFsRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrOiBfc2Nyb2xsYmFySG9yaXpvbnRhbFRyYWNrRWxlbWVudFswXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZTogX3Njcm9sbGJhckhvcml6b250YWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhclZlcnRpY2FsOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxiYXI6IF9zY3JvbGxiYXJWZXJ0aWNhbEVsZW1lbnRbMF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjazogX3Njcm9sbGJhclZlcnRpY2FsVHJhY2tFbGVtZW50WzBdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZGxlOiBfc2Nyb2xsYmFyVmVydGljYWxIYW5kbGVFbGVtZW50WzBdXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbGJhckNvcm5lcjogX3Njcm9sbGJhckNvcm5lckVsZW1lbnRbMF1cclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlKGVsZW1lbnROYW1lKSA9PSBUWVBFUy5zID8gZ2V0T2JqZWN0UHJvcFZhbChvYmosIGVsZW1lbnROYW1lKSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGRlc2NyaWJlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIHN0YXRlUHJvcGVydHkgQSBzcGVjaWZpYyBwcm9wZXJ0eSBmcm9tIHRoZSBzdGF0ZSBvYmplY3Qgd2hpY2ggc2hhbGwgYmUgcmV0dXJuZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcmV0dXJucyB7e3dpZHRoQXV0bywgaGVpZ2h0QXV0bywgb3ZlcmZsb3dBbW91bnQsIGhpZGVPdmVyZmxvdywgaGFzT3ZlcmZsb3csIGNvbnRlbnRTY3JvbGxTaXplLCB2aWV3cG9ydFNpemUsIGhvc3RTaXplLCBhdXRvVXBkYXRlfSB8ICp9XHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmdldFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlUHJvcGVydHkpIHtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBwcmVwYXJlKG9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUZSQU1FV09SSy5pc1BsYWluT2JqZWN0KG9iaikpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0ZW5kZWQgPSBleHRlbmREZWVwKHt9LCBvYmopO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2hhbmdlUHJvcGVydHlOYW1lID0gZnVuY3Rpb24gKGZyb20sIHRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXh0ZW5kZWRbTEVYSUNPTi5oT1BdKGZyb20pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kZWRbdG9dID0gZXh0ZW5kZWRbZnJvbV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV4dGVuZGVkW2Zyb21dO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VQcm9wZXJ0eU5hbWUoJ3cnLCBfc3RyV2lkdGgpOyAvL2NoYW5nZSB3IHRvIHdpZHRoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZVByb3BlcnR5TmFtZSgnaCcsIF9zdHJIZWlnaHQpOyAvL2NoYW5nZSBoIHRvIGhlaWdodFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZXh0ZW5kZWQuYzsgLy9kZWxldGUgYyAodGhlICdjaGFuZ2VkJyBwcm9wKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXh0ZW5kZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb2JqID0ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXN0cm95ZWQ6ICEhcHJlcGFyZShfZGVzdHJveWVkKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2xlZXBpbmc6ICEhcHJlcGFyZShfc2xlZXBpbmcpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvVXBkYXRlOiBwcmVwYXJlKCFfbXV0YXRpb25PYnNlcnZlcnNDb25uZWN0ZWQpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aWR0aEF1dG86IHByZXBhcmUoX3dpZHRoQXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0QXV0bzogcHJlcGFyZShfaGVpZ2h0QXV0b0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogcHJlcGFyZShfY3NzUGFkZGluZ0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcmZsb3dBbW91bnQ6IHByZXBhcmUoX292ZXJmbG93QW1vdW50Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoaWRlT3ZlcmZsb3c6IHByZXBhcmUoX2hpZGVPdmVyZmxvd0NhY2hlKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzT3ZlcmZsb3c6IHByZXBhcmUoX2hhc092ZXJmbG93Q2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50U2Nyb2xsU2l6ZTogcHJlcGFyZShfY29udGVudFNjcm9sbFNpemVDYWNoZSksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdwb3J0U2l6ZTogcHJlcGFyZShfdmlld3BvcnRTaXplKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgaG9zdFNpemU6IHByZXBhcmUoX2hvc3RTaXplQ2FjaGUpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudE1peGVkOiBwcmVwYXJlKF9kb2N1bWVudE1peGVkKVxyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHR5cGUoc3RhdGVQcm9wZXJ0eSkgPT0gVFlQRVMucyA/IGdldE9iamVjdFByb3BWYWwob2JqLCBzdGF0ZVByb3BlcnR5KSA6IG9iajtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBHZXRzIGFsbCBvciBzcGVjaWZpYyBleHRlbnNpb24gaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIGZyb20gd2hpY2ggdGhlIGluc3RhbmNlIHNoYWxsIGJlIGdvdC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBleHRlbnNpb24gd2l0aCB0aGUgZ2l2ZW4gbmFtZSBvciB1bmRlZmluZWQgaWYgdGhlIGluc3RhbmNlIGNvdWxkbid0IGJlIGZvdW5kLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5leHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByaXZhdGVNZXRob2RzID0gX2V4dGVuc2lvbnNQcml2YXRlTWV0aG9kcy5zcGxpdCgnICcpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHROYW1lKSA9PSBUWVBFUy5zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGV4dGVuZERlZXAoe30sIF9leHRlbnNpb25zW2V4dE5hbWVdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgcHJpdmF0ZU1ldGhvZHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3VsdFtwcml2YXRlTWV0aG9kc1tpXV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4gX2V4dGVuc2lvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBleHRlbmREZWVwKHt9LCBfYmFzZS5leHQoaSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIEFkZHMgYSBleHRlbnNpb24gdG8gdGhpcyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICAgICAqIEBwYXJhbSBleHROYW1lIFRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgYWRkZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uT3B0aW9ucyBUaGUgZXh0ZW5zaW9uIG9wdGlvbnMgd2hpY2ggc2hhbGwgYmUgdXNlZC5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHt7fX0gVGhlIGluc3RhbmNlIG9mIHRoZSBhZGRlZCBleHRlbnNpb24gb3IgdW5kZWZpbmVkIGlmIHRoZSBleHRlbnNpb24gY291bGRuJ3QgYmUgYWRkZWQgcHJvcGVybHkuXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIF9iYXNlLmFkZEV4dCA9IGZ1bmN0aW9uIChleHROYW1lLCBleHRlbnNpb25PcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlZ2lzdGVyZWRFeHRlbnNpb25PYmogPSBfcGx1Z2luLmV4dGVuc2lvbihleHROYW1lKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2U7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQWRkZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlQ29udHJhY3Q7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbnRyYWN0UmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjb250cmFjdEZ1bGZpbGxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlZ2lzdGVyZWRFeHRlbnNpb25PYmopIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFfZXh0ZW5zaW9uc1tMRVhJQ09OLmhPUF0oZXh0TmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlID0gcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5leHRlbnNpb25GYWN0b3J5LmNhbGwoX2Jhc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5kRGVlcCh7fSwgcmVnaXN0ZXJlZEV4dGVuc2lvbk9iai5kZWZhdWx0T3B0aW9ucyksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRlJBTUVXT1JLLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTVBBVElCSUxJVFkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ29udHJhY3QgPSBpbnN0YW5jZS5jb250cmFjdDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUNvbnRyYWN0KSA9PSBUWVBFUy5mKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYWN0UmVzdWx0ID0gaW5zdGFuY2VDb250cmFjdCh3aW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFjdEZ1bGZpbGxlZCA9IHR5cGUoY29udHJhY3RSZXN1bHQpID09IFRZUEVTLmIgPyBjb250cmFjdFJlc3VsdCA6IGNvbnRyYWN0RnVsZmlsbGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29udHJhY3RGdWxmaWxsZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2V4dGVuc2lvbnNbZXh0TmFtZV0gPSBpbnN0YW5jZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZCA9IGluc3RhbmNlLmFkZGVkO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShpbnN0YW5jZUFkZGVkKSA9PSBUWVBFUy5mKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VBZGRlZChleHRlbnNpb25PcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZS5leHQoZXh0TmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFwiQSBleHRlbnNpb24gd2l0aCB0aGUgbmFtZSBcXFwiXCIgKyBleHROYW1lICsgXCJcXFwiIGlzbid0IHJlZ2lzdGVyZWQuXCIpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAqIFJlbW92ZXMgYSBleHRlbnNpb24gZnJvbSB0aGlzIGluc3RhbmNlLlxyXG4gICAgICAgICAgICAgICAgICogQHBhcmFtIGV4dE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiB3aGljaCBzaGFsbCBiZSByZW1vdmVkLlxyXG4gICAgICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGV4dGVuc2lvbiB3YXMgcmVtb3ZlZCwgZmFsc2Ugb3RoZXJ3aXNlIGUuZy4gaWYgdGhlIGV4dGVuc2lvbiB3YXNuJ3QgYWRkZWQgYmVmb3JlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBfYmFzZS5yZW1vdmVFeHQgPSBmdW5jdGlvbiAoZXh0TmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZSA9IF9leHRlbnNpb25zW2V4dE5hbWVdO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZXh0ZW5zaW9uc1tleHROYW1lXTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCA9IGluc3RhbmNlLnJlbW92ZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlKGluc3RhbmNlUmVtb3ZlZCkgPT0gVFlQRVMuZilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlUmVtb3ZlZCgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBUaGUgZWxlbWVudCB0byB3aGljaCB0aGUgcGx1Z2luIHNoYWxsIGJlIGFwcGxpZWQuXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgaW5pdGlhbCBvcHRpb25zIG9mIHRoZSBwbHVnaW4uXHJcbiAgICAgICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9uKHMpIHdoaWNoIHNoYWxsIGJlIGFkZGVkIHJpZ2h0IGFmdGVyIHRoZSBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwbHVnaW4gd2FzIHN1Y2Nlc3NmdWxseSBpbml0aWFsaXplZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiBjb25zdHJ1Y3QodGFyZ2V0RWxlbWVudCwgb3B0aW9ucywgZXh0ZW5zaW9ucykge1xyXG4gICAgICAgICAgICAgICAgICAgIF9kZWZhdWx0T3B0aW9ucyA9IGdsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclN0eWxpbmcgPSBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclN0eWxpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX25hdGl2ZVNjcm9sbGJhclNpemUgPSBleHRlbmREZWVwKHt9LCBnbG9iYWxzLm5hdGl2ZVNjcm9sbGJhclNpemUpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkKTtcclxuICAgICAgICAgICAgICAgICAgICBfb3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSA9IGV4dGVuZERlZXAoe30sIGdsb2JhbHMub3ZlcmxheVNjcm9sbGJhckR1bW15U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3J0bFNjcm9sbEJlaGF2aW9yID0gZXh0ZW5kRGVlcCh7fSwgZ2xvYmFscy5ydGxTY3JvbGxCZWhhdmlvcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vcGFyc2UgJiBzZXQgb3B0aW9ucyBidXQgZG9uJ3QgdXBkYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0T3B0aW9ucyhleHRlbmREZWVwKHt9LCBfZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgX2Nzc0NhbGMgPSBnbG9iYWxzLmNzc0NhbGM7XHJcbiAgICAgICAgICAgICAgICAgICAgX21zaWVWZXJzaW9uID0gZ2xvYmFscy5tc2llO1xyXG4gICAgICAgICAgICAgICAgICAgIF9hdXRvVXBkYXRlUmVjb21tZW5kZWQgPSBnbG9iYWxzLmF1dG9VcGRhdGVSZWNvbW1lbmRlZDtcclxuICAgICAgICAgICAgICAgICAgICBfc3VwcG9ydFRyYW5zaXRpb24gPSBnbG9iYWxzLnN1cHBvcnRUcmFuc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0VHJhbnNmb3JtID0gZ2xvYmFscy5zdXBwb3J0VHJhbnNmb3JtO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0UGFzc2l2ZUV2ZW50cyA9IGdsb2JhbHMuc3VwcG9ydFBhc3NpdmVFdmVudHM7XHJcbiAgICAgICAgICAgICAgICAgICAgX3N1cHBvcnRSZXNpemVPYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydFJlc2l6ZU9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgICAgIF9zdXBwb3J0TXV0YXRpb25PYnNlcnZlciA9IGdsb2JhbHMuc3VwcG9ydE11dGF0aW9uT2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgX3Jlc3RyaWN0ZWRNZWFzdXJpbmcgPSBnbG9iYWxzLnJlc3RyaWN0ZWRNZWFzdXJpbmc7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50Lm93bmVyRG9jdW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIF9kb2N1bWVudEVsZW1lbnROYXRpdmUgPSBfZG9jdW1lbnRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50ID0gRlJBTUVXT1JLKF9kb2N1bWVudEVsZW1lbnROYXRpdmUuZGVmYXVsdFZpZXcgfHwgX2RvY3VtZW50RWxlbWVudE5hdGl2ZS5wYXJlbnRXaW5kb3cpO1xyXG4gICAgICAgICAgICAgICAgICAgIF93aW5kb3dFbGVtZW50TmF0aXZlID0gX3dpbmRvd0VsZW1lbnRbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgX2h0bWxFbGVtZW50ID0gZmluZEZpcnN0KF9kb2N1bWVudEVsZW1lbnQsICdodG1sJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2JvZHlFbGVtZW50ID0gZmluZEZpcnN0KF9odG1sRWxlbWVudCwgJ2JvZHknKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudCA9IEZSQU1FV09SSyh0YXJnZXRFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfdGFyZ2V0RWxlbWVudE5hdGl2ZSA9IF90YXJnZXRFbGVtZW50WzBdO1xyXG4gICAgICAgICAgICAgICAgICAgIF9pc1RleHRhcmVhID0gX3RhcmdldEVsZW1lbnQuaXMoJ3RleHRhcmVhJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2lzQm9keSA9IF90YXJnZXRFbGVtZW50LmlzKCdib2R5Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgX2RvY3VtZW50TWl4ZWQgPSBfZG9jdW1lbnRFbGVtZW50TmF0aXZlICE9PSBkb2N1bWVudDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyogT24gYSBkaXYgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy1ob3N0XCJcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyBhIGEgY2hpbGQgd2l0aCB0aGUgY2xhc3MgXCJvcy1wYWRkaW5nXCJcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy1ob3N0XCIgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy12aWV3cG9ydFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3MtY29udGVudFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyIG9zLXNjcm9sbGJhci1ob3Jpem9udGFsIFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItdHJhY2tcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci1oYW5kbGVcIj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItdmVydGljYWxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItY29ybmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgICAgICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gICAgICAgICAgICAgICAgICAgICAqIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIE9uIGEgVGV4dGFyZWEgRWxlbWVudCBUaGUgaWYgY2hlY2tzIG9ubHkgd2hldGhlcjpcclxuICAgICAgICAgICAgICAgICAgICAgKiAtIHRoZSB0YXJnZXRFbGVtZW50IGhhcyB0aGUgY2xhc3MgXCJvcy10ZXh0YXJlYVwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAqIC0gdGhlIHRhcmdldEVsZW1lbnQgaXMgaW5zaWRlIGEgZWxlbWVudCB3aXRoIHRoZSBjbGFzcyBcIm9zLWNvbnRlbnRcIiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBcclxuICAgICAgICAgICAgICAgICAgICAgKiBJZiB0aGF0J3MgdGhlIGNhc2UsIGl0cyBhc3N1bWVkIHRoZSBET00gaGFzIGFscmVhZHkgdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6XHJcbiAgICAgICAgICAgICAgICAgICAgICogKFRoZSBcIi5vcy10ZXh0YXJlYVwiICh0ZXh0YXJlYSkgZWxlbWVudCBpcyB0aGUgdGFyZ2V0RWxlbWVudClcclxuICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8ZGl2IGNsYXNzPVwib3MtaG9zdC10ZXh0YXJlYVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXJlc2l6ZS1vYnNlcnZlci1ob3N0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3MtcGFkZGluZyBvcy10ZXh0LWluaGVyaXRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtdmlld3BvcnQgb3MtdGV4dC1pbmhlcml0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1jb250ZW50IG9zLXRleHQtaW5oZXJpdFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXRleHRhcmVhLWNvdmVyXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJvcy10ZXh0YXJlYSBvcy10ZXh0LWluaGVyaXRcIj48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhciBvcy1zY3JvbGxiYXItaG9yaXpvbnRhbCBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLXRyYWNrXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXItaGFuZGxlXCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKiAgICAgIDxkaXYgY2xhc3M9XCJvcy1zY3JvbGxiYXIgb3Mtc2Nyb2xsYmFyLXZlcnRpY2FsXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgPGRpdiBjbGFzcz1cIm9zLXNjcm9sbGJhci10cmFja1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWhhbmRsZVwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICogICAgICA8ZGl2IGNsYXNzPVwib3Mtc2Nyb2xsYmFyLWNvcm5lclwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAqICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBfZG9tRXhpc3RzID0gX2lzVGV4dGFyZWFcclxuICAgICAgICAgICAgICAgICAgICAgICAgPyBfdGFyZ2V0RWxlbWVudC5oYXNDbGFzcyhfY2xhc3NOYW1lVGV4dGFyZWFFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5wYXJlbnQoKS5oYXNDbGFzcyhfY2xhc3NOYW1lQ29udGVudEVsZW1lbnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogX3RhcmdldEVsZW1lbnQuaGFzQ2xhc3MoX2NsYXNzTmFtZUhvc3RFbGVtZW50KSAmJiBfdGFyZ2V0RWxlbWVudC5jaGlsZHJlbihfc3RyRG90ICsgX2NsYXNzTmFtZVBhZGRpbmdFbGVtZW50KVtMRVhJQ09OLmxdO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgaW5pdEJvZHlTY3JvbGw7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGJvZHlNb3VzZVRvdWNoRG93bkxpc3RlbmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NoZWNrIGlmIHRoZSBwbHVnaW4gaGFzbid0IHRvIGJlIGluaXRpYWxpemVkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF9uYXRpdmVTY3JvbGxiYXJJc092ZXJsYWlkLnggJiYgX25hdGl2ZVNjcm9sbGJhcklzT3ZlcmxhaWQueSAmJiAhX2N1cnJlbnRQcmVwYXJlZE9wdGlvbnMubmF0aXZlU2Nyb2xsYmFyc092ZXJsYWlkLmluaXRpYWxpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2hDYWxsYmFjaygnb25Jbml0aWFsaXphdGlvbldpdGhkcmF3bicpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX2RvbUV4aXN0cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00odHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSh0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgX2Rlc3Ryb3llZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF9zbGVlcGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2Jhc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbCA9IHt9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC5sID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbExlZnRdKCksIF9odG1sRWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oKSwgX3dpbmRvd0VsZW1lbnRbX3N0clNjcm9sbExlZnRdKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0Qm9keVNjcm9sbC50ID0gTUFUSC5tYXgoX3RhcmdldEVsZW1lbnRbX3N0clNjcm9sbFRvcF0oKSwgX2h0bWxFbGVtZW50W19zdHJTY3JvbGxUb3BdKCksIF93aW5kb3dFbGVtZW50W19zdHJTY3JvbGxUb3BdKCkpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdmlld3BvcnRFbGVtZW50LnJlbW92ZUF0dHIoTEVYSUNPTi50aSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR1cFJlc3BvbnNpdmVFdmVudExpc3RlbmVyKF92aWV3cG9ydEVsZW1lbnQsIF9zdHJNb3VzZVRvdWNoRG93bkV2ZW50LCBib2R5TW91c2VUb3VjaERvd25MaXN0ZW5lciwgdHJ1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYnVpbGQgT3ZlcmxheVNjcm9sbGJhcnMgRE9NXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0dXBTdHJ1Y3R1cmVET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhcnNET00oKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckRPTSgpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBPdmVybGF5U2Nyb2xsYmFycyBldmVudHNcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFN0cnVjdHVyZUV2ZW50cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwU2Nyb2xsYmFyRXZlbnRzKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXR1cFNjcm9sbGJhckNvcm5lckV2ZW50cygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2NyZWF0ZSBtdXRhdGlvbiBvYnNlcnZlcnNcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVNdXRhdGlvbk9ic2VydmVycygpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvL2J1aWxkIHJlc2l6ZSBvYnNlcnZlciBmb3IgdGhlIGhvc3QgZWxlbWVudFxyXG4gICAgICAgICAgICAgICAgICAgIHNldHVwUmVzaXplT2JzZXJ2ZXIoX3NpemVPYnNlcnZlckVsZW1lbnQsIGhvc3RPblJlc2l6ZWQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzQm9keSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2FwcGx5IHRoZSBib2R5IHNjcm9sbCB0byBoYW5kbGUgaXQgcmlnaHQgaW4gdGhlIHVwZGF0ZSBtZXRob2RcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3ZpZXdwb3J0RWxlbWVudFtfc3RyU2Nyb2xsTGVmdF0oaW5pdEJvZHlTY3JvbGwubClbX3N0clNjcm9sbFRvcF0oaW5pdEJvZHlTY3JvbGwudCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvL3NldCB0aGUgZm9jdXMgb24gdGhlIHZpZXdwb3J0IGVsZW1lbnQgc28geW91IGRvbnQgaGF2ZSB0byBjbGljayBvbiB0aGUgcGFnZSB0byB1c2Uga2V5Ym9hcmQga2V5cyAodXAgLyBkb3duIC8gc3BhY2UpIGZvciBzY3JvbGxpbmdcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT0gdGFyZ2V0RWxlbWVudCAmJiBfdmlld3BvcnRFbGVtZW50TmF0aXZlLmZvY3VzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NldCBhIHRhYmluZGV4IHRvIG1ha2UgdGhlIHZpZXdwb3J0RWxlbWVudCBmb2N1c2FibGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnQuYXR0cihMRVhJQ09OLnRpLCAnLTEnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF92aWV3cG9ydEVsZW1lbnROYXRpdmUuZm9jdXMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0aGUgdGFiaW5kZXggaGFzIHRvIGJlIHJlbW92ZWQgZHVlIHRvO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogSWYgeW91IHNldCB0aGUgdGFiaW5kZXggYXR0cmlidXRlIG9uIGFuIDxkaXY+LCB0aGVuIGl0cyBjaGlsZCBjb250ZW50IGNhbm5vdCBiZSBzY3JvbGxlZCB3aXRoIHRoZSBhcnJvdyBrZXlzIHVubGVzcyB5b3Ugc2V0IHRhYmluZGV4IG9uIHRoZSBjb250ZW50LCB0b29cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0hUTUwvR2xvYmFsX2F0dHJpYnV0ZXMvdGFiaW5kZXhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBSZXNwb25zaXZlRXZlbnRMaXN0ZW5lcihfdmlld3BvcnRFbGVtZW50LCBfc3RyTW91c2VUb3VjaERvd25FdmVudCwgYm9keU1vdXNlVG91Y2hEb3duTGlzdGVuZXIsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy91cGRhdGUgZm9yIHRoZSBmaXJzdCB0aW1lICYgaW5pdGlhbGl6ZSBjYWNoZVxyXG4gICAgICAgICAgICAgICAgICAgIF9iYXNlLnVwZGF0ZShfc3RyQXV0byk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vdGhlIHBsdWdpbiBpcyBpbml0aWFsaXplZCBub3chXHJcbiAgICAgICAgICAgICAgICAgICAgX2luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKCdvbkluaXRpYWxpemVkJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vY2FsbCBhbGwgY2FsbGJhY2tzIHdoaWNoIHdvdWxkIGZpcmUgYmVmb3JlIHRoZSBpbml0aWFsaXplZCB3YXMgY29tcGxldGVcclxuICAgICAgICAgICAgICAgICAgICBlYWNoKF9jYWxsYmFja3NJbml0UWV1ZXVlLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IGRpc3BhdGNoQ2FsbGJhY2sodmFsdWUubiwgdmFsdWUuYSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIF9jYWxsYmFja3NJbml0UWV1ZXVlID0gW107XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIGV4dGVuc2lvbnNcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZShleHRlbnNpb25zKSA9PSBUWVBFUy5zKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25zID0gW2V4dGVuc2lvbnNdO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChDT01QQVRJQklMSVRZLmlzQShleHRlbnNpb25zKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgZWFjaChleHRlbnNpb25zLCBmdW5jdGlvbiAoaW5kZXgsIHZhbHVlKSB7IF9iYXNlLmFkZEV4dCh2YWx1ZSk7IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKEZSQU1FV09SSy5pc1BsYWluT2JqZWN0KGV4dGVuc2lvbnMpKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBlYWNoKGV4dGVuc2lvbnMsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7IF9iYXNlLmFkZEV4dChrZXksIHZhbHVlKTsgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vYWRkIHRoZSB0cmFuc2l0aW9uIGNsYXNzIGZvciB0cmFuc2l0aW9ucyBBRlRFUiB0aGUgZmlyc3QgdXBkYXRlICYgQUZURVIgdGhlIGFwcGxpZWQgZXh0ZW5zaW9ucyAoZm9yIHByZXZlbnRpbmcgdW53YW50ZWQgdHJhbnNpdGlvbnMpXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfc3VwcG9ydFRyYW5zaXRpb24gJiYgIV9kZXN0cm95ZWQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRDbGFzcyhfaG9zdEVsZW1lbnQsIF9jbGFzc05hbWVIb3N0VHJhbnNpdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgMzMzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfcGx1Z2luLnZhbGlkKGNvbnN0cnVjdChwbHVnaW5UYXJnZXRFbGVtZW50LCBvcHRpb25zLCBleHRlbnNpb25zKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBJTlNUQU5DRVMocGx1Z2luVGFyZ2V0RWxlbWVudCwgX2Jhc2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIHJldHVybiBfYmFzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3IE92ZXJsYXlTY3JvbGxiYXJzSW5zdGFuY2Ugb2JqZWN0IG9yIGNoYW5nZXMgb3B0aW9ucyBpZiBhbHJlYWR5IGluaXRpYWxpemVkIG9yIHJldHVybnMgdGhlIGN1cnJlbnQgaW5zdGFuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBwbHVnaW5UYXJnZXRFbGVtZW50cyBUaGUgZWxlbWVudHMgdG8gd2hpY2ggdGhlIFBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9wdGlvbnMgVGhlIGN1c3RvbSBvcHRpb25zIHdpdGggd2hpY2ggdGhlIHBsdWdpbiBzaGFsbCBiZSBpbml0aWFsaXplZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbihzKSB3aGljaCBzaGFsbCBiZSBhZGRlZCByaWdodCBhZnRlciBpbml0aWFsaXphdGlvbi5cclxuICAgICAgICAgICAgICogQHJldHVybnMgeyp9XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luID0gd2luZG93W1BMVUdJTk5BTUVdID0gZnVuY3Rpb24gKHBsdWdpblRhcmdldEVsZW1lbnRzLCBvcHRpb25zLCBleHRlbnNpb25zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW0xFWElDT04ubF0gPT09IDApXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcblxyXG4gICAgICAgICAgICAgICAgdmFyIGFyciA9IFtdO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9wdHNJc1BsYWluT2JqID0gRlJBTUVXT1JLLmlzUGxhaW5PYmplY3Qob3B0aW9ucyk7XHJcbiAgICAgICAgICAgICAgICB2YXIgaW5zdDtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcblxyXG4gICAgICAgICAgICAgICAgLy9wbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKCFwbHVnaW5UYXJnZXRFbGVtZW50cylcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0c0lzUGxhaW5PYmogfHwgIW9wdGlvbnMgPyByZXN1bHQgOiBhcnI7XHJcblxyXG4gICAgICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgICAgICAgIHBsdWdpblRhcmdldEVsZW1lbnRzIHdpbGwgYmUgY29udmVydGVkIHRvOlxyXG4gICAgICAgICAgICAgICAgICAgMS4gQSBqUXVlcnlFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAyLiBBIEhUTUxFbGVtZW50IEFycmF5XHJcbiAgICAgICAgICAgICAgICAgICAzLiBBIEFycmF5IHdpdGggYSBzaW5nbGUgSFRNTCBFbGVtZW50XHJcbiAgICAgICAgICAgICAgICAgICBzbyBwbHVnaW5UYXJnZXRFbGVtZW50cyBpcyBhbHdheXMgYSBhcnJheS5cclxuICAgICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgICAgICBwbHVnaW5UYXJnZXRFbGVtZW50cyA9IHBsdWdpblRhcmdldEVsZW1lbnRzW0xFWElDT04ubF0gIT0gdW5kZWZpbmVkID8gcGx1Z2luVGFyZ2V0RWxlbWVudHMgOiBbcGx1Z2luVGFyZ2V0RWxlbWVudHNbMF0gfHwgcGx1Z2luVGFyZ2V0RWxlbWVudHNdO1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5UYXJnZXRFbGVtZW50c1tMRVhJQ09OLmxdID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRzSXNQbGFpbk9iaikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBGUkFNRVdPUksuZWFjaChwbHVnaW5UYXJnZXRFbGVtZW50cywgZnVuY3Rpb24gKGksIHYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3QgPSB2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3QgIT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChPdmVybGF5U2Nyb2xsYmFyc0luc3RhbmNlKGluc3QsIG9wdGlvbnMsIGV4dGVuc2lvbnMsIF9wbHVnaW5zR2xvYmFscywgX3BsdWdpbnNBdXRvVXBkYXRlTG9vcCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIEZSQU1FV09SSy5lYWNoKHBsdWdpblRhcmdldEVsZW1lbnRzLCBmdW5jdGlvbiAoaSwgdikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdCA9IElOU1RBTkNFUyh2KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgob3B0aW9ucyA9PT0gJyEnICYmIF9wbHVnaW4udmFsaWQoaW5zdCkpIHx8IChDT01QQVRJQklMSVRZLnR5cGUob3B0aW9ucykgPT0gVFlQRVMuZiAmJiBvcHRpb25zKHYsIGluc3QpKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcnIucHVzaChpbnN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGFycltMRVhJQ09OLmxdID09PSAxID8gYXJyWzBdIDogYXJyO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBSZXR1cm5zIGEgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGdsb2JhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGx1Z2luIGFuZCBlYWNoIGluc3RhbmNlIG9mIGl0LlxyXG4gICAgICAgICAgICAgKiBUaGUgcmV0dXJuZWQgb2JqZWN0IGlzIGp1c3QgYSBjb3B5LCB0aGF0IG1lYW5zIHRoYXQgY2hhbmdlcyB0byB0aGUgcmV0dXJuZWQgb2JqZWN0IHdvbid0IGhhdmUgYW55IGVmZmVjdCB0byB0aGUgb3JpZ2luYWwgb2JqZWN0LlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi5nbG9iYWxzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaW5pdE92ZXJsYXlTY3JvbGxiYXJzU3RhdGljcygpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGdsb2JhbHMgPSBGUkFNRVdPUksuZXh0ZW5kKHRydWUsIHt9LCBfcGx1Z2luc0dsb2JhbHMpO1xyXG4gICAgICAgICAgICAgICAgZGVsZXRlIGdsb2JhbHNbJ21zaWUnXTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBnbG9iYWxzO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEdldHMgb3IgU2V0cyB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBlYWNoIG5ldyBwbHVnaW4gaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBuZXdEZWZhdWx0T3B0aW9ucyBUaGUgb2JqZWN0IHdpdGggd2hpY2ggdGhlIGRlZmF1bHQgb3B0aW9ucyBzaGFsbCBiZSBleHRlbmRlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIF9wbHVnaW4uZGVmYXVsdE9wdGlvbnMgPSBmdW5jdGlvbiAobmV3RGVmYXVsdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgICAgIGluaXRPdmVybGF5U2Nyb2xsYmFyc1N0YXRpY3MoKTtcclxuICAgICAgICAgICAgICAgIHZhciBjdXJyRGVmYXVsdE9wdGlvbnMgPSBfcGx1Z2luc0dsb2JhbHMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3RGVmYXVsdE9wdGlvbnMgPT09IHVuZGVmaW5lZClcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvL3NldCB0aGUgbmV3IGRlZmF1bHQgb3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgX3BsdWdpbnNHbG9iYWxzLmRlZmF1bHRPcHRpb25zID0gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7fSwgY3VyckRlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3ZhbGlkYXRlKG5ld0RlZmF1bHRPcHRpb25zLCBfcGx1Z2luc09wdGlvbnMuX3RlbXBsYXRlLCB0cnVlLCBjdXJyRGVmYXVsdE9wdGlvbnMpLl9kZWZhdWx0KTtcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcGFzc2VkIGluc3RhbmNlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZS5cclxuICAgICAgICAgICAgICogQHBhcmFtIG9zSW5zdGFuY2UgVGhlIHBvdGVudGlhbCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSB3aGljaCBzaGFsbCBiZSBjaGVja2VkLlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgcGFzc2VkIHZhbHVlIGlzIGEgbm9uLWRlc3Ryb3llZCBPdmVybGF5U2Nyb2xsYmFycyBpbnN0YW5jZSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgX3BsdWdpbi52YWxpZCA9IGZ1bmN0aW9uIChvc0luc3RhbmNlKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb3NJbnN0YW5jZSBpbnN0YW5jZW9mIF9wbHVnaW4gJiYgIW9zSW5zdGFuY2UuZ2V0U3RhdGUoKS5kZXN0cm95ZWQ7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogUmVnaXN0ZXJzLCBVbnJlZ2lzdGVycyBvciByZXR1cm5zIGEgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBSZWdpc3RlcjogUGFzcyB0aGUgbmFtZSBhbmQgdGhlIGV4dGVuc2lvbi4gKGRlZmF1bHRPcHRpb25zIGlzIG9wdGlvbmFsKVxyXG4gICAgICAgICAgICAgKiBVbnJlZ2lzdGVyOiBQYXNzIHRoZSBuYW1lIGFuZCBhbnl0aGluZyBleGNlcHQgYSBmdW5jdGlvbiBhcyBleHRlbnNpb24gcGFyYW1ldGVyLlxyXG4gICAgICAgICAgICAgKiBHZXQgZXh0ZW5zaW9uOiBQYXNzIHRoZSBuYW1lIG9mIHRoZSBleHRlbnNpb24gd2hpY2ggc2hhbGwgYmUgZ290LlxyXG4gICAgICAgICAgICAgKiBHZXQgYWxsIGV4dGVuc2lvbnM6IFBhc3Mgbm8gYXJndW1lbnRzLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHdoaWNoIHNoYWxsIGJlIHJlZ2lzdGVyZWQsIHVucmVnaXN0ZXJlZCBvciByZXR1cm5lZC5cclxuICAgICAgICAgICAgICogQHBhcmFtIGV4dGVuc2lvbiBBIGZ1bmN0aW9uIHdoaWNoIGdlbmVyYXRlcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIGV4dGVuc2lvbiBvciBhbnl0aGluZyBvdGhlciB0byByZW1vdmUgYSBhbHJlYWR5IHJlZ2lzdGVyZWQgZXh0ZW5zaW9uLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0gZGVmYXVsdE9wdGlvbnMgVGhlIGRlZmF1bHQgb3B0aW9ucyB3aGljaCBzaGFsbCBiZSB1c2VkIGZvciB0aGUgcmVnaXN0ZXJlZCBleHRlbnNpb24uXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBfcGx1Z2luLmV4dGVuc2lvbiA9IGZ1bmN0aW9uIChleHRlbnNpb25OYW1lLCBleHRlbnNpb24sIGRlZmF1bHRPcHRpb25zKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZXh0TmFtZVR5cGVTdHJpbmcgPSBDT01QQVRJQklMSVRZLnR5cGUoZXh0ZW5zaW9uTmFtZSkgPT0gVFlQRVMucztcclxuICAgICAgICAgICAgICAgIHZhciBhcmdMZW4gPSBhcmd1bWVudHNbTEVYSUNPTi5sXTtcclxuICAgICAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChhcmdMZW4gPCAxIHx8ICFleHROYW1lVHlwZVN0cmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vcmV0dXJuIGEgY29weSBvZiBhbGwgZXh0ZW5zaW9uIG9iamVjdHNcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gRlJBTUVXT1JLLmV4dGVuZCh0cnVlLCB7IGxlbmd0aDogX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF0gfSwgX3BsdWdpbnNFeHRlbnNpb25zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGV4dE5hbWVUeXBlU3RyaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKENPTVBBVElCSUxJVFkudHlwZShleHRlbnNpb24pID09IFRZUEVTLmYpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlciBleHRlbnNpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3BsdWdpbnNFeHRlbnNpb25zLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZXh0ZW5zaW9uTmFtZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbkZhY3Rvcnk6IGV4dGVuc2lvbixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRPcHRpb25zOiBkZWZhdWx0T3B0aW9uc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBpIDwgX3BsdWdpbnNFeHRlbnNpb25zW0xFWElDT04ubF07IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF9wbHVnaW5zRXh0ZW5zaW9uc1tpXS5uYW1lID09PSBleHRlbnNpb25OYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ0xlbiA+IDEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wbHVnaW5zRXh0ZW5zaW9ucy5zcGxpY2UoaSwgMSk7IC8vcmVtb3ZlIGV4dGVuc2lvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZSQU1FV09SSy5leHRlbmQodHJ1ZSwge30sIF9wbHVnaW5zRXh0ZW5zaW9uc1tpXSk7IC8vcmV0dXJuIGV4dGVuc2lvbiB3aXRoIHRoZSBnaXZlbiBuYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gX3BsdWdpbjtcclxuICAgICAgICB9KSgpO1xyXG5cclxuICAgICAgICBpZiAoSlFVRVJZICYmIEpRVUVSWS5mbikge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVGhlIGpRdWVyeSBpbml0aWFsaXphdGlvbiBpbnRlcmZhY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBpbml0aWFsIG9wdGlvbnMgZm9yIHRoZSBjb25zdHJ1Y3Rpb24gb2YgdGhlIHBsdWdpbi4gVG8gaW5pdGlhbGl6ZSB0aGUgcGx1Z2luLCB0aGlzIG9wdGlvbiBoYXMgdG8gYmUgYSBvYmplY3QhIElmIGl0IGlzbid0IGEgb2JqZWN0LCB0aGUgaW5zdGFuY2UocykgYXJlIHJldHVybmVkIGFuZCB0aGUgcGx1Z2luIHdvbnQgYmUgaW5pdGlhbGl6ZWQuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb24ocykgd2hpY2ggc2hhbGwgYmUgYWRkZWQgcmlnaHQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHsqfSBBZnRlciBpbml0aWFsaXphdGlvbiBpdCByZXR1cm5zIHRoZSBqUXVlcnkgZWxlbWVudCBhcnJheSwgZWxzZSBpdCByZXR1cm5zIHRoZSBpbnN0YW5jZShzKSBvZiB0aGUgZWxlbWVudHMgd2hpY2ggYXJlIHNlbGVjdGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgSlFVRVJZLmZuLm92ZXJsYXlTY3JvbGxiYXJzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGV4dGVuc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgIHZhciBfZWxlbWVudHMgPSB0aGlzO1xyXG4gICAgICAgICAgICAgICAgaWYgKEpRVUVSWS5pc1BsYWluT2JqZWN0KG9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgSlFVRVJZLmVhY2goX2VsZW1lbnRzLCBmdW5jdGlvbiAoKSB7IFBMVUdJTih0aGlzLCBvcHRpb25zLCBleHRlbnNpb25zKTsgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9lbGVtZW50cztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUExVR0lOKF9lbGVtZW50cywgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBQTFVHSU47XHJcbiAgICB9XHJcbikpOyJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///1091\n")}}]);
|